mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Support -C passes in NewPM
And report an error if parsing the additional pass pipeline fails. Threading through the error accounts for most of the changes here.
This commit is contained in:
parent
5519cbfe33
commit
c2b15a6b64
@ -568,10 +568,11 @@ fn thin_lto(
|
||||
|
||||
pub(crate) fn run_pass_manager(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
diag_handler: &Handler,
|
||||
module: &ModuleCodegen<ModuleLlvm>,
|
||||
config: &ModuleConfig,
|
||||
thin: bool,
|
||||
) {
|
||||
) -> Result<(), FatalError> {
|
||||
let _timer = cgcx.prof.extra_verbose_generic_activity("LLVM_lto_optimize", &module.name[..]);
|
||||
|
||||
// Now we have one massive module inside of llmod. Time to run the
|
||||
@ -584,9 +585,16 @@ pub(crate) fn run_pass_manager(
|
||||
if write::should_use_new_llvm_pass_manager(config) {
|
||||
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, module, config, opt_level, opt_stage);
|
||||
write::optimize_with_new_llvm_pass_manager(
|
||||
cgcx,
|
||||
diag_handler,
|
||||
module,
|
||||
config,
|
||||
opt_level,
|
||||
opt_stage,
|
||||
)?;
|
||||
debug!("lto done");
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let pm = llvm::LLVMCreatePassManager();
|
||||
@ -628,6 +636,7 @@ pub(crate) fn run_pass_manager(
|
||||
llvm::LLVMDisposePassManager(pm);
|
||||
}
|
||||
debug!("lto done");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub struct ModuleBuffer(&'static mut llvm::ModuleBuffer);
|
||||
@ -850,7 +859,7 @@ pub unsafe fn optimize_thin_module(
|
||||
{
|
||||
info!("running thin lto passes over {}", module.name);
|
||||
let config = cgcx.config(module.kind);
|
||||
run_pass_manager(cgcx, &module, config, true);
|
||||
run_pass_manager(cgcx, &diag_handler, &module, config, true)?;
|
||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-pm");
|
||||
}
|
||||
}
|
||||
|
@ -415,11 +415,12 @@ pub(crate) fn should_use_new_llvm_pass_manager(config: &ModuleConfig) -> bool {
|
||||
|
||||
pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
diag_handler: &Handler,
|
||||
module: &ModuleCodegen<ModuleLlvm>,
|
||||
config: &ModuleConfig,
|
||||
opt_level: config::OptLevel,
|
||||
opt_stage: llvm::OptStage,
|
||||
) {
|
||||
) -> Result<(), FatalError> {
|
||||
let unroll_loops =
|
||||
opt_level != config::OptLevel::Size && opt_level != config::OptLevel::SizeMin;
|
||||
let using_thin_buffers = opt_stage == llvm::OptStage::PreLinkThinLTO || config.bitcode_needed();
|
||||
@ -449,13 +450,12 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
|
||||
std::ptr::null_mut()
|
||||
};
|
||||
|
||||
let extra_passes = config.passes.join(",");
|
||||
|
||||
// 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.
|
||||
// FIXME: NewPM uses an different and more explicit way to textually represent
|
||||
// pass pipelines. It would probably make sense to expose this, but it would
|
||||
// require a different format than the current -C passes.
|
||||
llvm::LLVMRustOptimizeWithNewPassManager(
|
||||
let result = llvm::LLVMRustOptimizeWithNewPassManager(
|
||||
module.module_llvm.llmod(),
|
||||
&*module.module_llvm.tm,
|
||||
to_pass_builder_opt_level(opt_level),
|
||||
@ -477,7 +477,10 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
|
||||
llvm_selfprofiler,
|
||||
selfprofile_before_pass_callback,
|
||||
selfprofile_after_pass_callback,
|
||||
extra_passes.as_ptr().cast(),
|
||||
extra_passes.len(),
|
||||
);
|
||||
result.into_result().map_err(|()| llvm_err(diag_handler, "failed to run LLVM passes"))
|
||||
}
|
||||
|
||||
// Unsafe due to LLVM calls.
|
||||
@ -486,7 +489,7 @@ pub(crate) unsafe fn optimize(
|
||||
diag_handler: &Handler,
|
||||
module: &ModuleCodegen<ModuleLlvm>,
|
||||
config: &ModuleConfig,
|
||||
) {
|
||||
) -> Result<(), FatalError> {
|
||||
let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &module.name[..]);
|
||||
|
||||
let llmod = module.module_llvm.llmod();
|
||||
@ -511,8 +514,14 @@ pub(crate) unsafe fn optimize(
|
||||
_ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
|
||||
_ => llvm::OptStage::PreLinkNoLTO,
|
||||
};
|
||||
optimize_with_new_llvm_pass_manager(cgcx, module, config, opt_level, opt_stage);
|
||||
return;
|
||||
return optimize_with_new_llvm_pass_manager(
|
||||
cgcx,
|
||||
diag_handler,
|
||||
module,
|
||||
config,
|
||||
opt_level,
|
||||
opt_stage,
|
||||
);
|
||||
}
|
||||
|
||||
if cgcx.prof.llvm_recording_enabled() {
|
||||
@ -647,6 +656,7 @@ pub(crate) unsafe fn optimize(
|
||||
llvm::LLVMDisposePassManager(fpm);
|
||||
llvm::LLVMDisposePassManager(mpm);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn add_sanitizer_passes(config: &ModuleConfig, passes: &mut Vec<&'static mut llvm::Pass>) {
|
||||
|
@ -162,7 +162,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
||||
module: &ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
) -> Result<(), FatalError> {
|
||||
Ok(back::write::optimize(cgcx, diag_handler, module, config))
|
||||
back::write::optimize(cgcx, diag_handler, module, config)
|
||||
}
|
||||
unsafe fn optimize_thin(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
@ -189,8 +189,9 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
||||
module: &ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
thin: bool,
|
||||
) {
|
||||
back::lto::run_pass_manager(cgcx, module, config, thin)
|
||||
) -> Result<(), FatalError> {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
back::lto::run_pass_manager(cgcx, &diag_handler, module, config, thin)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2208,7 +2208,9 @@ extern "C" {
|
||||
llvm_selfprofiler: *mut c_void,
|
||||
begin_callback: SelfProfileBeforePassCallback,
|
||||
end_callback: SelfProfileAfterPassCallback,
|
||||
);
|
||||
ExtraPasses: *const c_char,
|
||||
ExtraPassesLen: size_t,
|
||||
) -> LLVMRustResult;
|
||||
pub fn LLVMRustPrintModule(
|
||||
M: &'a Module,
|
||||
Output: *const c_char,
|
||||
|
@ -72,7 +72,7 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
|
||||
let module = module.take().unwrap();
|
||||
{
|
||||
let config = cgcx.config(module.kind);
|
||||
B::run_lto_pass_manager(cgcx, &module, config, false);
|
||||
B::run_lto_pass_manager(cgcx, &module, config, false)?;
|
||||
}
|
||||
Ok(module)
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
|
||||
llmod: &ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
thin: bool,
|
||||
);
|
||||
) -> Result<(), FatalError>;
|
||||
}
|
||||
|
||||
pub trait ThinBufferMethods: Send + Sync {
|
||||
|
@ -736,7 +736,7 @@ struct LLVMRustSanitizerOptions {
|
||||
bool SanitizeHWAddressRecover;
|
||||
};
|
||||
|
||||
extern "C" void
|
||||
extern "C" LLVMRustResult
|
||||
LLVMRustOptimizeWithNewPassManager(
|
||||
LLVMModuleRef ModuleRef,
|
||||
LLVMTargetMachineRef TMRef,
|
||||
@ -750,7 +750,8 @@ LLVMRustOptimizeWithNewPassManager(
|
||||
bool InstrumentCoverage, bool InstrumentGCOV,
|
||||
void* LlvmSelfProfiler,
|
||||
LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
|
||||
LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
|
||||
LLVMRustSelfProfileAfterPassCallback AfterPassCallback,
|
||||
const char *ExtraPasses, size_t ExtraPassesLen) {
|
||||
Module *TheModule = unwrap(ModuleRef);
|
||||
TargetMachine *TM = unwrap(TMRef);
|
||||
PassBuilder::OptimizationLevel OptLevel = fromRust(OptLevelRust);
|
||||
@ -1062,6 +1063,14 @@ LLVMRustOptimizeWithNewPassManager(
|
||||
}
|
||||
}
|
||||
|
||||
if (ExtraPassesLen) {
|
||||
if (auto Err = PB.parsePassPipeline(MPM, StringRef(ExtraPasses, ExtraPassesLen))) {
|
||||
std::string ErrMsg = toString(std::move(Err));
|
||||
LLVMRustSetLastError(ErrMsg.c_str());
|
||||
return LLVMRustResult::Failure;
|
||||
}
|
||||
}
|
||||
|
||||
if (NeedThinLTOBufferPasses) {
|
||||
MPM.addPass(CanonicalizeAliasesPass());
|
||||
MPM.addPass(NameAnonGlobalPass());
|
||||
@ -1072,6 +1081,7 @@ LLVMRustOptimizeWithNewPassManager(
|
||||
UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
|
||||
|
||||
MPM.run(*TheModule, MAM);
|
||||
return LLVMRustResult::Success;
|
||||
}
|
||||
|
||||
// Callback to demangle function name
|
||||
|
4
src/test/ui/invalid/invalid-llvm-passes.rs
Normal file
4
src/test/ui/invalid/invalid-llvm-passes.rs
Normal file
@ -0,0 +1,4 @@
|
||||
// build-fail
|
||||
// compile-flags: -Cpasses=unknown-pass -Z new-llvm-pass-manager=yes
|
||||
|
||||
fn main() {}
|
4
src/test/ui/invalid/invalid-llvm-passes.stderr
Normal file
4
src/test/ui/invalid/invalid-llvm-passes.stderr
Normal file
@ -0,0 +1,4 @@
|
||||
error: failed to run LLVM passes: unknown pass name 'unknown-pass'
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user