Rollup merge of #101997 - cuviper:drop-legacy-pm, r=nikic

Remove support for legacy PM

This removes support for optimizing with LLVM's legacy pass manager, as well as the unstable `-Znew-llvm-pass-manager` option. We have been defaulting to the new PM since LLVM 13 (except for s390x that waited for 14), and LLVM 15 removed support altogether. The only place we still use the legacy PM is for writing the output file, just like `llc` does.

cc #74705
r? ``@nikic``
This commit is contained in:
fee1-dead 2022-09-25 22:06:38 +08:00 committed by GitHub
commit 07467c5308
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 28 additions and 685 deletions

View File

@ -3263,7 +3263,6 @@ dependencies = [
"bitflags",
"cstr",
"libc",
"libloading",
"measureme",
"object 0.29.0",
"rustc-demangle",

View File

@ -11,7 +11,6 @@ doctest = false
bitflags = "1.0"
cstr = "0.2"
libc = "0.2"
libloading = "0.7.1"
measureme = "10.0.0"
object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "archive", "coff", "elf", "macho", "pe"] }
tracing = "0.1"

View File

@ -1,8 +1,6 @@
use crate::back::write::{
self, save_temp_bitcode, to_llvm_opt_settings, with_llvm_pmb, DiagnosticHandlers,
};
use crate::llvm::{self, build_string, False, True};
use crate::{llvm_util, LlvmCodegenBackend, ModuleLlvm};
use crate::back::write::{self, save_temp_bitcode, DiagnosticHandlers};
use crate::llvm::{self, build_string};
use crate::{LlvmCodegenBackend, ModuleLlvm};
use object::read::archive::ArchiveFile;
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
use rustc_codegen_ssa::back::symbol_export;
@ -597,61 +595,9 @@ pub(crate) fn run_pass_manager(
1,
);
}
if llvm_util::should_use_new_llvm_pass_manager(
&config.new_llvm_pass_manager,
&cgcx.target_arch,
) {
let opt_stage = if thin { llvm::OptStage::ThinLTO } else { llvm::OptStage::FatLTO };
let opt_level = config.opt_level.unwrap_or(config::OptLevel::No);
write::optimize_with_new_llvm_pass_manager(
cgcx,
diag_handler,
module,
config,
opt_level,
opt_stage,
)?;
debug!("lto done");
return Ok(());
}
let pm = llvm::LLVMCreatePassManager();
llvm::LLVMAddAnalysisPasses(module.module_llvm.tm, pm);
if config.verify_llvm_ir {
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr().cast());
llvm::LLVMRustAddPass(pm, pass.unwrap());
}
let opt_level = config
.opt_level
.map(|x| to_llvm_opt_settings(x).0)
.unwrap_or(llvm::CodeGenOptLevel::None);
with_llvm_pmb(module.module_llvm.llmod(), config, opt_level, false, &mut |b| {
if thin {
llvm::LLVMRustPassManagerBuilderPopulateThinLTOPassManager(b, pm);
} else {
llvm::LLVMRustPassManagerBuilderPopulateLTOPassManager(
b, pm, /* Internalize = */ False, /* RunInliner = */ True,
);
}
});
// We always generate bitcode through ThinLTOBuffers,
// which do not support anonymous globals
if config.bitcode_needed() {
let pass = llvm::LLVMRustFindAndCreatePass("name-anon-globals\0".as_ptr().cast());
llvm::LLVMRustAddPass(pm, pass.unwrap());
}
if config.verify_llvm_ir {
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr().cast());
llvm::LLVMRustAddPass(pm, pass.unwrap());
}
llvm::LLVMRunPassManager(pm, module.module_llvm.llmod());
llvm::LLVMDisposePassManager(pm);
let opt_stage = if thin { llvm::OptStage::ThinLTO } else { llvm::OptStage::FatLTO };
let opt_level = config.opt_level.unwrap_or(config::OptLevel::No);
write::llvm_optimize(cgcx, diag_handler, module, config, opt_level, opt_stage)?;
}
debug!("lto done");
Ok(())

View File

