@@ -410,16 +410,17 @@ fn get_pgo_use_path(config: &ModuleConfig) -> Option<CString> {
410
410
411
411
pub ( crate ) fn should_use_new_llvm_pass_manager ( config : & ModuleConfig ) -> bool {
412
412
// The new pass manager is disabled by default.
413
- config. new_llvm_pass_manager
413
+ config. new_llvm_pass_manager . unwrap_or ( false )
414
414
}
415
415
416
416
pub ( crate ) unsafe fn optimize_with_new_llvm_pass_manager (
417
417
cgcx : & CodegenContext < LlvmCodegenBackend > ,
418
+ diag_handler : & Handler ,
418
419
module : & ModuleCodegen < ModuleLlvm > ,
419
420
config : & ModuleConfig ,
420
421
opt_level : config:: OptLevel ,
421
422
opt_stage : llvm:: OptStage ,
422
- ) {
423
+ ) -> Result < ( ) , FatalError > {
423
424
let unroll_loops =
424
425
opt_level != config:: OptLevel :: Size && opt_level != config:: OptLevel :: SizeMin ;
425
426
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(
449
450
std:: ptr:: null_mut ( )
450
451
} ;
451
452
453
+ let extra_passes = config. passes . join ( "," ) ;
454
+
452
455
// FIXME: NewPM doesn't provide a facility to pass custom InlineParams.
453
456
// We would have to add upstream support for this first, before we can support
454
457
// 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 (
459
459
module. module_llvm . llmod ( ) ,
460
460
& * module. module_llvm . tm ,
461
461
to_pass_builder_opt_level ( opt_level) ,
@@ -472,10 +472,15 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
472
472
sanitizer_options. as_ref ( ) ,
473
473
pgo_gen_path. as_ref ( ) . map_or ( std:: ptr:: null ( ) , |s| s. as_ptr ( ) ) ,
474
474
pgo_use_path. as_ref ( ) . map_or ( std:: ptr:: null ( ) , |s| s. as_ptr ( ) ) ,
475
+ config. instrument_coverage ,
476
+ config. instrument_gcov ,
475
477
llvm_selfprofiler,
476
478
selfprofile_before_pass_callback,
477
479
selfprofile_after_pass_callback,
480
+ extra_passes. as_ptr ( ) . cast ( ) ,
481
+ extra_passes. len ( ) ,
478
482
) ;
483
+ result. into_result ( ) . map_err ( |( ) | llvm_err ( diag_handler, "failed to run LLVM passes" ) )
479
484
}
480
485
481
486
// Unsafe due to LLVM calls.
@@ -484,7 +489,7 @@ pub(crate) unsafe fn optimize(
484
489
diag_handler : & Handler ,
485
490
module : & ModuleCodegen < ModuleLlvm > ,
486
491
config : & ModuleConfig ,
487
- ) {
492
+ ) -> Result < ( ) , FatalError > {
488
493
let _timer = cgcx. prof . generic_activity_with_arg ( "LLVM_module_optimize" , & module. name [ ..] ) ;
489
494
490
495
let llmod = module. module_llvm . llmod ( ) ;
@@ -509,8 +514,14 @@ pub(crate) unsafe fn optimize(
509
514
_ if cgcx. opts . cg . linker_plugin_lto . enabled ( ) => llvm:: OptStage :: PreLinkThinLTO ,
510
515
_ => llvm:: OptStage :: PreLinkNoLTO ,
511
516
} ;
512
- optimize_with_new_llvm_pass_manager ( cgcx, module, config, opt_level, opt_stage) ;
513
- 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
+ ) ;
514
525
}
515
526
516
527
if cgcx. prof . llvm_recording_enabled ( ) {
@@ -545,15 +556,6 @@ pub(crate) unsafe fn optimize(
545
556
llvm:: LLVMRustAddPass ( fpm, find_pass ( "lint" ) . unwrap ( ) ) ;
546
557
continue ;
547
558
}
548
- if pass_name == "insert-gcov-profiling" || pass_name == "instrprof" {
549
- // Instrumentation must be inserted before optimization,
550
- // otherwise LLVM may optimize some functions away which
551
- // breaks llvm-cov.
552
- //
553
- // This mirrors what Clang does in lib/CodeGen/BackendUtil.cpp.
554
- llvm:: LLVMRustAddPass ( mpm, find_pass ( pass_name) . unwrap ( ) ) ;
555
- continue ;
556
- }
557
559
558
560
if let Some ( pass) = find_pass ( pass_name) {
559
561
extra_passes. push ( pass) ;
@@ -566,6 +568,18 @@ pub(crate) unsafe fn optimize(
566
568
}
567
569
}
568
570
571
+ // Instrumentation must be inserted before optimization,
572
+ // otherwise LLVM may optimize some functions away which
573
+ // breaks llvm-cov.
574
+ //
575
+ // This mirrors what Clang does in lib/CodeGen/BackendUtil.cpp.
576
+ if config. instrument_gcov {
577
+ llvm:: LLVMRustAddPass ( mpm, find_pass ( "insert-gcov-profiling" ) . unwrap ( ) ) ;
578
+ }
579
+ if config. instrument_coverage {
580
+ llvm:: LLVMRustAddPass ( mpm, find_pass ( "instrprof" ) . unwrap ( ) ) ;
581
+ }
582
+
569
583
add_sanitizer_passes ( config, & mut extra_passes) ;
570
584
571
585
// Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need
@@ -642,6 +656,7 @@ pub(crate) unsafe fn optimize(
642
656
llvm:: LLVMDisposePassManager ( fpm) ;
643
657
llvm:: LLVMDisposePassManager ( mpm) ;
644
658
}
659
+ Ok ( ( ) )
645
660
}
646
661
647
662
unsafe fn add_sanitizer_passes ( config : & ModuleConfig , passes : & mut Vec < & ' static mut llvm:: Pass > ) {
0 commit comments