Skip to content

Commit

Permalink
Backport "Fix Expr(:loopinfo) codegen" (#51883)
Browse files Browse the repository at this point in the history
Backport #50663 to 1.10
  • Loading branch information
vchuravy authored Oct 28, 2023
1 parent 1fe4e26 commit cba88c1
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 202 deletions.
45 changes: 30 additions & 15 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -981,14 +981,7 @@ static const auto jl_typeof_func = new JuliaFunction<>{
Attributes(C, {Attribute::NonNull}),
None); },
};
static const auto jl_loopinfo_marker_func = new JuliaFunction<>{
"julia.loopinfo_marker",
[](LLVMContext &C) { return FunctionType::get(getVoidTy(C), false); },
[](LLVMContext &C) { return AttributeList::get(C,
Attributes(C, {Attribute::ReadOnly, Attribute::NoRecurse, Attribute::InaccessibleMemOnly}),
AttributeSet(),
None); },
};

static const auto jl_write_barrier_func = new JuliaFunction<>{
"julia.write_barrier",
[](LLVMContext &C) { return FunctionType::get(getVoidTy(C),
Expand Down Expand Up @@ -1600,6 +1593,7 @@ class jl_codectx_t {
std::map<void*, GlobalVariable*> &global_targets;
std::map<std::tuple<jl_code_instance_t*, bool>, GlobalVariable*> &external_calls;
Function *f = NULL;
MDNode* LoopID = NULL;
// local var info. globals are not in here.
std::vector<jl_varinfo_t> slots;
std::map<int, jl_varinfo_t> phic_slots;
Expand Down Expand Up @@ -5766,16 +5760,22 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_
}
else if (head == jl_loopinfo_sym) {
// parse Expr(:loopinfo, "julia.simdloop", ("llvm.loop.vectorize.width", 4))
// to LLVM LoopID
SmallVector<Metadata *, 8> MDs;

// Reserve first location for self reference to the LoopID metadata node.
TempMDTuple TempNode = MDNode::getTemporary(ctx.builder.getContext(), None);
MDs.push_back(TempNode.get());

for (int i = 0, ie = nargs; i < ie; ++i) {
Metadata *MD = to_md_tree(args[i], ctx.builder.getContext());
if (MD)
MDs.push_back(MD);
}

MDNode* MD = MDNode::get(ctx.builder.getContext(), MDs);
CallInst *I = ctx.builder.CreateCall(prepare_call(jl_loopinfo_marker_func));
I->setMetadata("julia.loopinfo", MD);
ctx.LoopID = MDNode::getDistinct(ctx.builder.getContext(), MDs);
// Replace the temporary node with a self-reference.
ctx.LoopID->replaceOperandWith(0, ctx.LoopID);
return jl_cgval_t();
}
else if (head == jl_leave_sym || head == jl_coverageeffect_sym
Expand Down Expand Up @@ -8045,6 +8045,7 @@ static jl_llvm_functions_t
std::map<int, BasicBlock*> BB;
std::map<size_t, BasicBlock*> come_from_bb;
int cursor = 0;
int current_label = 0;
auto find_next_stmt = [&] (int seq_next) {
// new style ir is always in dominance order, but frontend IR might not be
// `seq_next` is the next statement we want to emit
Expand All @@ -8061,6 +8062,7 @@ static jl_llvm_functions_t
workstack.pop_back();
auto nextbb = BB.find(item + 1);
if (nextbb == BB.end()) {
// Not a BB
cursor = item;
return;
}
Expand All @@ -8071,8 +8073,10 @@ static jl_llvm_functions_t
seq_next = -1;
// if this BB is non-empty, we've visited it before so skip it
if (!nextbb->second->getTerminator()) {
// New BB
ctx.builder.SetInsertPoint(nextbb->second);
cursor = item;
current_label = item;
return;
}
}
Expand Down Expand Up @@ -8319,7 +8323,12 @@ static jl_llvm_functions_t
if (jl_is_gotonode(stmt)) {
int lname = jl_gotonode_label(stmt);
come_from_bb[cursor+1] = ctx.builder.GetInsertBlock();
ctx.builder.CreateBr(BB[lname]);
auto br = ctx.builder.CreateBr(BB[lname]);
// Check if backwards branch
if (ctx.LoopID && lname <= current_label) {
br->setMetadata(LLVMContext::MD_loop, ctx.LoopID);
ctx.LoopID = NULL;
}
find_next_stmt(lname - 1);
continue;
}
Expand All @@ -8337,10 +8346,17 @@ static jl_llvm_functions_t
workstack.push_back(lname - 1);
BasicBlock *ifnot = BB[lname];
BasicBlock *ifso = BB[cursor+2];
Instruction *br;
if (ifnot == ifso)
ctx.builder.CreateBr(ifnot);
br = ctx.builder.CreateBr(ifnot);
else
ctx.builder.CreateCondBr(isfalse, ifnot, ifso);
br = ctx.builder.CreateCondBr(isfalse, ifnot, ifso);

// Check if backwards branch
if (ctx.LoopID && lname <= current_label) {
br->setMetadata(LLVMContext::MD_loop, ctx.LoopID);
ctx.LoopID = NULL;
}
find_next_stmt(cursor + 1);
continue;
}
Expand Down Expand Up @@ -9088,7 +9104,6 @@ static void init_jit_functions(void)
add_named_global(jl_object_id__func, &jl_object_id_);
add_named_global(jl_alloc_obj_func, (void*)NULL);
add_named_global(jl_newbits_func, (void*)jl_new_bits);
add_named_global(jl_loopinfo_marker_func, (void*)NULL);
add_named_global(jl_typeof_func, (void*)NULL);
add_named_global(jl_write_barrier_func, (void*)NULL);
add_named_global(jldlsym_func, &jl_load_and_lookup);
Expand Down
2 changes: 1 addition & 1 deletion src/jl_exported_funcs.inc
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,6 @@
YY(LLVMExtraAddCPUFeaturesPass) \
YY(LLVMExtraMPMAddCPUFeaturesPass) \
YY(LLVMExtraMPMAddRemoveNIPass) \
YY(LLVMExtraMPMAddLowerSIMDLoopPass) \
YY(LLVMExtraMPMAddFinalLowerGCPass) \
YY(LLVMExtraMPMAddMultiVersioningPass) \
YY(LLVMExtraMPMAddRemoveJuliaAddrspacesPass) \
Expand All @@ -594,6 +593,7 @@
YY(LLVMExtraFPMAddLowerExcHandlersPass) \
YY(LLVMExtraFPMAddGCInvariantVerifierPass) \
YY(LLVMExtraLPMAddJuliaLICMPass) \
YY(LLVMExtraLPMAddLowerSIMDLoopPass) \
YY(JLJITGetLLVMOrcExecutionSession) \
YY(JLJITGetJuliaOJIT) \
YY(JLJITGetExternalJITDylib) \
Expand Down
2 changes: 1 addition & 1 deletion src/llvm-julia-passes.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#ifdef MODULE_PASS
MODULE_PASS("CPUFeatures", CPUFeaturesPass, CPUFeaturesPass())
MODULE_PASS("RemoveNI", RemoveNIPass, RemoveNIPass())
MODULE_PASS("LowerSIMDLoop", LowerSIMDLoopPass, LowerSIMDLoopPass())
MODULE_PASS("FinalLowerGC", FinalLowerGCPass, FinalLowerGCPass())
MODULE_PASS("JuliaMultiVersioning", MultiVersioningPass, MultiVersioningPass())
MODULE_PASS("RemoveJuliaAddrspaces", RemoveJuliaAddrspacesPass, RemoveJuliaAddrspacesPass())
Expand All @@ -24,4 +23,5 @@ FUNCTION_PASS("GCInvariantVerifier", GCInvariantVerifierPass, GCInvariantVerifie
//Loop passes
#ifdef LOOP_PASS
LOOP_PASS("JuliaLICM", JuliaLICMPass, JuliaLICMPass())
LOOP_PASS("LowerSIMDLoop", LowerSIMDLoopPass, LowerSIMDLoopPass())
#endif
Loading

0 comments on commit cba88c1

Please sign in to comment.