@ -21,7 +21,6 @@ use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_errors::{FatalError, Handler, Level};
use rustc_fs_util::{link_or_copy, path_to_c_string};
use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath};
use rustc_session::Session;
@ -417,7 +416,7 @@ fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> {
}
}
pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
pub(crate) unsafe fn llvm_optimize(
cgcx: &CodegenContext<LlvmCodegenBackend>,
diag_handler: &Handler,
module: &ModuleCodegen<ModuleLlvm>,
@ -465,7 +464,7 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
// FIXME: NewPM doesn't provide a facility to pass custom InlineParams.
// We would have to add upstream support for this first, before we can support
// config.inline_threshold and our more aggressive default thresholds.
let result = llvm::LLVMRustOptimizeWithNewPassManager(
let result = llvm::LLVMRustOptimize(
module.module_llvm.llmod(),
&*module.module_llvm.tm,
to_pass_builder_opt_level(opt_level),
@ -509,18 +508,11 @@ pub(crate) unsafe fn optimize(
let llmod = module.module_llvm.llmod();
let llcx = &*module.module_llvm.llcx;
let tm = &*module.module_llvm.tm;
let _handlers = DiagnosticHandlers::new(cgcx, diag_handler, llcx);
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);
@ -528,184 +520,17 @@ pub(crate) unsafe fn optimize(
}
if let Some(opt_level) = config.opt_level {
if llvm_util::should_use_new_llvm_pass_manager(
&config.new_llvm_pass_manager,
&cgcx.target_arch,
) {
let opt_stage = match cgcx.lto {
Lto::Fat => llvm::OptStage::PreLinkFatLTO,
Lto::Thin | Lto::ThinLocal => llvm::OptStage::PreLinkThinLTO,
_ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
_ => llvm::OptStage::PreLinkNoLTO,
};
return optimize_with_new_llvm_pass_manager(
cgcx,
diag_handler,
module,
config,
opt_level,
opt_stage,
);
}
if cgcx.prof.llvm_recording_enabled() {
diag_handler
.warn("`-Z self-profile-events = llvm` requires `-Z new-llvm-pass-manager`");
}
// Create the two optimizing pass managers. These mirror what clang
// does, and are by populated by LLVM's default PassManagerBuilder.
// Each manager has a different set of passes, but they also share
// some common passes.
let fpm = llvm::LLVMCreateFunctionPassManagerForModule(llmod);
let mpm = llvm::LLVMCreatePassManager();
{
let find_pass = |pass_name: &str| {
let pass_name = SmallCStr::new(pass_name);
llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr())
};
if config.verify_llvm_ir {
// Verification should run as the very first pass.
llvm::LLVMRustAddPass(fpm, find_pass("verify").unwrap());
}
let mut extra_passes = Vec::new();
let mut have_name_anon_globals_pass = false;
for pass_name in &config.passes {
if pass_name == "lint" {
// Linting should also be performed early, directly on the generated IR.
llvm::LLVMRustAddPass(fpm, find_pass("lint").unwrap());
continue;
}
if let Some(pass) = find_pass(pass_name) {
extra_passes.push(pass);
} else {
diag_handler.warn(&format!("unknown pass `{}`, ignoring", pass_name));
}
if pass_name == "name-anon-globals" {
have_name_anon_globals_pass = true;
}
}
// Instrumentation must be inserted before optimization,
// otherwise LLVM may optimize some functions away which
// breaks llvm-cov.
//
// This mirrors what Clang does in lib/CodeGen/BackendUtil.cpp.
if config.instrument_gcov {
llvm::LLVMRustAddPass(mpm, find_pass("insert-gcov-profiling").unwrap());
}
if config.instrument_coverage {
llvm::LLVMRustAddPass(mpm, find_pass("instrprof").unwrap());
}
if config.debug_info_for_profiling {
llvm::LLVMRustAddPass(mpm, find_pass("add-discriminators").unwrap());
}
add_sanitizer_passes(config, &mut extra_passes);
// Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need
// to make sure we run LLVM's NameAnonGlobals pass when emitting bitcode; otherwise
// we'll get errors in LLVM.
let using_thin_buffers = config.bitcode_needed();
if !config.no_prepopulate_passes {
llvm::LLVMAddAnalysisPasses(tm, fpm);
llvm::LLVMAddAnalysisPasses(tm, mpm);
let opt_level = to_llvm_opt_settings(opt_level).0;
let prepare_for_thin_lto = cgcx.lto == Lto::Thin
|| cgcx.lto == Lto::ThinLocal
|| (cgcx.lto != Lto::Fat && cgcx.opts.cg.linker_plugin_lto.enabled());
with_llvm_pmb(llmod, config, opt_level, prepare_for_thin_lto, &mut |b| {
llvm::LLVMRustAddLastExtensionPasses(
b,
extra_passes.as_ptr(),
extra_passes.len() as size_t,
);
llvm::LLVMRustPassManagerBuilderPopulateFunctionPassManager(b, fpm);
llvm::LLVMRustPassManagerBuilderPopulateModulePassManager(b, mpm);
});
have_name_anon_globals_pass = have_name_anon_globals_pass || prepare_for_thin_lto;
if using_thin_buffers && !prepare_for_thin_lto {
llvm::LLVMRustAddPass(mpm, find_pass("name-anon-globals").unwrap());
have_name_anon_globals_pass = true;
}
} else {
// If we don't use the standard pipeline, directly populate the MPM
// with the extra passes.
for pass in extra_passes {
llvm::LLVMRustAddPass(mpm, pass);
}
}
if using_thin_buffers && !have_name_anon_globals_pass {
// As described above, this will probably cause an error in LLVM
if config.no_prepopulate_passes {
diag_handler.err(
"The current compilation is going to use thin LTO buffers \
without running LLVM's NameAnonGlobals pass. \
This will likely cause errors in LLVM. Consider adding \
-C passes=name-anon-globals to the compiler command line.",
);
} else {
bug!(
"We are using thin LTO buffers without running the NameAnonGlobals pass. \
This will likely cause errors in LLVM and should never happen."
);
}
}
}
diag_handler.abort_if_errors();
// Finally, run the actual optimization passes
{
let _timer = cgcx.prof.extra_verbose_generic_activity(
"LLVM_module_optimize_function_passes",
&*module.name,
);
llvm::LLVMRustRunFunctionPassManager(fpm, llmod);
}
{
let _timer = cgcx.prof.extra_verbose_generic_activity(
"LLVM_module_optimize_module_passes",
&*module.name,
);
llvm::LLVMRunPassManager(mpm, llmod);
}
// Deallocate managers that we're now done with
llvm::LLVMDisposePassManager(fpm);
llvm::LLVMDisposePassManager(mpm);
let opt_stage = match cgcx.lto {
Lto::Fat => llvm::OptStage::PreLinkFatLTO,
Lto::Thin | Lto::ThinLocal => llvm::OptStage::PreLinkThinLTO,
_ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
_ => llvm::OptStage::PreLinkNoLTO,
};
return llvm_optimize(cgcx, diag_handler, module, config, opt_level, opt_stage);
}
Ok(())
}
unsafe fn add_sanitizer_passes(config: &ModuleConfig, passes: &mut Vec<&'static mut llvm::Pass>) {
if config.sanitizer.contains(SanitizerSet::ADDRESS) {
let recover = config.sanitizer_recover.contains(SanitizerSet::ADDRESS);
passes.push(llvm::LLVMRustCreateAddressSanitizerFunctionPass(recover));
passes.push(llvm::LLVMRustCreateModuleAddressSanitizerPass(recover));
}
if config.sanitizer.contains(SanitizerSet::MEMORY) {
let track_origins = config.sanitizer_memory_track_origins as c_int;
let recover = config.sanitizer_recover.contains(SanitizerSet::MEMORY);
passes.push(llvm::LLVMRustCreateMemorySanitizerPass(track_origins, recover));
}
if config.sanitizer.contains(SanitizerSet::THREAD) {
passes.push(llvm::LLVMRustCreateThreadSanitizerPass());
}
if config.sanitizer.contains(SanitizerSet::HWADDRESS) {
let recover = config.sanitizer_recover.contains(SanitizerSet::HWADDRESS);
passes.push(llvm::LLVMRustCreateHWAddressSanitizerPass(recover));
}
}
pub(crate) fn link(
cgcx: &CodegenContext<LlvmCodegenBackend>,
diag_handler: &Handler,
@ -1072,72 +897,6 @@ unsafe fn embed_bitcode(
}
}
pub unsafe fn with_llvm_pmb(
llmod: &llvm::Module,
config: &ModuleConfig,
opt_level: llvm::CodeGenOptLevel,
prepare_for_thin_lto: bool,
f: &mut dyn FnMut(&llvm::PassManagerBuilder),
) {
use std::ptr;
// Create the PassManagerBuilder for LLVM. We configure it with
// reasonable defaults and prepare it to actually populate the pass
// manager.
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);
let pgo_use_path = get_pgo_use_path(config);
let pgo_sample_use_path = get_pgo_sample_use_path(config);
llvm::LLVMRustConfigurePassManagerBuilder(
builder,
opt_level,
config.merge_functions,
config.vectorize_slp,
config.vectorize_loop,
prepare_for_thin_lto,
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::LLVMRustAddBuilderLibraryInfo(builder, llmod, config.no_builtins);
// Here we match what clang does (kinda). For O0 we only inline
// always-inline functions (but don't add lifetime intrinsics), at O1 we
// inline with lifetime intrinsics, and O2+ we add an inliner with a
// thresholds copied from clang.
match (opt_level, opt_size, inline_threshold) {
(.., Some(t)) => {
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, t);
}
(llvm::CodeGenOptLevel::Aggressive, ..) => {
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 275);
}
(_, llvm::CodeGenOptSizeDefault, _) => {
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 75);
}
(_, llvm::CodeGenOptSizeAggressive, _) => {
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 25);
}
(llvm::CodeGenOptLevel::None, ..) => {
llvm::LLVMRustAddAlwaysInlinePass(builder, config.emit_lifetime_markers);
}
(llvm::CodeGenOptLevel::Less, ..) => {
llvm::LLVMRustAddAlwaysInlinePass(builder, config.emit_lifetime_markers);
}
(llvm::CodeGenOptLevel::Default, ..) => {
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 225);
}
}
f(builder);
llvm::LLVMRustPassManagerBuilderDispose(builder);
}
// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
// This is required to satisfy `dllimport` references to static data in .rlibs
// when using MSVC linker. We do this only for data, as linker can fix up

