@@ -249,7 +249,7 @@ pub fn create_target_machine(sess: &Session) -> TargetMachineRef {
249
249
250
250
/// Module-specific configuration for `optimize_and_codegen`.
251
251
#[ derive( Clone ) ]
252
- struct ModuleConfig {
252
+ pub struct ModuleConfig {
253
253
/// LLVM TargetMachine to use for codegen.
254
254
tm : TargetMachineRef ,
255
255
/// Names of additional optimization passes to run.
@@ -444,72 +444,72 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
444
444
llvm:: LLVMWriteBitcodeToFile ( llmod, out. as_ptr ( ) ) ;
445
445
}
446
446
447
- match config. opt_level {
448
- Some ( opt_level) => {
449
- // Create the two optimizing pass managers. These mirror what clang
450
- // does, and are by populated by LLVM's default PassManagerBuilder.
451
- // Each manager has a different set of passes, but they also share
452
- // some common passes.
453
- let fpm = llvm:: LLVMCreateFunctionPassManagerForModule ( llmod) ;
454
- let mpm = llvm:: LLVMCreatePassManager ( ) ;
455
-
456
- // If we're verifying or linting, add them to the function pass
457
- // manager.
458
- let addpass = |pass : & str | {
459
- let pass = CString :: new ( pass) . unwrap ( ) ;
460
- llvm:: LLVMRustAddPass ( fpm, pass. as_ptr ( ) )
461
- } ;
447
+ if config. opt_level . is_some ( ) {
448
+ // Create the two optimizing pass managers. These mirror what clang
449
+ // does, and are by populated by LLVM's default PassManagerBuilder.
450
+ // Each manager has a different set of passes, but they also share
451
+ // some common passes.
452
+ let fpm = llvm:: LLVMCreateFunctionPassManagerForModule ( llmod) ;
453
+ let mpm = llvm:: LLVMCreatePassManager ( ) ;
454
+
455
+ // If we're verifying or linting, add them to the function pass
456
+ // manager.
457
+ let addpass = |pass : & str | {
458
+ let pass = CString :: new ( pass) . unwrap ( ) ;
459
+ llvm:: LLVMRustAddPass ( fpm, pass. as_ptr ( ) )
460
+ } ;
462
461
463
- if !config. no_verify { assert ! ( addpass( "verify" ) ) ; }
464
- if !config. no_prepopulate_passes {
465
- llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
466
- llvm:: LLVMRustAddAnalysisPasses ( tm, mpm, llmod) ;
467
- populate_llvm_passes ( fpm, mpm, llmod, opt_level, & config) ;
468
- }
462
+ if !config. no_verify { assert ! ( addpass( "verify" ) ) ; }
463
+ if !config. no_prepopulate_passes {
464
+ llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
465
+ llvm:: LLVMRustAddAnalysisPasses ( tm, mpm, llmod) ;
466
+ with_llvm_pmb ( llmod, & config, & mut |b| {
467
+ llvm:: LLVMPassManagerBuilderPopulateFunctionPassManager ( b, fpm) ;
468
+ llvm:: LLVMPassManagerBuilderPopulateModulePassManager ( b, mpm) ;
469
+ } )
470
+ }
469
471
470
- for pass in & config. passes {
471
- if !addpass ( pass) {
472
- cgcx. handler . warn ( & format ! ( "unknown pass `{}`, ignoring" ,
473
- pass) ) ;
474
- }
472
+ for pass in & config. passes {
473
+ if !addpass ( pass) {
474
+ cgcx. handler . warn ( & format ! ( "unknown pass `{}`, ignoring" ,
475
+ pass) ) ;
475
476
}
477
+ }
476
478
477
- for pass in & cgcx. plugin_passes {
478
- if !addpass ( pass) {
479
- cgcx. handler . err ( & format ! ( "a plugin asked for LLVM pass \
480
- `{}` but LLVM does not \
481
- recognize it", pass) ) ;
482
- }
479
+ for pass in & cgcx. plugin_passes {
480
+ if !addpass ( pass) {
481
+ cgcx. handler . err ( & format ! ( "a plugin asked for LLVM pass \
482
+ `{}` but LLVM does not \
483
+ recognize it", pass) ) ;
483
484
}
485
+ }
484
486
485
- cgcx. handler . abort_if_errors ( ) ;
487
+ cgcx. handler . abort_if_errors ( ) ;
486
488
487
- // Finally, run the actual optimization passes
488
- time ( config. time_passes , "llvm function passes" , ( ) , |( ) |
489
- llvm:: LLVMRustRunFunctionPassManager ( fpm, llmod) ) ;
490
- time ( config. time_passes , "llvm module passes" , ( ) , |( ) |
491
- llvm:: LLVMRunPassManager ( mpm, llmod) ) ;
489
+ // Finally, run the actual optimization passes
490
+ time ( config. time_passes , "llvm function passes" , ( ) , |( ) |
491
+ llvm:: LLVMRustRunFunctionPassManager ( fpm, llmod) ) ;
492
+ time ( config. time_passes , "llvm module passes" , ( ) , |( ) |
493
+ llvm:: LLVMRunPassManager ( mpm, llmod) ) ;
492
494
493
- // Deallocate managers that we're now done with
494
- llvm:: LLVMDisposePassManager ( fpm) ;
495
- llvm:: LLVMDisposePassManager ( mpm) ;
495
+ // Deallocate managers that we're now done with
496
+ llvm:: LLVMDisposePassManager ( fpm) ;
497
+ llvm:: LLVMDisposePassManager ( mpm) ;
496
498
497
- match cgcx. lto_ctxt {
498
- Some ( ( sess, reachable) ) if sess. lto ( ) => {
499
- time ( sess. time_passes ( ) , "all lto passes" , ( ) , |( ) |
500
- lto:: run ( sess, llmod, tm, reachable) ) ;
499
+ match cgcx. lto_ctxt {
500
+ Some ( ( sess, reachable) ) if sess. lto ( ) => {
501
+ time ( sess. time_passes ( ) , "all lto passes" , ( ) , |( ) |
502
+ lto:: run ( sess, llmod, tm, reachable, & config ) ) ;
501
503
502
- if config. emit_lto_bc {
503
- let name = format ! ( "{}.lto.bc" , name_extra) ;
504
- let out = output_names. with_extension ( & name) ;
505
- let out = path2cstr ( & out) ;
506
- llvm:: LLVMWriteBitcodeToFile ( llmod, out. as_ptr ( ) ) ;
507
- }
508
- } ,
509
- _ => { } ,
510
- }
511
- } ,
512
- None => { } ,
504
+ if config. emit_lto_bc {
505
+ let name = format ! ( "{}.lto.bc" , name_extra) ;
506
+ let out = output_names. with_extension ( & name) ;
507
+ let out = path2cstr ( & out) ;
508
+ llvm:: LLVMWriteBitcodeToFile ( llmod, out. as_ptr ( ) ) ;
509
+ }
510
+ } ,
511
+ _ => { } ,
512
+ }
513
513
}
514
514
515
515
// A codegen-specific pass manager is used to generate object
@@ -1001,15 +1001,14 @@ pub unsafe fn configure_llvm(sess: &Session) {
1001
1001
llvm_args. as_ptr ( ) ) ;
1002
1002
}
1003
1003
1004
- unsafe fn populate_llvm_passes ( fpm : llvm:: PassManagerRef ,
1005
- mpm : llvm:: PassManagerRef ,
1006
- llmod : ModuleRef ,
1007
- opt : llvm:: CodeGenOptLevel ,
1008
- config : & ModuleConfig ) {
1004
+ pub unsafe fn with_llvm_pmb ( llmod : ModuleRef ,
1005
+ config : & ModuleConfig ,
1006
+ f : & mut FnMut ( llvm:: PassManagerBuilderRef ) ) {
1009
1007
// Create the PassManagerBuilder for LLVM. We configure it with
1010
1008
// reasonable defaults and prepare it to actually populate the pass
1011
1009
// manager.
1012
1010
let builder = llvm:: LLVMPassManagerBuilderCreate ( ) ;
1011
+ let opt = config. opt_level . unwrap_or ( llvm:: CodeGenLevelNone ) ;
1013
1012
1014
1013
llvm:: LLVMRustConfigurePassManagerBuilder ( builder, opt,
1015
1014
config. merge_functions ,
@@ -1037,8 +1036,6 @@ unsafe fn populate_llvm_passes(fpm: llvm::PassManagerRef,
1037
1036
}
1038
1037
}
1039
1038
1040
- // Use the builder to populate the function/module pass managers.
1041
- llvm:: LLVMPassManagerBuilderPopulateFunctionPassManager ( builder, fpm) ;
1042
- llvm:: LLVMPassManagerBuilderPopulateModulePassManager ( builder, mpm) ;
1039
+ f ( builder) ;
1043
1040
llvm:: LLVMPassManagerBuilderDispose ( builder) ;
1044
1041
}
0 commit comments