Skip to content

Commit cba88c1

Browse files
authored
Backport "Fix Expr(:loopinfo) codegen" (#51883)
Backport #50663 to 1.10
1 parent 1fe4e26 commit cba88c1

10 files changed

+209
-202
lines changed

src/codegen.cpp

+30-15
Original file line numberDiff line numberDiff line change
@@ -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+
992985
static 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);

src/jl_exported_funcs.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,6 @@
580580
YY(LLVMExtraAddCPUFeaturesPass) \
581581
YY(LLVMExtraMPMAddCPUFeaturesPass) \
582582
YY(LLVMExtraMPMAddRemoveNIPass) \
583-
YY(LLVMExtraMPMAddLowerSIMDLoopPass) \
584583
YY(LLVMExtraMPMAddFinalLowerGCPass) \
585584
YY(LLVMExtraMPMAddMultiVersioningPass) \
586585
YY(LLVMExtraMPMAddRemoveJuliaAddrspacesPass) \
@@ -594,6 +593,7 @@
594593
YY(LLVMExtraFPMAddLowerExcHandlersPass) \
595594
YY(LLVMExtraFPMAddGCInvariantVerifierPass) \
596595
YY(LLVMExtraLPMAddJuliaLICMPass) \
596+
YY(LLVMExtraLPMAddLowerSIMDLoopPass) \
597597
YY(JLJITGetLLVMOrcExecutionSession) \
598598
YY(JLJITGetJuliaOJIT) \
599599
YY(JLJITGetExternalJITDylib) \

src/llvm-julia-passes.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#ifdef MODULE_PASS
33
MODULE_PASS("CPUFeatures", CPUFeaturesPass, CPUFeaturesPass())
44
MODULE_PASS("RemoveNI", RemoveNIPass, RemoveNIPass())
5-
MODULE_PASS("LowerSIMDLoop", LowerSIMDLoopPass, LowerSIMDLoopPass())
65
MODULE_PASS("FinalLowerGC", FinalLowerGCPass, FinalLowerGCPass())
76
MODULE_PASS("JuliaMultiVersioning", MultiVersioningPass, MultiVersioningPass())
87
MODULE_PASS("RemoveJuliaAddrspaces", RemoveJuliaAddrspacesPass, RemoveJuliaAddrspacesPass())
@@ -24,4 +23,5 @@ FUNCTION_PASS("GCInvariantVerifier", GCInvariantVerifierPass, GCInvariantVerifie
2423
//Loop passes
2524
#ifdef LOOP_PASS
2625
LOOP_PASS("JuliaLICM", JuliaLICMPass, JuliaLICMPass())
26+
LOOP_PASS("LowerSIMDLoop", LowerSIMDLoopPass, LowerSIMDLoopPass())
2727
#endif

0 commit comments

Comments
 (0)