View File

@ -1792,18 +1792,9 @@ extern "C" {
/// Writes a module to the specified path. Returns 0 on success.
pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;
/// Creates a pass manager.
/// Creates a legacy pass manager -- only used for final codegen.
pub fn LLVMCreatePassManager<'a>() -> &'a mut PassManager<'a>;
/// Creates a function-by-function pass manager
pub fn LLVMCreateFunctionPassManagerForModule(M: &Module) -> &mut PassManager<'_>;
/// Disposes a pass manager.
pub fn LLVMDisposePassManager<'a>(PM: &'a mut PassManager<'a>);
/// Runs a pass manager on a module.
pub fn LLVMRunPassManager<'a>(PM: &PassManager<'a>, M: &'a Module) -> Bool;
pub fn LLVMInitializePasses();
pub fn LLVMTimeTraceProfilerInitialize();
@ -1814,32 +1805,6 @@ extern "C" {
pub fn LLVMAddAnalysisPasses<'a>(T: &'a TargetMachine, PM: &PassManager<'a>);
pub fn LLVMRustPassManagerBuilderCreate() -> &'static mut PassManagerBuilder;
pub fn LLVMRustPassManagerBuilderDispose(PMB: &'static mut PassManagerBuilder);
pub fn LLVMRustPassManagerBuilderUseInlinerWithThreshold(
PMB: &PassManagerBuilder,
threshold: c_uint,
);
pub fn LLVMRustPassManagerBuilderPopulateModulePassManager(
PMB: &PassManagerBuilder,
PM: &PassManager<'_>,
);
pub fn LLVMRustPassManagerBuilderPopulateFunctionPassManager(
PMB: &PassManagerBuilder,
PM: &PassManager<'_>,
);
pub fn LLVMRustPassManagerBuilderPopulateLTOPassManager(
PMB: &PassManagerBuilder,
PM: &PassManager<'_>,
Internalize: Bool,
RunInliner: Bool,
);
pub fn LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
PMB: &PassManagerBuilder,
PM: &PassManager<'_>,
);
pub fn LLVMGetHostCPUFeatures() -> *mut c_char;
pub fn LLVMDisposeMessage(message: *mut c_char);
@ -2244,22 +2209,6 @@ extern "C" {
pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&ConstantInt>;
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>;
pub fn LLVMRustCreateAddressSanitizerFunctionPass(Recover: bool) -> &'static mut Pass;
pub fn LLVMRustCreateModuleAddressSanitizerPass(Recover: bool) -> &'static mut Pass;
pub fn LLVMRustCreateMemorySanitizerPass(
TrackOrigins: c_int,
Recover: bool,
) -> &'static mut Pass;
pub fn LLVMRustCreateThreadSanitizerPass() -> &'static mut Pass;
pub fn LLVMRustCreateHWAddressSanitizerPass(Recover: bool) -> &'static mut Pass;
pub fn LLVMRustAddPass(PM: &PassManager<'_>, Pass: &'static mut Pass);
pub fn LLVMRustAddLastExtensionPasses(
PMB: &PassManagerBuilder,
Passes: *const &'static mut Pass,
NumPasses: size_t,
);
pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool;
pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine);
@ -2293,29 +2242,11 @@ extern "C" {
SplitDwarfFile: *const c_char,
) -> Option<&'static mut TargetMachine>;
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
pub fn LLVMRustAddBuilderLibraryInfo<'a>(
PMB: &'a PassManagerBuilder,
M: &'a Module,
DisableSimplifyLibCalls: bool,
);
pub fn LLVMRustConfigurePassManagerBuilder(
PMB: &PassManagerBuilder,
OptLevel: CodeGenOptLevel,
MergeFunctions: bool,
SLPVectorize: bool,
LoopVectorize: bool,
PrepareForThinLTO: bool,
PGOGenPath: *const c_char,
PGOUsePath: *const c_char,
PGOSampleUsePath: *const c_char,
SizeLevel: c_int,
);
pub fn LLVMRustAddLibraryInfo<'a>(
PM: &PassManager<'a>,
M: &'a Module,
DisableSimplifyLibCalls: bool,
);
pub fn LLVMRustRunFunctionPassManager<'a>(PM: &PassManager<'a>, M: &'a Module);
pub fn LLVMRustWriteOutputFile<'a>(
T: &'a TargetMachine,
PM: &PassManager<'a>,
@ -2324,7 +2255,7 @@ extern "C" {
DwoOutput: *const c_char,
FileType: FileType,
) -> LLVMRustResult;
pub fn LLVMRustOptimizeWithNewPassManager<'a>(
pub fn LLVMRustOptimize<'a>(
M: &'a Module,
TM: &'a TargetMachine,
OptLevel: PassBuilderOptLevel,
@ -2362,7 +2293,6 @@ extern "C" {
pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
pub fn LLVMRustPrintPasses();
pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char);
pub fn LLVMRustAddAlwaysInlinePass(P: &PassManagerBuilder, AddLifetimes: bool);
pub fn LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t);
pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>;

