@@ -410,16 +410,17 @@ fn get_pgo_use_path(config: &ModuleConfig) -> Option<CString> {
410410
411411pub ( crate ) fn should_use_new_llvm_pass_manager ( config : & ModuleConfig ) -> bool {
412412 // The new pass manager is disabled by default.
413- config. new_llvm_pass_manager
413+ config. new_llvm_pass_manager . unwrap_or ( false )
414414}
415415
416416pub ( 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) ,
@@ -472,10 +472,15 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
472472 sanitizer_options. as_ref ( ) ,
473473 pgo_gen_path. as_ref ( ) . map_or ( std:: ptr:: null ( ) , |s| s. as_ptr ( ) ) ,
474474 pgo_use_path. as_ref ( ) . map_or ( std:: ptr:: null ( ) , |s| s. as_ptr ( ) ) ,
475+ config. instrument_coverage ,
476+ config. instrument_gcov ,
475477 llvm_selfprofiler,
476478 selfprofile_before_pass_callback,
477479 selfprofile_after_pass_callback,
480+ extra_passes. as_ptr ( ) . cast ( ) ,
481+ extra_passes. len ( ) ,
478482 ) ;
483+ result. into_result ( ) . map_err ( |( ) | llvm_err ( diag_handler, "failed to run LLVM passes" ) )
479484}
480485
481486// Unsafe due to LLVM calls.
@@ -484,7 +489,7 @@ pub(crate) unsafe fn optimize(
484489 diag_handler : & Handler ,
485490 module : & ModuleCodegen < ModuleLlvm > ,
486491 config : & ModuleConfig ,
487- ) {
492+ ) -> Result < ( ) , FatalError > {
488493 let _timer = cgcx. prof . generic_activity_with_arg ( "LLVM_module_optimize" , & module. name [ ..] ) ;
489494
490495 let llmod = module. module_llvm . llmod ( ) ;
@@ -509,8 +514,14 @@ pub(crate) unsafe fn optimize(
509514 _ if cgcx. opts . cg . linker_plugin_lto . enabled ( ) => llvm:: OptStage :: PreLinkThinLTO ,
510515 _ => llvm:: OptStage :: PreLinkNoLTO ,
511516 } ;
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+ ) ;
514525 }
515526
516527 if cgcx. prof . llvm_recording_enabled ( ) {
@@ -545,15 +556,6 @@ pub(crate) unsafe fn optimize(
545556 llvm:: LLVMRustAddPass ( fpm, find_pass ( "lint" ) . unwrap ( ) ) ;
546557 continue ;
547558 }
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- }
557559
558560 if let Some ( pass) = find_pass ( pass_name) {
559561 extra_passes. push ( pass) ;
@@ -566,6 +568,18 @@ pub(crate) unsafe fn optimize(
566568 }
567569 }
568570
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+
569583 add_sanitizer_passes ( config, & mut extra_passes) ;
570584
571585 // Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need
@@ -642,6 +656,7 @@ pub(crate) unsafe fn optimize(
642656 llvm:: LLVMDisposePassManager ( fpm) ;
643657 llvm:: LLVMDisposePassManager ( mpm) ;
644658 }
659+ Ok ( ( ) )
645660}
646661
647662unsafe fn add_sanitizer_passes ( config : & ModuleConfig , passes : & mut Vec < & ' static mut llvm:: Pass > ) {
0 commit comments