From 57717eb8adf63e00ee51b722a81a6676b74f2678 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Apr 2022 12:52:48 +0200 Subject: [PATCH 1/6] Don't use new-llvm-pass-manager=no in test --- src/test/codegen/panic-in-drop-abort.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/codegen/panic-in-drop-abort.rs b/src/test/codegen/panic-in-drop-abort.rs index 39f73c4e3967e..7b9c41b658ae9 100644 --- a/src/test/codegen/panic-in-drop-abort.rs +++ b/src/test/codegen/panic-in-drop-abort.rs @@ -1,10 +1,12 @@ -// compile-flags: -Z panic-in-drop=abort -O -Z new-llvm-pass-manager=no +// compile-flags: -Z panic-in-drop=abort -O +// ignore-msvc // Ensure that unwinding code paths are eliminated from the output after // optimization. -// This test uses -Z new-llvm-pass-manager=no, because the expected optimization does not happen -// on targets using SEH exceptions (i.e. MSVC) anymore. The core issue is that Rust promises that +// This test uses ignore-msvc, because the expected optimization does not happen on targets using +// SEH exceptions with the new LLVM pass manager anymore, see +// https://github.com/llvm/llvm-project/issues/51311. The core issue is that Rust promises that // the drop_in_place() function can't unwind, but implements it in a way that *can*, because we // currently go out of our way to allow longjmps, which also use the unwinding mechanism on MSVC // targets. We should either forbid longjmps, or not assume nounwind, making this optimization From 25286dda2bded340cb43bea8d63fca3ebfed412b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Apr 2022 15:02:43 +0200 Subject: [PATCH 2/6] Drop support for -Znew-llvm-pass-manager=no with LLVM 15 --- compiler/rustc_codegen_llvm/src/back/write.rs | 6 ++++++ compiler/rustc_codegen_llvm/src/llvm_util.rs | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 7ef3b12cd08da..43e49bbeca9d1 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -523,6 +523,12 @@ pub(crate) unsafe fn optimize( let module_name = module.name.clone(); let module_name = Some(&module_name[..]); + if let Some(false) = config.new_llvm_pass_manager && llvm_util::get_version() >= (15, 0, 0) { + diag_handler.warn( + "ignoring `-Z new-llvm-pass-manager=no`, which is no longer supported with LLVM 15", + ); + } + if config.emit_no_opt_bc { let out = cgcx.output_filenames.temp_path_ext("no-opt.bc", module_name); let out = path_to_c_string(&out); diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index c24e369ae7284..7b407c94e7b06 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -542,6 +542,11 @@ pub(crate) fn should_use_new_llvm_pass_manager(user_opt: &Option, target_a // The new pass manager is enabled by default for LLVM >= 13. // This matches Clang, which also enables it since Clang 13. + // Since LLVM 15, the legacy pass manager is no longer supported. + if llvm_util::get_version() >= (15, 0, 0) { + return true; + } + // There are some perf issues with the new pass manager when targeting // s390x with LLVM 13, so enable the new pass manager only with LLVM 14. // See https://github.com/rust-lang/rust/issues/89609. From 7dc307fc7a55faddec71fff574c5789f84741315 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Apr 2022 14:55:24 +0200 Subject: [PATCH 3/6] Add missing include --- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 3ed4396d1e955..850b80e42801b 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -6,6 +6,7 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Mangler.h" #include "llvm/Object/Archive.h" #include "llvm/Object/COFFImportFile.h" #include "llvm/Object/ObjectFile.h" From 890cabac8acb566dee2d01bdfd9198546adfa310 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Apr 2022 13:22:39 +0200 Subject: [PATCH 4/6] Stub out various legacy PM functions with LLVM 15 --- compiler/rustc_codegen_llvm/src/back/lto.rs | 2 +- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 +- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 44 +++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 7a747a9cdee4e..3f5957bdb6e8f 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -625,7 +625,7 @@ pub(crate) fn run_pass_manager( if thin { llvm::LLVMRustPassManagerBuilderPopulateThinLTOPassManager(b, pm); } else { - llvm::LLVMPassManagerBuilderPopulateLTOPassManager( + llvm::LLVMRustPassManagerBuilderPopulateLTOPassManager( b, pm, /* Internalize = */ False, /* RunInliner = */ True, ); } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 7f533b0552a5d..492cd10b4657c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1842,7 +1842,7 @@ extern "C" { PMB: &PassManagerBuilder, PM: &PassManager<'_>, ); - pub fn LLVMPassManagerBuilderPopulateLTOPassManager( + pub fn LLVMRustPassManagerBuilderPopulateLTOPassManager( PMB: &PassManagerBuilder, PM: &PassManager<'_>, Internalize: Bool, diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 71f21dc666686..3f522b0bcef71 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -107,6 +107,7 @@ static LLVMRustPassKind toRust(PassKind Kind) { } extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) { +#if LLVM_VERSION_LT(15, 0) StringRef SR(PassName); PassRegistry *PR = PassRegistry::getPassRegistry(); @@ -115,36 +116,59 @@ extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) { return wrap(PI->createPass()); } return nullptr; +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif } extern "C" LLVMPassRef LLVMRustCreateAddressSanitizerFunctionPass(bool Recover) { +#if LLVM_VERSION_LT(15, 0) const bool CompileKernel = false; const bool UseAfterScope = true; return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover, UseAfterScope)); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif } extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) { +#if LLVM_VERSION_LT(15, 0) const bool CompileKernel = false; return wrap(createModuleAddressSanitizerLegacyPassPass(CompileKernel, Recover)); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif } extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool Recover) { +#if LLVM_VERSION_LT(15, 0) const bool CompileKernel = false; return wrap(createMemorySanitizerLegacyPassPass( MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel})); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif } extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() { +#if LLVM_VERSION_LT(15, 0) return wrap(createThreadSanitizerLegacyPassPass()); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif } extern "C" LLVMPassRef LLVMRustCreateHWAddressSanitizerPass(bool Recover) { +#if LLVM_VERSION_LT(15, 0) const bool CompileKernel = false; return wrap(createHWAddressSanitizerLegacyPassPass(CompileKernel, Recover)); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif } extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) { @@ -154,10 +178,22 @@ extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) { } extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) { +#if LLVM_VERSION_LT(15, 0) assert(RustPass); Pass *Pass = unwrap(RustPass); PassManagerBase *PMB = unwrap(PMR); PMB->add(Pass); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif +} +extern "C" void LLVMRustPassManagerBuilderPopulateLTOPassManager( + LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM, bool Internalize, bool RunInliner) { +#if LLVM_VERSION_LT(15, 0) + LLVMPassManagerBuilderPopulateLTOPassManager(PMB, PM, Internalize, RunInliner); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif } extern "C" @@ -165,12 +201,17 @@ void LLVMRustPassManagerBuilderPopulateThinLTOPassManager( LLVMPassManagerBuilderRef PMBR, LLVMPassManagerRef PMR ) { +#if LLVM_VERSION_LT(15, 0) unwrap(PMBR)->populateThinLTOPassManager(*unwrap(PMR)); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif } extern "C" void LLVMRustAddLastExtensionPasses( LLVMPassManagerBuilderRef PMBR, LLVMPassRef *Passes, size_t NumPasses) { +#if LLVM_VERSION_LT(15, 0) auto AddExtensionPasses = [Passes, NumPasses]( const PassManagerBuilder &Builder, PassManagerBase &PM) { for (size_t I = 0; I < NumPasses; I++) { @@ -183,6 +224,9 @@ void LLVMRustAddLastExtensionPasses( AddExtensionPasses); unwrap(PMBR)->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, AddExtensionPasses); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif } #ifdef LLVM_COMPONENT_X86 From 3cf0809a8d3ce66f468eed3dea96408d42eec33b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Apr 2022 16:12:23 +0200 Subject: [PATCH 5/6] Drop inaccurate comment The linked issue has an accurate description of the situation, drop the inaccurate comment. --- src/test/codegen/panic-in-drop-abort.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/test/codegen/panic-in-drop-abort.rs b/src/test/codegen/panic-in-drop-abort.rs index 7b9c41b658ae9..7a84484c41996 100644 --- a/src/test/codegen/panic-in-drop-abort.rs +++ b/src/test/codegen/panic-in-drop-abort.rs @@ -6,11 +6,7 @@ // This test uses ignore-msvc, because the expected optimization does not happen on targets using // SEH exceptions with the new LLVM pass manager anymore, see -// https://github.com/llvm/llvm-project/issues/51311. The core issue is that Rust promises that -// the drop_in_place() function can't unwind, but implements it in a way that *can*, because we -// currently go out of our way to allow longjmps, which also use the unwinding mechanism on MSVC -// targets. We should either forbid longjmps, or not assume nounwind, making this optimization -// incompatible with the current behavior of running cleanuppads on longjmp unwinding. +// https://github.com/llvm/llvm-project/issues/51311. // CHECK-NOT: {{(call|invoke).*}}should_not_appear_in_output From 6dc0bcc5db00524af73eb7dd2f6e24f38736f1aa Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 20 Apr 2022 09:25:13 +0200 Subject: [PATCH 6/6] Stub out more PassManagerBuilder functions --- compiler/rustc_codegen_llvm/src/back/write.rs | 25 ++++----- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 13 +++-- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 53 ++++++++++++++++++- 3 files changed, 68 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 43e49bbeca9d1..99e30531c226f 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -634,8 +634,8 @@ pub(crate) unsafe fn optimize( extra_passes.as_ptr(), extra_passes.len() as size_t, ); - llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm); - llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm); + llvm::LLVMRustPassManagerBuilderPopulateFunctionPassManager(b, fpm); + llvm::LLVMRustPassManagerBuilderPopulateModulePassManager(b, mpm); }); have_name_anon_globals_pass = have_name_anon_globals_pass || prepare_for_thin_lto; @@ -1091,7 +1091,7 @@ pub unsafe fn with_llvm_pmb( // Create the PassManagerBuilder for LLVM. We configure it with // reasonable defaults and prepare it to actually populate the pass // manager. - let builder = llvm::LLVMPassManagerBuilderCreate(); + let builder = llvm::LLVMRustPassManagerBuilderCreate(); let opt_size = config.opt_size.map_or(llvm::CodeGenOptSizeNone, |x| to_llvm_opt_settings(x).1); let inline_threshold = config.inline_threshold; let pgo_gen_path = get_pgo_gen_path(config); @@ -1108,14 +1108,9 @@ pub unsafe fn with_llvm_pmb( pgo_gen_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()), pgo_use_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()), pgo_sample_use_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()), + opt_size as c_int, ); - llvm::LLVMPassManagerBuilderSetSizeLevel(builder, opt_size as u32); - - if opt_size != llvm::CodeGenOptSizeNone { - llvm::LLVMPassManagerBuilderSetDisableUnrollLoops(builder, 1); - } - llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod, config.no_builtins); // Here we match what clang does (kinda). For O0 we only inline @@ -1124,16 +1119,16 @@ pub unsafe fn with_llvm_pmb( // thresholds copied from clang. match (opt_level, opt_size, inline_threshold) { (.., Some(t)) => { - llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t); + llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, t); } (llvm::CodeGenOptLevel::Aggressive, ..) => { - llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 275); + llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 275); } (_, llvm::CodeGenOptSizeDefault, _) => { - llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 75); + llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 75); } (_, llvm::CodeGenOptSizeAggressive, _) => { - llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 25); + llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 25); } (llvm::CodeGenOptLevel::None, ..) => { llvm::LLVMRustAddAlwaysInlinePass(builder, config.emit_lifetime_markers); @@ -1142,12 +1137,12 @@ pub unsafe fn with_llvm_pmb( llvm::LLVMRustAddAlwaysInlinePass(builder, config.emit_lifetime_markers); } (llvm::CodeGenOptLevel::Default, ..) => { - llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 225); + llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 225); } } f(builder); - llvm::LLVMPassManagerBuilderDispose(builder); + llvm::LLVMRustPassManagerBuilderDispose(builder); } // Create a `__imp_ = &symbol` global for every public static `symbol`. diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 492cd10b4657c..13baaddccd4df 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1825,20 +1825,18 @@ extern "C" { pub fn LLVMAddAnalysisPasses<'a>(T: &'a TargetMachine, PM: &PassManager<'a>); - pub fn LLVMPassManagerBuilderCreate() -> &'static mut PassManagerBuilder; - pub fn LLVMPassManagerBuilderDispose(PMB: &'static mut PassManagerBuilder); - pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: &PassManagerBuilder, Value: Bool); - pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(PMB: &PassManagerBuilder, Value: Bool); - pub fn LLVMPassManagerBuilderUseInlinerWithThreshold( + pub fn LLVMRustPassManagerBuilderCreate() -> &'static mut PassManagerBuilder; + pub fn LLVMRustPassManagerBuilderDispose(PMB: &'static mut PassManagerBuilder); + pub fn LLVMRustPassManagerBuilderUseInlinerWithThreshold( PMB: &PassManagerBuilder, threshold: c_uint, ); - pub fn LLVMPassManagerBuilderPopulateModulePassManager( + pub fn LLVMRustPassManagerBuilderPopulateModulePassManager( PMB: &PassManagerBuilder, PM: &PassManager<'_>, ); - pub fn LLVMPassManagerBuilderPopulateFunctionPassManager( + pub fn LLVMRustPassManagerBuilderPopulateFunctionPassManager( PMB: &PassManagerBuilder, PM: &PassManager<'_>, ); @@ -2308,6 +2306,7 @@ extern "C" { PGOGenPath: *const c_char, PGOUsePath: *const c_char, PGOSampleUsePath: *const c_char, + SizeLevel: c_int, ); pub fn LLVMRustAddLibraryInfo<'a>( PM: &PassManager<'a>, diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 3f522b0bcef71..38fddbdba54dd 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -187,6 +187,41 @@ extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) { report_fatal_error("Legacy PM not supported with LLVM 15"); #endif } + +extern "C" LLVMPassManagerBuilderRef LLVMRustPassManagerBuilderCreate() { +#if LLVM_VERSION_LT(15, 0) + return LLVMPassManagerBuilderCreate(); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif +} + +extern "C" void LLVMRustPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB) { +#if LLVM_VERSION_LT(15, 0) + LLVMPassManagerBuilderDispose(PMB); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif +} + +extern "C" void LLVMRustPassManagerBuilderPopulateFunctionPassManager( + LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM) { +#if LLVM_VERSION_LT(15, 0) + LLVMPassManagerBuilderPopulateFunctionPassManager(PMB, PM); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif +} + +extern "C" void LLVMRustPassManagerBuilderPopulateModulePassManager( + LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM) { +#if LLVM_VERSION_LT(15, 0) + LLVMPassManagerBuilderPopulateModulePassManager(PMB, PM); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif +} + extern "C" void LLVMRustPassManagerBuilderPopulateLTOPassManager( LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM, bool Internalize, bool RunInliner) { #if LLVM_VERSION_LT(15, 0) @@ -208,6 +243,15 @@ void LLVMRustPassManagerBuilderPopulateThinLTOPassManager( #endif } +extern "C" void LLVMRustPassManagerBuilderUseInlinerWithThreshold( + LLVMPassManagerBuilderRef PMB, unsigned Threshold) { +#if LLVM_VERSION_LT(15, 0) + LLVMPassManagerBuilderUseInlinerWithThreshold(PMB, Threshold); +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif +} + extern "C" void LLVMRustAddLastExtensionPasses( LLVMPassManagerBuilderRef PMBR, LLVMPassRef *Passes, size_t NumPasses) { @@ -577,12 +621,16 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) { extern "C" void LLVMRustConfigurePassManagerBuilder( LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel, bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO, - const char* PGOGenPath, const char* PGOUsePath, const char* PGOSampleUsePath) { + const char* PGOGenPath, const char* PGOUsePath, const char* PGOSampleUsePath, + int SizeLevel) { +#if LLVM_VERSION_LT(15, 0) unwrap(PMBR)->MergeFunctions = MergeFunctions; unwrap(PMBR)->SLPVectorize = SLPVectorize; unwrap(PMBR)->OptLevel = fromRust(OptLevel); unwrap(PMBR)->LoopVectorize = LoopVectorize; unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO; + unwrap(PMBR)->SizeLevel = SizeLevel; + unwrap(PMBR)->DisableUnrollLoops = SizeLevel != 0; if (PGOGenPath) { assert(!PGOUsePath && !PGOSampleUsePath); @@ -594,6 +642,9 @@ extern "C" void LLVMRustConfigurePassManagerBuilder( } else if (PGOSampleUsePath) { unwrap(PMBR)->PGOSampleUse = PGOSampleUsePath; } +#else + report_fatal_error("Legacy PM not supported with LLVM 15"); +#endif } // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`