View File

@ -1,7 +1,6 @@
use crate::back::write::create_informational_target_machine;
use crate::{llvm, llvm_util};
use crate::llvm;
use libc::c_int;
use libloading::Library;
use rustc_codegen_ssa::target_features::{
supported_target_features, tied_target_features, RUSTC_SPECIFIC_FEATURES,
};
@ -16,7 +15,6 @@ use rustc_target::spec::{MergeFunctions, PanicStrategy};
use smallvec::{smallvec, SmallVec};
use std::ffi::{CStr, CString};
use std::mem;
use std::path::Path;
use std::ptr;
use std::slice;
@ -120,22 +118,6 @@ unsafe fn configure_llvm(sess: &Session) {
llvm::LLVMInitializePasses();
// Use the legacy plugin registration if we don't use the new pass manager
if !should_use_new_llvm_pass_manager(
&sess.opts.unstable_opts.new_llvm_pass_manager,
&sess.target.arch,
) {
// Register LLVM plugins by loading them into the compiler process.
for plugin in &sess.opts.unstable_opts.llvm_plugins {
let lib = Library::new(plugin).unwrap_or_else(|e| bug!("couldn't load plugin: {}", e));
debug!("LLVM plugin loaded successfully {:?} ({})", lib, plugin);
// Intentionally leak the dynamic library. We can't ever unload it
// since the library can make things that will live arbitrarily long.
mem::forget(lib);
}
}
rustc_llvm::initialize_available_targets();
llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr());
@ -539,19 +521,3 @@ pub fn tune_cpu(sess: &Session) -> Option<&str> {
let name = sess.opts.unstable_opts.tune_cpu.as_ref()?;
Some(handle_native(name))
}
pub(crate) fn should_use_new_llvm_pass_manager(user_opt: &Option<bool>, target_arch: &str) -> bool {
// 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.
let min_version = if target_arch == "s390x" { 14 } else { 13 };
user_opt.unwrap_or_else(|| llvm_util::get_version() >= (min_version, 0, 0))
}

