Skip to content

Commit c2b15a6

Browse files
committed
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.
1 parent 5519cbf commit c2b15a6

File tree

9 files changed

+60
-20
lines changed

9 files changed

+60
-20
lines changed

compiler/rustc_codegen_llvm/src/back/lto.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -568,10 +568,11 @@ fn thin_lto(
568568

569569
pub(crate) fn run_pass_manager(
570570
cgcx: &CodegenContext<LlvmCodegenBackend>,
571+
diag_handler: &Handler,
571572
module: &ModuleCodegen<ModuleLlvm>,
572573
config: &ModuleConfig,
573574
thin: bool,
574-
) {
575+
) -> Result<(), FatalError> {
575576
let _timer = cgcx.prof.extra_verbose_generic_activity("LLVM_lto_optimize", &module.name[..]);
576577

577578
// Now we have one massive module inside of llmod. Time to run the
@@ -584,9 +585,16 @@ pub(crate) fn run_pass_manager(
584585
if write::should_use_new_llvm_pass_manager(config) {
585586
let opt_stage = if thin { llvm::OptStage::ThinLTO } else { llvm::OptStage::FatLTO };
586587
let opt_level = config.opt_level.unwrap_or(config::OptLevel::No);
587-
write::optimize_with_new_llvm_pass_manager(cgcx, module, config, opt_level, opt_stage);
588+
write::optimize_with_new_llvm_pass_manager(
589+
cgcx,
590+
diag_handler,
591+
module,
592+
config,
593+
opt_level,
594+
opt_stage,
595+
)?;
588596
debug!("lto done");
589-
return;
597+
return Ok(());
590598
}
591599

592600
let pm = llvm::LLVMCreatePassManager();
@@ -628,6 +636,7 @@ pub(crate) fn run_pass_manager(
628636
llvm::LLVMDisposePassManager(pm);
629637
}
630638
debug!("lto done");
639+
Ok(())
631640
}
632641

633642
pub struct ModuleBuffer(&'static mut llvm::ModuleBuffer);
@@ -850,7 +859,7 @@ pub unsafe fn optimize_thin_module(
850859
{
851860
info!("running thin lto passes over {}", module.name);
852861
let config = cgcx.config(module.kind);
853-
run_pass_manager(cgcx, &module, config, true);
862+
run_pass_manager(cgcx, &diag_handler, &module, config, true)?;
854863
save_temp_bitcode(cgcx, &module, "thin-lto-after-pm");
855864
}
856865
}

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -415,11 +415,12 @@ pub(crate) fn should_use_new_llvm_pass_manager(config: &ModuleConfig) -> bool {
415415

416416
pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
417417
cgcx: &CodegenContext<LlvmCodegenBackend>,
418+
diag_handler: &Handler,
418419
module: &ModuleCodegen<ModuleLlvm>,
419420
config: &ModuleConfig,
420421
opt_level: config::OptLevel,
421422
opt_stage: llvm::OptStage,
422-
) {
423+
) -> Result<(), FatalError> {
423424
let unroll_loops =
424425
opt_level != config::OptLevel::Size && opt_level != config::OptLevel::SizeMin;
425426
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(
449450
std::ptr::null_mut()
450451
};
451452

453+
let extra_passes = config.passes.join(",");
454+
452455
// FIXME: NewPM doesn't provide a facility to pass custom InlineParams.
453456
// We would have to add upstream support for this first, before we can support
454457
// config.inline_threshold and our more aggressive default thresholds.
455-
// FIXME: NewPM uses an different and more explicit way to textually represent
456-
// pass pipelines. It would probably make sense to expose this, but it would
457-
// require a different format than the current -C passes.
458-
llvm::LLVMRustOptimizeWithNewPassManager(
458+
let result = llvm::LLVMRustOptimizeWithNewPassManager(
459459
module.module_llvm.llmod(),
460460
&*module.module_llvm.tm,
461461
to_pass_builder_opt_level(opt_level),
@@ -477,7 +477,10 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
477477
llvm_selfprofiler,
478478
selfprofile_before_pass_callback,
479479
selfprofile_after_pass_callback,
480+
extra_passes.as_ptr().cast(),
481+
extra_passes.len(),
480482
);
483+
result.into_result().map_err(|()| llvm_err(diag_handler, "failed to run LLVM passes"))
481484
}
482485

483486
// Unsafe due to LLVM calls.
@@ -486,7 +489,7 @@ pub(crate) unsafe fn optimize(
486489
diag_handler: &Handler,
487490
module: &ModuleCodegen<ModuleLlvm>,
488491
config: &ModuleConfig,
489-
) {
492+
) -> Result<(), FatalError> {
490493
let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &module.name[..]);
491494

492495
let llmod = module.module_llvm.llmod();
@@ -511,8 +514,14 @@ pub(crate) unsafe fn optimize(
511514
_ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
512515
_ => llvm::OptStage::PreLinkNoLTO,
513516
};
514-
optimize_with_new_llvm_pass_manager(cgcx, module, config, opt_level, opt_stage);
515-
return;
517+
return optimize_with_new_llvm_pass_manager(
518+
cgcx,
519+
diag_handler,
520+
module,
521+
config,
522+
opt_level,
523+
opt_stage,
524+
);
516525
}
517526

518527
if cgcx.prof.llvm_recording_enabled() {
@@ -647,6 +656,7 @@ pub(crate) unsafe fn optimize(
647656
llvm::LLVMDisposePassManager(fpm);
648657
llvm::LLVMDisposePassManager(mpm);
649658
}
659+
Ok(())
650660
}
651661

652662
unsafe fn add_sanitizer_passes(config: &ModuleConfig, passes: &mut Vec<&'static mut llvm::Pass>) {

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
162162
module: &ModuleCodegen<Self::Module>,
163163
config: &ModuleConfig,
164164
) -> Result<(), FatalError> {
165-
Ok(back::write::optimize(cgcx, diag_handler, module, config))
165+
back::write::optimize(cgcx, diag_handler, module, config)
166166
}
167167
unsafe fn optimize_thin(
168168
cgcx: &CodegenContext<Self>,
@@ -189,8 +189,9 @@ impl WriteBackendMethods for LlvmCodegenBackend {
189189
module: &ModuleCodegen<Self::Module>,
190190
config: &ModuleConfig,
191191
thin: bool,
192-
) {
193-
back::lto::run_pass_manager(cgcx, module, config, thin)
192+
) -> Result<(), FatalError> {
193+
let diag_handler = cgcx.create_diag_handler();
194+
back::lto::run_pass_manager(cgcx, &diag_handler, module, config, thin)
194195
}
195196
}
196197

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2208,7 +2208,9 @@ extern "C" {
22082208
llvm_selfprofiler: *mut c_void,
22092209
begin_callback: SelfProfileBeforePassCallback,
22102210
end_callback: SelfProfileAfterPassCallback,
2211-
);
2211+
ExtraPasses: *const c_char,
2212+
ExtraPassesLen: size_t,
2213+
) -> LLVMRustResult;
22122214
pub fn LLVMRustPrintModule(
22132215
M: &'a Module,
22142216
Output: *const c_char,

compiler/rustc_codegen_ssa/src/back/lto.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
7272
let module = module.take().unwrap();
7373
{
7474
let config = cgcx.config(module.kind);
75-
B::run_lto_pass_manager(cgcx, &module, config, false);
75+
B::run_lto_pass_manager(cgcx, &module, config, false)?;
7676
}
7777
Ok(module)
7878
}

compiler/rustc_codegen_ssa/src/traits/write.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
5858
llmod: &ModuleCodegen<Self::Module>,
5959
config: &ModuleConfig,
6060
thin: bool,
61-
);
61+
) -> Result<(), FatalError>;
6262
}
6363

