From e650860ab60d66b03dba92e0fb4282baed8b6f24 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Fri, 2 Oct 2026 11:13:05 -0700 Subject: [PATCH 1/3] Use runCodeGen Abstraction for new LLVM This is the abstraction that clang/flang both use. It simplifies the code by quite a bit (although not until we delete the old version). Mainly this enables the use of the NewPM for LLVM targets that opt-in (currently only Lanai and MSP430, but more soon). --- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 78 ++++++++++--------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 3873701ae09ac..ca04e35877e2d 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -22,6 +22,9 @@ #include "llvm/MC/TargetRegistry.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Passes/PassBuilder.h" +#if LLVM_VERSION_GE(24, 0) +#include "llvm/Passes/RunCodeGen.h" +#endif #include "llvm/Passes/StandardInstrumentations.h" #include "llvm/Plugins/PassPlugin.h" #include "llvm/Support/CBindingWrapping.h" @@ -470,30 +473,6 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMModuleRef M, const char *Path, const char *DwoPath, LLVMRustFileType RustFileType, bool VerifyIR, bool DisableSimplifyLibCalls) { - std::unique_ptr PM = - std::make_unique(); - - PM->add(createTargetTransformInfoWrapperPass( - unwrap(Target)->getTargetIRAnalysis())); - - auto TargetTriple = Triple(unwrap(M)->getTargetTriple()); - TargetOptions *Options = &unwrap(Target)->Options; - auto TLII = TargetLibraryInfoImpl(TargetTriple); - if (DisableSimplifyLibCalls) - TLII.disableAllFunctions(); - PM->add(new TargetLibraryInfoWrapperPass(TLII)); -#if LLVM_VERSION_GE(24, 0) - // LLVM 24 removed TargetOptions::EABIVersion and ExceptionModel; the EABI - // version and exception model are now derived from the target triple and - // module flags respectively instead. - PM->add(new RuntimeLibraryInfoWrapper(Options->MCOptions.ABIName, - Options->VecLib)); -#else - PM->add(new RuntimeLibraryInfoWrapper( - TargetTriple, Options->ExceptionModel, Options->FloatABIType, - Options->EABIVersion, Options->MCOptions.ABIName, Options->VecLib)); -#endif - auto FileType = fromRust(RustFileType); std::string ErrorInfo; @@ -506,29 +485,52 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMModuleRef M, return LLVMRustResult::Failure; } - // TargetMachine::addPassesToEmitFile stores pointers to the output streams - // in a couple of places inside of the object. Explicitly delete the PM after - // we call run() to avoid dangling references. + std::unique_ptr DOS; auto BOS = buffer_ostream(OS); if (DwoPath) { - auto DOS = raw_fd_ostream(DwoPath, EC, sys::fs::OF_None); - EC.clear(); - if (EC) + DOS = std::make_unique(DwoPath, EC, + llvm::sys::fs::OF_None); + if (EC) { ErrorInfo = EC.message(); + DOS.reset(); + } if (ErrorInfo != "") { LLVMRustSetLastError(ErrorInfo.c_str()); return LLVMRustResult::Failure; } - auto DBOS = buffer_ostream(DOS); - unwrap(Target)->addPassesToEmitFile(*PM, BOS, &DBOS, FileType, !VerifyIR); - PM->run(*unwrap(M)); - PM.reset(); - } else { - unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, !VerifyIR); - PM->run(*unwrap(M)); - PM.reset(); + DOS->keep(); } +#if LLVM_VERSION_GE(24, 0) + Error CodeGenError = + runCodeGenPipeline(*unwrap(Target), *unwrap(M), BOS, DOS, FileType, false, + !VerifyIR, DisableSimplifyLibCalls); +#else + std::unique_ptr PM = + std::make_unique(); + + PM->add(createTargetTransformInfoWrapperPass( + unwrap(Target)->getTargetIRAnalysis())); + + auto TargetTriple = Triple(unwrap(M)->getTargetTriple()); + TargetOptions *Options = &unwrap(Target)->Options; + auto TLII = TargetLibraryInfoImpl(TargetTriple); + if (DisableSimplifyLibCalls) + TLII.disableAllFunctions(); + PM->add(new TargetLibraryInfoWrapperPass(TLII)); + PM->add(new RuntimeLibraryInfoWrapper( + TargetTriple, Options->ExceptionModel, Options->FloatABIType, + Options->EABIVersion, Options->MCOptions.ABIName, Options->VecLib)); + + // TargetMachine::addPassesToEmitFile stores pointers to the output streams + // in a couple of places inside of the object. Explicitly delete the PM after + // we call run() to avoid dangling references. + unwrap(Target)->addPassesToEmitFile(*PM, BOS, DOS ? &DOS->os() : nullptr, + FileType, !VerifyIR); + PM->run(*unwrap(M)); + PM.reset(); +#endif + return LLVMRustResult::Success; } From f97fb378181649e33e9ff8fb10ff6a693ac6ea84 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Fri, 2 Oct 2026 11:25:46 -0700 Subject: [PATCH 2/3] Add include for ToolOutputFile.h This does not seem to get transitively included otherwise. --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index ca04e35877e2d..7409a570faab0 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -31,6 +31,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Program.h" #include "llvm/Support/TimeProfiler.h" +#include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/Host.h" From 86c9fc25d187d7363b9bd2fee7a7574c6c87cdd9 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Fri, 2 Oct 2026 11:35:07 -0700 Subject: [PATCH 3/3] Only add RuntimeLibraryInfo if LLVM > 22 Otherwise it does not exist. Screwed up when trying to eliminate the LLVM 24+ constructor. --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 7409a570faab0..ef67e6c1e6ad7 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -519,9 +519,11 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMModuleRef M, if (DisableSimplifyLibCalls) TLII.disableAllFunctions(); PM->add(new TargetLibraryInfoWrapperPass(TLII)); +#if LLVM_VERSION_GE(22, 0) PM->add(new RuntimeLibraryInfoWrapper( TargetTriple, Options->ExceptionModel, Options->FloatABIType, Options->EABIVersion, Options->MCOptions.ABIName, Options->VecLib)); +#endif // TargetMachine::addPassesToEmitFile stores pointers to the output streams // in a couple of places inside of the object. Explicitly delete the PM after