@@ -981,14 +981,7 @@ static const auto jl_typeof_func = new JuliaFunction<>{
981
981
Attributes (C, {Attribute::NonNull}),
982
982
None); },
983
983
};
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
+
992
985
static const auto jl_write_barrier_func = new JuliaFunction<>{
993
986
" julia.write_barrier" ,
994
987
[](LLVMContext &C) { return FunctionType::get (getVoidTy (C),
@@ -1600,6 +1593,7 @@ class jl_codectx_t {
1600
1593
std::map<void *, GlobalVariable*> &global_targets;
1601
1594
std::map<std::tuple<jl_code_instance_t *, bool >, GlobalVariable*> &external_calls;
1602
1595
Function *f = NULL ;
1596
+ MDNode* LoopID = NULL ;
1603
1597
// local var info. globals are not in here.
1604
1598
std::vector<jl_varinfo_t > slots;
1605
1599
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_
5766
5760
}
5767
5761
else if (head == jl_loopinfo_sym) {
5768
5762
// parse Expr(:loopinfo, "julia.simdloop", ("llvm.loop.vectorize.width", 4))
5763
+ // to LLVM LoopID
5769
5764
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
+
5770
5770
for (int i = 0 , ie = nargs; i < ie; ++i) {
5771
5771
Metadata *MD = to_md_tree (args[i], ctx.builder .getContext ());
5772
5772
if (MD)
5773
5773
MDs.push_back (MD);
5774
5774
}
5775
5775
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 );
5779
5779
return jl_cgval_t ();
5780
5780
}
5781
5781
else if (head == jl_leave_sym || head == jl_coverageeffect_sym
@@ -8045,6 +8045,7 @@ static jl_llvm_functions_t
8045
8045
std::map<int , BasicBlock*> BB;
8046
8046
std::map<size_t , BasicBlock*> come_from_bb;
8047
8047
int cursor = 0 ;
8048
+ int current_label = 0 ;
8048
8049
auto find_next_stmt = [&] (int seq_next) {
8049
8050
// new style ir is always in dominance order, but frontend IR might not be
8050
8051
// `seq_next` is the next statement we want to emit
@@ -8061,6 +8062,7 @@ static jl_llvm_functions_t
8061
8062
workstack.pop_back ();
8062
8063
auto nextbb = BB.find (item + 1 );
8063
8064
if (nextbb == BB.end ()) {
8065
+ // Not a BB
8064
8066
cursor = item;
8065
8067
return ;
8066
8068
}
@@ -8071,8 +8073,10 @@ static jl_llvm_functions_t
8071
8073
seq_next = -1 ;
8072
8074
// if this BB is non-empty, we've visited it before so skip it
8073
8075
if (!nextbb->second ->getTerminator ()) {
8076
+ // New BB
8074
8077
ctx.builder .SetInsertPoint (nextbb->second );
8075
8078
cursor = item;
8079
+ current_label = item;
8076
8080
return ;
8077
8081
}
8078
8082
}
@@ -8319,7 +8323,12 @@ static jl_llvm_functions_t
8319
8323
if (jl_is_gotonode (stmt)) {
8320
8324
int lname = jl_gotonode_label (stmt);
8321
8325
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
+ }
8323
8332
find_next_stmt (lname - 1 );
8324
8333
continue ;
8325
8334
}
@@ -8337,10 +8346,17 @@ static jl_llvm_functions_t
8337
8346
workstack.push_back (lname - 1 );
8338
8347
BasicBlock *ifnot = BB[lname];
8339
8348
BasicBlock *ifso = BB[cursor+2 ];
8349
+ Instruction *br;
8340
8350
if (ifnot == ifso)
8341
- ctx.builder .CreateBr (ifnot);
8351
+ br = ctx.builder .CreateBr (ifnot);
8342
8352
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
+ }
8344
8360
find_next_stmt (cursor + 1 );
8345
8361
continue ;
8346
8362
}
@@ -9088,7 +9104,6 @@ static void init_jit_functions(void)
9088
9104
add_named_global (jl_object_id__func, &jl_object_id_);
9089
9105
add_named_global (jl_alloc_obj_func, (void *)NULL );
9090
9106
add_named_global (jl_newbits_func, (void *)jl_new_bits);
9091
- add_named_global (jl_loopinfo_marker_func, (void *)NULL );
9092
9107
add_named_global (jl_typeof_func, (void *)NULL );
9093
9108
add_named_global (jl_write_barrier_func, (void *)NULL );
9094
9109
add_named_global (jldlsym_func, &jl_load_and_lookup);
0 commit comments