Remove support for LLVM's legacy pass manager
This commit is contained in:
parent
a37499ae66
commit
2860f77a0d
8 changed files with 23 additions and 653 deletions
|
@ -3263,7 +3263,6 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cstr",
|
"cstr",
|
||||||
"libc",
|
"libc",
|
||||||
"libloading",
|
|
||||||
"measureme",
|
"measureme",
|
||||||
"object 0.29.0",
|
"object 0.29.0",
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
|
|
|
@ -11,7 +11,6 @@ doctest = false
|
||||||
bitflags = "1.0"
|
bitflags = "1.0"
|
||||||
cstr = "0.2"
|
cstr = "0.2"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
libloading = "0.7.1"
|
|
||||||
measureme = "10.0.0"
|
measureme = "10.0.0"
|
||||||
object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "archive", "coff", "elf", "macho", "pe"] }
|
object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "archive", "coff", "elf", "macho", "pe"] }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use crate::back::write::{
|
use crate::back::write::{self, save_temp_bitcode, DiagnosticHandlers};
|
||||||
self, save_temp_bitcode, to_llvm_opt_settings, with_llvm_pmb, DiagnosticHandlers,
|
use crate::llvm::{self, build_string};
|
||||||
};
|
use crate::{LlvmCodegenBackend, ModuleLlvm};
|
||||||
use crate::llvm::{self, build_string, False, True};
|
|
||||||
use crate::{llvm_util, LlvmCodegenBackend, ModuleLlvm};
|
|
||||||
use object::read::archive::ArchiveFile;
|
use object::read::archive::ArchiveFile;
|
||||||
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
|
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
|
||||||
use rustc_codegen_ssa::back::symbol_export;
|
use rustc_codegen_ssa::back::symbol_export;
|
||||||
|
@ -597,61 +595,9 @@ pub(crate) fn run_pass_manager(
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if llvm_util::should_use_new_llvm_pass_manager(
|
let opt_stage = if thin { llvm::OptStage::ThinLTO } else { llvm::OptStage::FatLTO };
|
||||||
&config.new_llvm_pass_manager,
|
let opt_level = config.opt_level.unwrap_or(config::OptLevel::No);
|
||||||
&cgcx.target_arch,
|
write::optimize(cgcx, diag_handler, module, config, opt_level, opt_stage)?;
|
||||||
) {
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
debug!("lto done");
|
debug!("lto done");
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -21,7 +21,6 @@ use rustc_data_structures::profiling::SelfProfilerRef;
|
||||||
use rustc_data_structures::small_c_str::SmallCStr;
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc_errors::{FatalError, Handler, Level};
|
use rustc_errors::{FatalError, Handler, Level};
|
||||||
use rustc_fs_util::{link_or_copy, path_to_c_string};
|
use rustc_fs_util::{link_or_copy, path_to_c_string};
|
||||||
use rustc_middle::bug;
|
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath};
|
use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath};
|
||||||
use rustc_session::Session;
|
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 optimize(
|
||||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||||
diag_handler: &Handler,
|
diag_handler: &Handler,
|
||||||
module: &ModuleCodegen<ModuleLlvm>,
|
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.
|
// 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
|
// We would have to add upstream support for this first, before we can support
|
||||||
// config.inline_threshold and our more aggressive default thresholds.
|
// config.inline_threshold and our more aggressive default thresholds.
|
||||||
let result = llvm::LLVMRustOptimizeWithNewPassManager(
|
let result = llvm::LLVMRustOptimize(
|
||||||
module.module_llvm.llmod(),
|
module.module_llvm.llmod(),
|
||||||
&*module.module_llvm.tm,
|
&*module.module_llvm.tm,
|
||||||
to_pass_builder_opt_level(opt_level),
|
to_pass_builder_opt_level(opt_level),
|
||||||
|
@ -499,7 +498,7 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsafe due to LLVM calls.
|
// Unsafe due to LLVM calls.
|
||||||
pub(crate) unsafe fn optimize(
|
pub(crate) unsafe fn maybe_optimize(
|
||||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||||
diag_handler: &Handler,
|
diag_handler: &Handler,
|
||||||
module: &ModuleCodegen<ModuleLlvm>,
|
module: &ModuleCodegen<ModuleLlvm>,
|
||||||
|
@ -509,16 +508,13 @@ pub(crate) unsafe fn optimize(
|
||||||
|
|
||||||
let llmod = module.module_llvm.llmod();
|
let llmod = module.module_llvm.llmod();
|
||||||
let llcx = &*module.module_llvm.llcx;
|
let llcx = &*module.module_llvm.llcx;
|
||||||
let tm = &*module.module_llvm.tm;
|
|
||||||
let _handlers = DiagnosticHandlers::new(cgcx, diag_handler, llcx);
|
let _handlers = DiagnosticHandlers::new(cgcx, diag_handler, llcx);
|
||||||
|
|
||||||
let module_name = module.name.clone();
|
let module_name = module.name.clone();
|
||||||
let module_name = Some(&module_name[..]);
|
let module_name = Some(&module_name[..]);
|
||||||
|
|
||||||
if let Some(false) = config.new_llvm_pass_manager && llvm_util::get_version() >= (15, 0, 0) {
|
if let Some(false) = config.new_llvm_pass_manager {
|
||||||
diag_handler.warn(
|
diag_handler.warn("ignoring `-Z new-llvm-pass-manager=no`, which is no longer supported");
|
||||||
"ignoring `-Z new-llvm-pass-manager=no`, which is no longer supported with LLVM 15",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.emit_no_opt_bc {
|
if config.emit_no_opt_bc {
|
||||||
|
@ -528,184 +524,17 @@ pub(crate) unsafe fn optimize(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(opt_level) = config.opt_level {
|
if let Some(opt_level) = config.opt_level {
|
||||||
if llvm_util::should_use_new_llvm_pass_manager(
|
let opt_stage = match cgcx.lto {
|
||||||
&config.new_llvm_pass_manager,
|
Lto::Fat => llvm::OptStage::PreLinkFatLTO,
|
||||||
&cgcx.target_arch,
|
Lto::Thin | Lto::ThinLocal => llvm::OptStage::PreLinkThinLTO,
|
||||||
) {
|
_ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
|
||||||
let opt_stage = match cgcx.lto {
|
_ => llvm::OptStage::PreLinkNoLTO,
|
||||||
Lto::Fat => llvm::OptStage::PreLinkFatLTO,
|
};
|
||||||
Lto::Thin | Lto::ThinLocal => llvm::OptStage::PreLinkThinLTO,
|
return optimize(cgcx, diag_handler, module, config, opt_level, opt_stage);
|
||||||
_ 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);
|
|
||||||
}
|
}
|
||||||
Ok(())
|
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(
|
pub(crate) fn link(
|
||||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||||
diag_handler: &Handler,
|
diag_handler: &Handler,
|
||||||
|
@ -1072,72 +901,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`.
|
// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
|
||||||
// This is required to satisfy `dllimport` references to static data in .rlibs
|
// 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
|
// when using MSVC linker. We do this only for data, as linker can fix up
|
||||||
|
|
|
@ -207,7 +207,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
||||||
module: &ModuleCodegen<Self::Module>,
|
module: &ModuleCodegen<Self::Module>,
|
||||||
config: &ModuleConfig,
|
config: &ModuleConfig,
|
||||||
) -> Result<(), FatalError> {
|
) -> Result<(), FatalError> {
|
||||||
back::write::optimize(cgcx, diag_handler, module, config)
|
back::write::maybe_optimize(cgcx, diag_handler, module, config)
|
||||||
}
|
}
|
||||||
fn optimize_fat(
|
fn optimize_fat(
|
||||||
cgcx: &CodegenContext<Self>,
|
cgcx: &CodegenContext<Self>,
|
||||||
|
|
|
@ -1810,18 +1810,9 @@ extern "C" {
|
||||||
/// Writes a module to the specified path. Returns 0 on success.
|
/// Writes a module to the specified path. Returns 0 on success.
|
||||||
pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;
|
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>;
|
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 LLVMInitializePasses();
|
||||||
|
|
||||||
pub fn LLVMTimeTraceProfilerInitialize();
|
pub fn LLVMTimeTraceProfilerInitialize();
|
||||||
|
@ -1832,32 +1823,6 @@ extern "C" {
|
||||||
|
|
||||||
pub fn LLVMAddAnalysisPasses<'a>(T: &'a TargetMachine, PM: &PassManager<'a>);
|
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 LLVMGetHostCPUFeatures() -> *mut c_char;
|
||||||
|
|
||||||
pub fn LLVMDisposeMessage(message: *mut c_char);
|
pub fn LLVMDisposeMessage(message: *mut c_char);
|
||||||
|
@ -2262,22 +2227,6 @@ extern "C" {
|
||||||
|
|
||||||
pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&ConstantInt>;
|
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 LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool;
|
||||||
|
|
||||||
pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine);
|
pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine);
|
||||||
|
@ -2311,29 +2260,11 @@ extern "C" {
|
||||||
SplitDwarfFile: *const c_char,
|
SplitDwarfFile: *const c_char,
|
||||||
) -> Option<&'static mut TargetMachine>;
|
) -> Option<&'static mut TargetMachine>;
|
||||||
pub fn LLVMRustDisposeTargetMachine(T: &'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>(
|
pub fn LLVMRustAddLibraryInfo<'a>(
|
||||||
PM: &PassManager<'a>,
|
PM: &PassManager<'a>,
|
||||||
M: &'a Module,
|
M: &'a Module,
|
||||||
DisableSimplifyLibCalls: bool,
|
DisableSimplifyLibCalls: bool,
|
||||||
);
|
);
|
||||||
pub fn LLVMRustRunFunctionPassManager<'a>(PM: &PassManager<'a>, M: &'a Module);
|
|
||||||
pub fn LLVMRustWriteOutputFile<'a>(
|
pub fn LLVMRustWriteOutputFile<'a>(
|
||||||
T: &'a TargetMachine,
|
T: &'a TargetMachine,
|
||||||
PM: &PassManager<'a>,
|
PM: &PassManager<'a>,
|
||||||
|
@ -2342,7 +2273,7 @@ extern "C" {
|
||||||
DwoOutput: *const c_char,
|
DwoOutput: *const c_char,
|
||||||
FileType: FileType,
|
FileType: FileType,
|
||||||
) -> LLVMRustResult;
|
) -> LLVMRustResult;
|
||||||
pub fn LLVMRustOptimizeWithNewPassManager<'a>(
|
pub fn LLVMRustOptimize<'a>(
|
||||||
M: &'a Module,
|
M: &'a Module,
|
||||||
TM: &'a TargetMachine,
|
TM: &'a TargetMachine,
|
||||||
OptLevel: PassBuilderOptLevel,
|
OptLevel: PassBuilderOptLevel,
|
||||||
|
@ -2380,7 +2311,6 @@ extern "C" {
|
||||||
pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
|
pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
|
||||||
pub fn LLVMRustPrintPasses();
|
pub fn LLVMRustPrintPasses();
|
||||||
pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char);
|
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 LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t);
|
||||||
|
|
||||||
pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>;
|
pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::back::write::create_informational_target_machine;
|
use crate::back::write::create_informational_target_machine;
|
||||||
use crate::{llvm, llvm_util};
|
use crate::llvm;
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
use libloading::Library;
|
|
||||||
use rustc_codegen_ssa::target_features::{
|
use rustc_codegen_ssa::target_features::{
|
||||||
supported_target_features, tied_target_features, RUSTC_SPECIFIC_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 smallvec::{smallvec, SmallVec};
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
|
|
||||||
use std::mem;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
@ -120,22 +118,6 @@ unsafe fn configure_llvm(sess: &Session) {
|
||||||
|
|
||||||
llvm::LLVMInitializePasses();
|
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();
|
rustc_llvm::initialize_available_targets();
|
||||||
|
|
||||||
llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr());
|
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()?;
|
let name = sess.opts.unstable_opts.tune_cpu.as_ref()?;
|
||||||
Some(handle_native(name))
|
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))
|
|
||||||
}
|
|
||||||
|
|
|
@ -93,172 +93,6 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
|
||||||
timeTraceProfilerCleanup();
|
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
|
#ifdef LLVM_COMPONENT_X86
|
||||||
#define SUBTARGET_X86 SUBTARGET(X86)
|
#define SUBTARGET_X86 SUBTARGET(X86)
|
||||||
#else
|
#else
|
||||||
|
@ -604,47 +438,6 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
|
||||||
delete unwrap(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
|
// Unfortunately, the LLVM C API doesn't provide a way to create the
|
||||||
// TargetLibraryInfo pass, so we use this method to do so.
|
// TargetLibraryInfo pass, so we use this method to do so.
|
||||||
extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
|
extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
|
||||||
|
@ -656,27 +449,6 @@ extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
|
||||||
unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
|
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) {
|
extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
|
||||||
// Initializing the command-line options more than once is not allowed. So,
|
// 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
|
// check if they've already been initialized. (This could happen if we're
|
||||||
|
@ -820,7 +592,7 @@ struct LLVMRustSanitizerOptions {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" LLVMRustResult
|
extern "C" LLVMRustResult
|
||||||
LLVMRustOptimizeWithNewPassManager(
|
LLVMRustOptimize(
|
||||||
LLVMModuleRef ModuleRef,
|
LLVMModuleRef ModuleRef,
|
||||||
LLVMTargetMachineRef TMRef,
|
LLVMTargetMachineRef TMRef,
|
||||||
LLVMRustPassBuilderOptLevel OptLevelRust,
|
LLVMRustPassBuilderOptLevel OptLevelRust,
|
||||||
|
@ -1241,11 +1013,6 @@ extern "C" void LLVMRustPrintPasses() {
|
||||||
PR->enumerateWith(&Listener);
|
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,
|
extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
|
||||||
size_t Len) {
|
size_t Len) {
|
||||||
llvm::legacy::PassManager passes;
|
llvm::legacy::PassManager passes;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue