@@ -981,14 +981,7 @@ static const auto jl_typeof_func = new JuliaFunction<>{
981981 Attributes (C, {Attribute::NonNull}),
982982 None); },
983983};
984- static const auto jl_loopinfo_marker_func = new JuliaFunction<>{
985- " julia.loopinfo_marker" ,
986- [](LLVMContext &C) { return FunctionType::get (getVoidTy (C), false ); },
987- [](LLVMContext &C) { return AttributeList::get (C,
988- Attributes (C, {Attribute::ReadOnly, Attribute::NoRecurse, Attribute::InaccessibleMemOnly}),
989- AttributeSet (),
990- None); },
991- };
984+
992985static const auto jl_write_barrier_func = new JuliaFunction<>{
993986 " julia.write_barrier" ,
994987 [](LLVMContext &C) { return FunctionType::get (getVoidTy (C),
@@ -1600,6 +1593,7 @@ class jl_codectx_t {
16001593 std::map<void *, GlobalVariable*> &global_targets;
16011594 std::map<std::tuple<jl_code_instance_t *, bool >, GlobalVariable*> &external_calls;
16021595 Function *f = NULL ;
1596+ MDNode* LoopID = NULL ;
16031597 // local var info. globals are not in here.
16041598 std::vector<jl_varinfo_t > slots;
16051599 std::map<int , jl_varinfo_t > phic_slots;
@@ -5766,16 +5760,22 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_
57665760 }
57675761 else if (head == jl_loopinfo_sym) {
57685762 // parse Expr(:loopinfo, "julia.simdloop", ("llvm.loop.vectorize.width", 4))
5763+ // to LLVM LoopID
57695764 SmallVector<Metadata *, 8 > MDs;
5765+
5766+ // Reserve first location for self reference to the LoopID metadata node.
5767+ TempMDTuple TempNode = MDNode::getTemporary (ctx.builder .getContext (), None);
5768+ MDs.push_back (TempNode.get ());
5769+
57705770 for (int i = 0 , ie = nargs; i < ie; ++i) {
57715771 Metadata *MD = to_md_tree (args[i], ctx.builder .getContext ());
57725772 if (MD)
57735773 MDs.push_back (MD);
57745774 }
57755775
5776- MDNode* MD = MDNode::get (ctx.builder .getContext (), MDs);
5777- CallInst *I = ctx. builder . CreateCall ( prepare_call (jl_loopinfo_marker_func));
5778- I-> setMetadata ( " julia.loopinfo " , MD );
5776+ ctx. LoopID = MDNode::getDistinct (ctx.builder .getContext (), MDs);
5777+ // Replace the temporary node with a self-reference.
5778+ ctx. LoopID -> replaceOperandWith ( 0 , ctx. LoopID );
57795779 return jl_cgval_t ();
57805780 }
57815781 else if (head == jl_leave_sym || head == jl_coverageeffect_sym
@@ -8045,6 +8045,7 @@ static jl_llvm_functions_t
80458045 std::map<int , BasicBlock*> BB;
80468046 std::map<size_t , BasicBlock*> come_from_bb;
80478047 int cursor = 0 ;
8048+ int current_label = 0 ;
80488049 auto find_next_stmt = [&] (int seq_next) {
80498050 // new style ir is always in dominance order, but frontend IR might not be
80508051 // `seq_next` is the next statement we want to emit
@@ -8061,6 +8062,7 @@ static jl_llvm_functions_t
80618062 workstack.pop_back ();
80628063 auto nextbb = BB.find (item + 1 );
80638064 if (nextbb == BB.end ()) {
8065+ // Not a BB
80648066 cursor = item;
80658067 return ;
80668068 }
@@ -8071,8 +8073,10 @@ static jl_llvm_functions_t
80718073 seq_next = -1 ;
80728074 // if this BB is non-empty, we've visited it before so skip it
80738075 if (!nextbb->second ->getTerminator ()) {
8076+ // New BB
80748077 ctx.builder .SetInsertPoint (nextbb->second );
80758078 cursor = item;
8079+ current_label = item;
80768080 return ;
80778081 }
80788082 }
@@ -8319,7 +8323,12 @@ static jl_llvm_functions_t
83198323 if (jl_is_gotonode (stmt)) {
83208324 int lname = jl_gotonode_label (stmt);
83218325 come_from_bb[cursor+1 ] = ctx.builder .GetInsertBlock ();
8322- ctx.builder .CreateBr (BB[lname]);
8326+ auto br = ctx.builder .CreateBr (BB[lname]);
8327+ // Check if backwards branch
8328+ if (ctx.LoopID && lname <= current_label) {
8329+ br->setMetadata (LLVMContext::MD_loop, ctx.LoopID );
8330+ ctx.LoopID = NULL ;
8331+ }
83238332 find_next_stmt (lname - 1 );
83248333 continue ;
83258334 }
@@ -8337,10 +8346,17 @@ static jl_llvm_functions_t
83378346 workstack.push_back (lname - 1 );
83388347 BasicBlock *ifnot = BB[lname];
83398348 BasicBlock *ifso = BB[cursor+2 ];
8349+ Instruction *br;
83408350 if (ifnot == ifso)
8341- ctx.builder .CreateBr (ifnot);
8351+ br = ctx.builder .CreateBr (ifnot);
83428352 else
8343- ctx.builder .CreateCondBr (isfalse, ifnot, ifso);
8353+ br = ctx.builder .CreateCondBr (isfalse, ifnot, ifso);
8354+
8355+ // Check if backwards branch
8356+ if (ctx.LoopID && lname <= current_label) {
8357+ br->setMetadata (LLVMContext::MD_loop, ctx.LoopID );
8358+ ctx.LoopID = NULL ;
8359+ }
83448360 find_next_stmt (cursor + 1 );
83458361 continue ;
83468362 }
@@ -9088,7 +9104,6 @@ static void init_jit_functions(void)
90889104 add_named_global (jl_object_id__func, &jl_object_id_);
90899105 add_named_global (jl_alloc_obj_func, (void *)NULL );
90909106 add_named_global (jl_newbits_func, (void *)jl_new_bits);
9091- add_named_global (jl_loopinfo_marker_func, (void *)NULL );
90929107 add_named_global (jl_typeof_func, (void *)NULL );
90939108 add_named_global (jl_write_barrier_func, (void *)NULL );
90949109 add_named_global (jldlsym_func, &jl_load_and_lookup);
0 commit comments