From 08575c8465cd32ded4b0106b592eb8e1cb8a399b Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Mon, 27 Oct 2025 15:39:05 -0400 Subject: [PATCH 1/6] Use triple without roundtrip through string on LLVM 21 --- src/aotcompile.cpp | 24 ++++++++++++++++++++++++ src/codegen.cpp | 4 ++++ src/jitlayers.cpp | 11 ++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index fe8b97a052f03..5af783ee72bb6 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -1557,7 +1557,11 @@ static AOTOutputs add_output_impl(Module &M, TargetMachine &SourceTM, ShardTimer AOTOutputs out; auto TM = std::unique_ptr( SourceTM.getTarget().createTargetMachine( +#if JL_LLVM_VERSION < 210000 SourceTM.getTargetTriple().str(), +#else + SourceTM.getTargetTriple(), +#endif SourceTM.getTargetCPU(), SourceTM.getTargetFeatureString(), SourceTM.Options, @@ -1585,7 +1589,11 @@ static AOTOutputs add_output_impl(Module &M, TargetMachine &SourceTM, ShardTimer auto PMTM = std::unique_ptr( SourceTM.getTarget().createTargetMachine( +#if JL_LLVM_VERSION < 210000 SourceTM.getTargetTriple().str(), +#else + SourceTM.getTargetTriple(), +#endif SourceTM.getTargetCPU(), SourceTM.getTargetFeatureString(), SourceTM.Options, @@ -2141,7 +2149,11 @@ void jl_dump_native_impl(void *native_code, } std::unique_ptr SourceTM( jl_ExecutionEngine->getTarget().createTargetMachine( +#if JL_LLVM_VERSION < 210000 TheTriple.getTriple(), +#else + TheTriple, +#endif jl_ExecutionEngine->getTargetCPU(), jl_ExecutionEngine->getTargetFeatureString(), jl_ExecutionEngine->getTargetOptions(), @@ -2174,7 +2186,11 @@ void jl_dump_native_impl(void *native_code, LLVMContext Context; Context.setDiscardValueNames(true); Module sysimgM("sysimg", Context); +#if JL_LLVM_VERSION < 210000 sysimgM.setTargetTriple(TheTriple.str()); +#else + sysimgM.setTargetTriple(TheTriple); +#endif sysimgM.setDataLayout(DL); sysimgM.setStackProtectorGuard(StackProtectorGuard); sysimgM.setOverrideStackAlignment(OverrideStackAlignment); @@ -2242,7 +2258,11 @@ void jl_dump_native_impl(void *native_code, data->M.withModuleDo([&](Module &dataM) { JL_TIMING(NATIVE_AOT, NATIVE_Setup); +#if JL_LLVM_VERSION < 210000 dataM.setTargetTriple(TheTriple.str()); +#else + dataM.setTargetTriple(TheTriple); +#endif dataM.setDataLayout(DL); dataM.setPICLevel(PICLevel::BigPIC); auto &Context = dataM.getContext(); @@ -2343,7 +2363,11 @@ void jl_dump_native_impl(void *native_code, LLVMContext Context; Context.setDiscardValueNames(true); Module metadataM("metadata", Context); +#if JL_LLVM_VERSION < 210000 metadataM.setTargetTriple(TheTriple.str()); +#else + metadataM.setTargetTriple(TheTriple); +#endif metadataM.setDataLayout(DL); metadataM.setStackProtectorGuard(StackProtectorGuard); metadataM.setOverrideStackAlignment(OverrideStackAlignment); diff --git a/src/codegen.cpp b/src/codegen.cpp index d40db1eb082e5..1183afbaf83b2 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2812,7 +2812,11 @@ std::unique_ptr jl_create_llvm_module(StringRef name, LLVMContext &conte m->addModuleFlag(llvm::Module::Warning, "Debug Info Version", llvm::DEBUG_METADATA_VERSION); m->setDataLayout(DL); +#if JL_LLVM_VERSION < 210000 m->setTargetTriple(triple.str()); +#else + m->setTargetTriple(triple); +#endif if (triple.isOSWindows() && triple.getArch() == Triple::x86) { // tell Win32 to assume the stack is always 16-byte aligned, diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 90091cc1f38db..4250923d91889 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -1396,7 +1396,12 @@ namespace { } auto optlevel = CodeGenOptLevelFor(jl_options.opt_level); auto TM = TheTarget->createTargetMachine( - TheTriple.getTriple(), TheCPU, FeaturesStr, +#if JL_LLVM_VERSION < 210000 + TheTriple.getTriple(), +#else + TheTriple, +#endif + TheCPU, FeaturesStr, options, relocmodel, codemodel, @@ -2382,7 +2387,11 @@ std::unique_ptr JuliaOJIT::cloneTargetMachine() const { auto NewTM = std::unique_ptr(getTarget() .createTargetMachine( +#if JL_LLVM_VERSION < 210000 getTargetTriple().str(), +#else + getTargetTriple(), +#endif getTargetCPU(), getTargetFeatureString(), getTargetOptions(), From 337169a406db10de10b43326cdf03b3a2156f9b1 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Mon, 27 Oct 2025 15:40:37 -0400 Subject: [PATCH 2/6] Use CaptureInfo for NoCapture on LLVM 21 --- src/codegen.cpp | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 1183afbaf83b2..b48f516530260 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -605,6 +605,24 @@ AttributeSet Attributes(LLVMContext &C, std::initializer_list(attrs)); } +static inline Attribute NoCaptureAttr(LLVMContext &C) +{ +#if JL_LLVM_VERSION < 210000 + return Attribute::get(C, Attribute::NoCapture); +#else + return Attribute::getWithCaptureInfo(C, CaptureInfo(CaptureComponents::None)); +#endif +} + +static inline void addNoCaptureAttr(AttrBuilder ¶m) +{ +#if JL_LLVM_VERSION < 210000 + param.addAttribute(Attribute::NoCapture); +#else + param.addCapturesAttr(CaptureInfo(CaptureComponents::None)); +#endif +} + static Type *get_pjlvalue(LLVMContext &C) { return JuliaType::get_pjlvalue_ty(C); } static FunctionType *get_func_sig(LLVMContext &C) { return JuliaType::get_jlfunc_ty(C); } @@ -617,7 +635,7 @@ static AttributeList get_func_attrs(LLVMContext &C) AttributeSet(), Attributes(C, {Attribute::NonNull}), {AttributeSet(), - Attributes(C, {Attribute::NoAlias, Attribute::ReadOnly, Attribute::NoCapture, Attribute::NoUndef})}); + Attributes(C, {Attribute::NoAlias, Attribute::ReadOnly, Attribute::NoUndef}, {NoCaptureAttr(C)})}); } static AttributeList get_attrs_noreturn(LLVMContext &C) @@ -996,7 +1014,7 @@ static const auto jllockvalue_func = new JuliaFunction<>{ [](LLVMContext &C) { return AttributeList::get(C, AttributeSet(), AttributeSet(), - {Attributes(C, {Attribute::NoCapture})}); }, + {Attributes(C, {}, {NoCaptureAttr(C)})}); }, }; static const auto jlunlockvalue_func = new JuliaFunction<>{ XSTR(jl_unlock_value), @@ -1005,7 +1023,7 @@ static const auto jlunlockvalue_func = new JuliaFunction<>{ [](LLVMContext &C) { return AttributeList::get(C, AttributeSet(), AttributeSet(), - {Attributes(C, {Attribute::NoCapture})}); }, + {Attributes(C, {}, {NoCaptureAttr(C)})}); }, }; static const auto jllockfield_func = new JuliaFunction<>{ XSTR(jl_lock_field), @@ -1014,7 +1032,7 @@ static const auto jllockfield_func = new JuliaFunction<>{ [](LLVMContext &C) { return AttributeList::get(C, AttributeSet(), AttributeSet(), - {Attributes(C, {Attribute::NoCapture})}); }, + {Attributes(C, {}, {NoCaptureAttr(C)})}); }, }; static const auto jlunlockfield_func = new JuliaFunction<>{ XSTR(jl_unlock_field), @@ -1023,7 +1041,7 @@ static const auto jlunlockfield_func = new JuliaFunction<>{ [](LLVMContext &C) { return AttributeList::get(C, AttributeSet(), AttributeSet(), - {Attributes(C, {Attribute::NoCapture})}); }, + {Attributes(C, {}, {NoCaptureAttr(C)})}); }, }; static const auto jlenter_func = new JuliaFunction<>{ XSTR(jl_enter_handler), @@ -1489,7 +1507,7 @@ static const auto gc_loaded_func = new JuliaFunction<>{ RetAttrs.addAttribute(Attribute::NonNull); RetAttrs.addAttribute(Attribute::NoUndef); return AttributeList::get(C, AttributeSet::get(C,FnAttrs), AttributeSet::get(C,RetAttrs), - { Attributes(C, {Attribute::NonNull, Attribute::NoUndef, Attribute::ReadNone, Attribute::NoCapture}), + { Attributes(C, {Attribute::NonNull, Attribute::NoUndef, Attribute::ReadNone}, {NoCaptureAttr(C)}), Attributes(C, {Attribute::NonNull, Attribute::NoUndef, Attribute::ReadNone}) }); }, }; @@ -8109,7 +8127,7 @@ static jl_returninfo_t get_specsig_function(jl_codegen_params_t ¶ms, Module param.addAttribute("julia.return_roots", std::to_string(tracked_count)); } param.addAttribute(Attribute::NoAlias); - param.addAttribute(Attribute::NoCapture); + addNoCaptureAttr(param); param.addAttribute(Attribute::NoUndef); attrs.push_back(AttributeSet::get(M->getContext(), param)); assert(fsig.size() == 1); @@ -8117,7 +8135,7 @@ static jl_returninfo_t get_specsig_function(jl_codegen_params_t ¶ms, Module if (props.cc == jl_returninfo_t::Union) { AttrBuilder param(M->getContext()); param.addAttribute(Attribute::NoAlias); - param.addAttribute(Attribute::NoCapture); + addNoCaptureAttr(param); param.addAttribute(Attribute::NoUndef); attrs.push_back(AttributeSet::get(M->getContext(), param)); assert(fsig.size() == 1); @@ -8126,7 +8144,7 @@ static jl_returninfo_t get_specsig_function(jl_codegen_params_t ¶ms, Module if (props.return_roots) { AttrBuilder param(M->getContext()); param.addAttribute(Attribute::NoAlias); - param.addAttribute(Attribute::NoCapture); + addNoCaptureAttr(param); param.addAttribute(Attribute::NoUndef); param.addAttribute("julia.return_roots", std::to_string(props.return_roots)); attrs.push_back(AttributeSet::get(M->getContext(), param)); @@ -8161,7 +8179,7 @@ static jl_returninfo_t get_specsig_function(jl_codegen_params_t ¶ms, Module AttrBuilder param(M->getContext()); Type *ty = et; if (et == nullptr || et->isAggregateType()) { // aggregate types are passed by pointer - param.addAttribute(Attribute::NoCapture); + addNoCaptureAttr(param); param.addAttribute(Attribute::ReadOnly); ty = PointerType::get(M->getContext(), AddressSpace::Derived); } From f995c6a429f566381faf8519f8954269e6385da3 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Mon, 27 Oct 2025 15:42:12 -0400 Subject: [PATCH 3/6] Removed IsNewDbgInfoFormat field --- src/aotcompile.cpp | 2 ++ src/codegen.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 5af783ee72bb6..6e86b7d245558 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -565,7 +565,9 @@ Function *IRLinker_copyFunctionProto(Module *DstM, Function *SF) { auto *F = Function::Create(SF->getFunctionType(), SF->getLinkage(), SF->getAddressSpace(), SF->getName(), DstM); F->copyAttributesFrom(SF); +#if JL_LLVM_VERSION < 210000 F->IsNewDbgInfoFormat = SF->IsNewDbgInfoFormat; +#endif // Remove these copied constants since they point to the source module. F->setPersonalityFn(nullptr); diff --git a/src/codegen.cpp b/src/codegen.cpp index b48f516530260..5f98ad32e23ed 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -10060,7 +10060,9 @@ void linkFunctionBody(Function &Dst, Function &Src) Dst.setPersonalityFn(Src.getPersonalityFn()); if (Src.hasPersonalityFn()) Dst.setPersonalityFn(Src.getPersonalityFn()); +#if JL_LLVM_VERSION < 210000 assert(Src.IsNewDbgInfoFormat == Dst.IsNewDbgInfoFormat); +#endif // Copy over the metadata attachments without remapping. Dst.copyMetadata(&Src, 0); From ce6c055e8ee623cbbfc870f3a75e6fd130e30a71 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Mon, 27 Oct 2025 15:42:47 -0400 Subject: [PATCH 4/6] Alias information change for LLVM 21/22 --- src/cgutils.cpp | 5 +++++ src/codegen.cpp | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/src/cgutils.cpp b/src/cgutils.cpp index d89f85302b2e3..92bfcc869cc68 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -1158,8 +1158,13 @@ static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, jl_aliasinfo_t const // above problem won't be as serious. auto merged_ai = dst_ai.merge(src_ai); +#if JL_LLVM_VERSION < 210000 ctx.builder.CreateMemCpy(dst, align_dst, src, align_src, sz, is_volatile, merged_ai.tbaa, merged_ai.tbaa_struct, merged_ai.scope, merged_ai.noalias); +#else + ctx.builder.CreateMemCpy(dst, align_dst, src, align_src, sz, is_volatile, + merged_ai.toAAMDNodes()); +#endif } template diff --git a/src/codegen.cpp b/src/codegen.cpp index 5f98ad32e23ed..3729b7dbf0a18 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1721,6 +1721,15 @@ struct jl_aliasinfo_t { // memory region non-aliasing. It should be deleted once the TBAA metadata // is improved to encode only memory layout and *not* memory regions. static jl_aliasinfo_t fromTBAA(jl_codectx_t &ctx, MDNode *tbaa); + + AAMDNodes toAAMDNodes() const + { +#if JL_LLVM_VERSION < 220000 + return AAMDNodes(tbaa, tbaa_struct, scope, noalias); +#else + return AAMDNodes(tbaa, tbaa_struct, scope, noalias, nullptr); +#endif + } }; // metadata tracking for a llvm Value* during codegen From 7209461c39a21f83fcd645270c49eab078c0c8a8 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Fri, 5 Dec 2025 09:51:26 -0500 Subject: [PATCH 5/6] runFinalizedActions API change --- src/cgmemmgr.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/cgmemmgr.cpp b/src/cgmemmgr.cpp index e570834b8500e..6f7bd71ffb08a 100644 --- a/src/cgmemmgr.cpp +++ b/src/cgmemmgr.cpp @@ -1013,10 +1013,19 @@ class JLJITLinkMemoryManager::InFlightAlloc if (!FA) return OnFinalized(FA.takeError()); // Need to handle dealloc actions when we GC code +#if JL_LLVM_VERSION >= 210000 && JL_LLVM_VERSION < 220000 + // This change was reverted before llvm 22 is branched off + orc::shared::runFinalizeActions(GP->allocActions(), [&] (auto E) { + if (!E) + return OnFinalized(E.takeError()); + OnFinalized(std::move(FA)); + }); +#else auto E = orc::shared::runFinalizeActions(GP->allocActions()); if (!E) return OnFinalized(E.takeError()); OnFinalized(std::move(FA)); +#endif }); } }; From ad589da1f96b82bcd60ea269d7fae60a73012fb8 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Mon, 27 Oct 2025 15:43:26 -0400 Subject: [PATCH 6/6] Assorted return value/argument type/include change for LLVM 21 --- src/debuginfo.cpp | 7 ++++++- src/disasm.cpp | 16 +++++++++++----- src/jitlayers.cpp | 6 +++++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index f8af82fa72c3c..c461f0938e0c5 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -505,8 +505,13 @@ static int lookup_pointer( else { int havelock = jl_lock_profile_wr(); assert(havelock); (void)havelock; - info = context->getLineInfoForAddress(makeAddress(Section, pointer + slide), infoSpec); + auto lineinfo = context->getLineInfoForAddress(makeAddress(Section, pointer + slide), infoSpec); jl_unlock_profile_wr(); +#if JL_LLVM_VERSION < 210000 + info = std::move(lineinfo); +#else + info = std::move(lineinfo.value()); +#endif } jl_frame_t *frame = &(*frames)[i]; diff --git a/src/disasm.cpp b/src/disasm.cpp index 3f994143a6c8b..7f79737a9a7cb 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -924,7 +924,11 @@ static void jl_dump_asm_internal( // LLVM will destroy the formatted stream, and we keep the raw stream. std::unique_ptr ustream(new formatted_raw_ostream(rstream)); std::unique_ptr Streamer( -#if JL_LLVM_VERSION >= 190000 +#if JL_LLVM_VERSION >= 210000 + TheTarget->createAsmStreamer(Ctx, std::move(ustream), + + std::move(IP), std::move(CE), std::move(MAB)) +#elif JL_LLVM_VERSION >= 190000 TheTarget->createAsmStreamer(Ctx, std::move(ustream), IP.release(), std::move(CE), std::move(MAB)) @@ -1268,8 +1272,8 @@ jl_value_t *jl_dump_function_asm_impl(jl_llvmf_dump_t* dump, char emit_mc, const OutputAsmDialect = 0; if (!strcmp(asm_variant, "intel")) OutputAsmDialect = 1; - MCInstPrinter *InstPrinter = TM->getTarget().createMCInstPrinter( - jl_ExecutionEngine->getTargetTriple(), OutputAsmDialect, MAI, MII, MRI); + std::unique_ptr InstPrinter(TM->getTarget().createMCInstPrinter( + jl_ExecutionEngine->getTargetTriple(), OutputAsmDialect, MAI, MII, MRI)); std::unique_ptr MAB(TM->getTarget().createMCAsmBackend( STI, MRI, Options)); std::unique_ptr MCE; @@ -1278,8 +1282,10 @@ jl_value_t *jl_dump_function_asm_impl(jl_llvmf_dump_t* dump, char emit_mc, const } auto FOut = std::make_unique(asmfile); std::unique_ptr S(TM->getTarget().createAsmStreamer( -#if JL_LLVM_VERSION >= 190000 - *Context, std::move(FOut), InstPrinter, std::move(MCE), std::move(MAB) +#if JL_LLVM_VERSION >= 210000 + *Context, std::move(FOut), std::move(InstPrinter), std::move(MCE), std::move(MAB) +#elif JL_LLVM_VERSION >= 190000 + *Context, std::move(FOut), InstPrinter.release(), std::move(MCE), std::move(MAB) #else *Context, std::move(FOut), true, true, InstPrinter, std::move(MCE), std::move(MAB), false diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 4250923d91889..0d504ec3e75f6 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -14,6 +14,9 @@ #include #include #include +#if JL_LLVM_VERSION >= 210000 +# include +#endif #include #if JL_LLVM_VERSION >= 200000 #include @@ -1931,7 +1934,8 @@ JuliaOJIT::JuliaOJIT() MemMgr(createRTDyldMemoryManager()), UnlockedObjectLayer( ES, - [this]() { + [this](auto&&...) { + // LLVM 21+ passes in a memory buffer std::unique_ptr result(new ForwardingMemoryManager(MemMgr)); return result; }