View File

@ -113,7 +113,6 @@ pub struct ModuleConfig {
pub vectorize_slp: bool,
pub merge_functions: bool,
pub inline_threshold: Option<u32>,
pub new_llvm_pass_manager: Option<bool>,
pub emit_lifetime_markers: bool,
pub llvm_plugins: Vec<String>,
}
@ -265,7 +264,6 @@ impl ModuleConfig {
},
inline_threshold: sess.opts.cg.inline_threshold,
new_llvm_pass_manager: sess.opts.unstable_opts.new_llvm_pass_manager,
emit_lifetime_markers: sess.emit_lifetime_markers(),
llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]),
}

View File

@ -758,7 +758,6 @@ fn test_unstable_options_tracking_hash() {
tracked!(mir_opt_level, Some(4));
tracked!(move_size_limit, Some(4096));
tracked!(mutable_noalias, Some(true));
tracked!(new_llvm_pass_manager, Some(true));
tracked!(no_generate_arange_section, true);
tracked!(no_link, true);
tracked!(no_unique_section_names, true);

View File

@ -31,13 +31,12 @@
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/Transforms/IPO/FunctionImport.h"
#if LLVM_VERSION_GE(15, 0)
#include "llvm/Transforms/IPO/Internalize.h"
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
#endif
#include "llvm/Transforms/Utils/AddDiscriminators.h"
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm/Transforms/Instrumentation.h"
@ -93,172 +92,6 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
timeTraceProfilerCleanup();
}
extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) {
#if LLVM_VERSION_LT(15, 0)
StringRef SR(PassName);
PassRegistry *PR = PassRegistry::getPassRegistry();
const PassInfo *PI = PR->getPassInfo(SR);
if (PI) {
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(
#if LLVM_VERSION_GE(14, 0)
MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel, /*EagerChecks=*/true}
#else
MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}
#endif
));
#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" 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" 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)
LLVMPassManagerBuilderPopulateLTOPassManager(PMB, PM, Internalize, RunInliner);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C"
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 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) {
#if LLVM_VERSION_LT(15, 0)
auto AddExtensionPasses = [Passes, NumPasses](
const PassManagerBuilder &Builder, PassManagerBase &PM) {
for (size_t I = 0; I < NumPasses; I++) {
PM.add(unwrap(Passes[I]));
}
};
// Add the passes to both of the pre-finalization extension points,
// so they are run for optimized and non-optimized builds.
unwrap(PMBR)->addExtension(PassManagerBuilder::EP_OptimizerLast,
AddExtensionPasses);
unwrap(PMBR)->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
AddExtensionPasses);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
#ifdef LLVM_COMPONENT_X86
#define SUBTARGET_X86 SUBTARGET(X86)
#else
@ -604,47 +437,6 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
delete unwrap(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,
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);
unwrap(PMBR)->EnablePGOInstrGen = true;
unwrap(PMBR)->PGOInstrGen = PGOGenPath;
} else if (PGOUsePath) {
assert(!PGOSampleUsePath);
unwrap(PMBR)->PGOInstrUse = PGOUsePath;
} 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`
// field of a PassManagerBuilder, we expose our own method of doing so.
extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR,
LLVMModuleRef M,
bool DisableSimplifyLibCalls) {
Triple TargetTriple(unwrap(M)->getTargetTriple());
TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
if (DisableSimplifyLibCalls)
TLI->disableAllFunctions();
unwrap(PMBR)->LibraryInfo = TLI;
}
// Unfortunately, the LLVM C API doesn't provide a way to create the
// TargetLibraryInfo pass, so we use this method to do so.
extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
@ -656,27 +448,6 @@ extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
}
// Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
// all the functions in a module, so we do that manually here. You'll find
// similar code in clang's BackendUtil.cpp file.
extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR,
LLVMModuleRef M) {
llvm::legacy::FunctionPassManager *P =
unwrap<llvm::legacy::FunctionPassManager>(PMR);
P->doInitialization();
// Upgrade all calls to old intrinsics first.
for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;)
UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;
++I)
if (!I->isDeclaration())
P->run(*I);
P->doFinalization();
}
extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
// Initializing the command-line options more than once is not allowed. So,
// check if they've already been initialized. (This could happen if we're
@ -820,7 +591,7 @@ struct LLVMRustSanitizerOptions {
};
extern "C" LLVMRustResult
LLVMRustOptimizeWithNewPassManager(
LLVMRustOptimize(
LLVMModuleRef ModuleRef,
LLVMTargetMachineRef TMRef,
LLVMRustPassBuilderOptLevel OptLevelRust,
@ -1241,15 +1012,8 @@ extern "C" void LLVMRustPrintPasses() {
PR->enumerateWith(&Listener);
}
extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR,
bool AddLifetimes) {
unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes);
}
extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
size_t Len) {
llvm::legacy::PassManager passes;
auto PreserveFunctions = [=](const GlobalValue &GV) {
for (size_t I = 0; I < Len; I++) {
if (GV.getName() == Symbols[I]) {
@ -1259,9 +1023,7 @@ extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
return false;
};
passes.add(llvm::createInternalizePass(PreserveFunctions));
passes.run(*unwrap(M));
internalizeModule(*unwrap(M), PreserveFunctions);
}
extern "C" void
@ -1610,11 +1372,6 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
raw_string_ostream OS(Ret->data);
{
if (is_thin) {
#if LLVM_VERSION_LT(15, 0)
legacy::PassManager PM;
PM.add(createWriteThinLTOBitcodePass(OS));
PM.run(*unwrap(M));
#else
PassBuilder PB;
LoopAnalysisManager LAM;
FunctionAnalysisManager FAM;
@ -1628,11 +1385,8 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
ModulePassManager MPM;
MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr));
MPM.run(*unwrap(M), MAM);
#endif
} else {
legacy::PassManager PM;
PM.add(createBitcodeWriterPass(OS));
PM.run(*unwrap(M));
WriteBitcodeToFile(*unwrap(M), OS);
}
}
}

View File

@ -12,7 +12,7 @@
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Pass.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/Support/Signals.h"
#include "llvm/ADT/Optional.h"
@ -1670,11 +1670,7 @@ LLVMRustModuleBufferCreate(LLVMModuleRef M) {
auto Ret = std::make_unique<LLVMRustModuleBuffer>();
{
raw_string_ostream OS(Ret->data);
{
legacy::PassManager PM;
PM.add(createBitcodeWriterPass(OS));
PM.run(*unwrap(M));
}
WriteBitcodeToFile(*unwrap(M), OS);
}
return Ret.release();
}

View File

@ -1409,8 +1409,6 @@ options! {
"the size at which the `large_assignments` lint starts to be emitted"),
mutable_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
"emit noalias metadata for mutable references (default: yes)"),
new_llvm_pass_manager: Option<bool> = (None, parse_opt_bool, [TRACKED],
"use new LLVM pass manager (default: no)"),
nll_facts: bool = (false, parse_bool, [UNTRACKED],
"dump facts from NLL analysis into side files (default: no)"),
nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED],

View File

@ -41,7 +41,7 @@ $ rustc -Zself-profile -Zself-profile-events=default,args
- `llvm`
- Adds tracing information about LLVM passes and codegeneration.
- Disabled by default because this only works when `-Znew-llvm-pass-manager` is enabled.
- Disabled by default because this significantly increases the trace file size.
## Event synonyms

View File

@ -82,7 +82,6 @@
-Z mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)
-Z move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted
-Z mutable-noalias=val -- emit noalias metadata for mutable references (default: yes)
-Z new-llvm-pass-manager=val -- use new LLVM pass manager (default: no)
-Z nll-facts=val -- dump facts from NLL analysis into side files (default: no)
-Z nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`)
-Z no-analysis=val -- parse and expand the source, but run no analysis

View File

@ -1,4 +1,4 @@
// build-fail
// compile-flags: -Cpasses=unknown-pass -Z new-llvm-pass-manager=yes
// compile-flags: -Cpasses=unknown-pass
fn main() {}

View File

@ -7,7 +7,7 @@
//
// no-prefer-dynamic
// revisions: opt0 opt1
// compile-flags: -Znew-llvm-pass-manager=yes -Zsanitizer=address -Clto=thin
// compile-flags: -Zsanitizer=address -Clto=thin
//[opt0]compile-flags: -Copt-level=0
//[opt1]compile-flags: -Copt-level=1
// run-fail