6464
pub trait ThinBufferMethods: Send + Sync {

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ struct LLVMRustSanitizerOptions {
736736
bool SanitizeHWAddressRecover;
737737
};
738738

739-
extern "C" void
739+
extern "C" LLVMRustResult
740740
LLVMRustOptimizeWithNewPassManager(
741741
LLVMModuleRef ModuleRef,
742742
LLVMTargetMachineRef TMRef,
@@ -750,7 +750,8 @@ LLVMRustOptimizeWithNewPassManager(
750750
bool InstrumentCoverage, bool InstrumentGCOV,
751751
void* LlvmSelfProfiler,
752752
LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
753-
LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
753+
LLVMRustSelfProfileAfterPassCallback AfterPassCallback,
754+
const char *ExtraPasses, size_t ExtraPassesLen) {
754755
Module *TheModule = unwrap(ModuleRef);
755756
TargetMachine *TM = unwrap(TMRef);
756757
PassBuilder::OptimizationLevel OptLevel = fromRust(OptLevelRust);
@@ -1062,6 +1063,14 @@ LLVMRustOptimizeWithNewPassManager(
10621063
}
10631064
}
10641065

1066+
if (ExtraPassesLen) {
1067+
if (auto Err = PB.parsePassPipeline(MPM, StringRef(ExtraPasses, ExtraPassesLen))) {
1068+
std::string ErrMsg = toString(std::move(Err));
1069+
LLVMRustSetLastError(ErrMsg.c_str());
1070+
return LLVMRustResult::Failure;
1071+
}
1072+
}
1073+
10651074
if (NeedThinLTOBufferPasses) {
10661075
MPM.addPass(CanonicalizeAliasesPass());
10671076
MPM.addPass(NameAnonGlobalPass());
@@ -1072,6 +1081,7 @@ LLVMRustOptimizeWithNewPassManager(
10721081
UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
10731082

10741083
MPM.run(*TheModule, MAM);
1084+
return LLVMRustResult::Success;
10751085
}
10761086

10771087
// Callback to demangle function name
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// build-fail
2+
// compile-flags: -Cpasses=unknown-pass -Z new-llvm-pass-manager=yes
3+
4+
fn main() {}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
error: failed to run LLVM passes: unknown pass name 'unknown-pass'
2+
3+
error: aborting due to previous error
4+

0 commit comments

Comments
 (0)