1010
1111use back:: lto;
1212use back:: link:: { get_cc_prog, remove} ;
13- use session:: config:: { OutputFilenames , NoDebugInfo , Passes , SomePasses , AllPasses } ;
13+ use session:: config:: { OutputFilenames , Passes , SomePasses , AllPasses } ;
1414use session:: Session ;
1515use session:: config;
1616use llvm;
@@ -188,10 +188,6 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
188188 let opt_level = get_llvm_opt_level ( sess. opts . optimize ) ;
189189 let use_softfp = sess. opts . cg . soft_float ;
190190
191- // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a parameter.
192- let no_fp_elim = ( sess. opts . debuginfo != NoDebugInfo ) ||
193- !sess. target . target . options . eliminate_frame_pointer ;
194-
195191 let any_library = sess. crate_types . borrow ( ) . iter ( ) . any ( |ty| {
196192 * ty != config:: CrateTypeExecutable
197193 } ) ;
@@ -237,7 +233,6 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
237233 opt_level,
238234 true /* EnableSegstk */ ,
239235 use_softfp,
240- no_fp_elim,
241236 !any_library && reloc_model == llvm:: RelocPIC ,
242237 ffunction_sections,
243238 fdata_sections,
@@ -279,6 +274,9 @@ struct ModuleConfig {
279274 no_prepopulate_passes : bool ,
280275 no_builtins : bool ,
281276 time_passes : bool ,
277+ vectorize_loop : bool ,
278+ vectorize_slp : bool ,
279+ merge_functions : bool ,
282280}
283281
284282unsafe impl Send for ModuleConfig { }
@@ -301,6 +299,9 @@ impl ModuleConfig {
301299 no_prepopulate_passes : false ,
302300 no_builtins : false ,
303301 time_passes : false ,
302+ vectorize_loop : false ,
303+ vectorize_slp : false ,
304+ merge_functions : false ,
304305 }
305306 }
306307
@@ -309,6 +310,18 @@ impl ModuleConfig {
309310 self . no_prepopulate_passes = sess. opts . cg . no_prepopulate_passes ;
310311 self . no_builtins = trans. no_builtins ;
311312 self . time_passes = sess. time_passes ( ) ;
313+
314+ // Copy what clang does by turning on loop vectorization at O2 and
315+ // slp vectorization at O3. Otherwise configure other optimization aspects
316+ // of this pass manager builder.
317+ self . vectorize_loop = !sess. opts . cg . no_vectorize_loops &&
318+ ( sess. opts . optimize == config:: Default ||
319+ sess. opts . optimize == config:: Aggressive ) ;
320+ self . vectorize_slp = !sess. opts . cg . no_vectorize_slp &&
321+ sess. opts . optimize == config:: Aggressive ;
322+
323+ self . merge_functions = sess. opts . optimize == config:: Default ||
324+ sess. opts . optimize == config:: Aggressive ;
312325 }
313326}
314327
@@ -448,27 +461,26 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
448461 let pass = CString :: new ( pass) . unwrap ( ) ;
449462 llvm:: LLVMRustAddPass ( fpm, pass. as_ptr ( ) )
450463 } ;
451- if !config. no_verify { assert ! ( addpass( "verify" ) ) ; }
452464
465+ if !config. no_verify { assert ! ( addpass( "verify" ) ) ; }
453466 if !config. no_prepopulate_passes {
454467 llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
455468 llvm:: LLVMRustAddAnalysisPasses ( tm, mpm, llmod) ;
456- populate_llvm_passes ( fpm, mpm, llmod, opt_level,
457- config. no_builtins ) ;
469+ populate_llvm_passes ( fpm, mpm, llmod, opt_level, & config) ;
458470 }
459471
460472 for pass in & config. passes {
461- let pass = CString :: new ( pass. clone ( ) ) . unwrap ( ) ;
462- if !llvm :: LLVMRustAddPass ( mpm , pass. as_ptr ( ) ) {
463- cgcx . handler . warn ( & format ! ( "unknown pass {:?}, ignoring" , pass) ) ;
473+ if ! addpass ( pass) {
474+ cgcx . handler . warn ( & format ! ( "unknown pass `{}`, ignoring" ,
475+ pass) ) ;
464476 }
465477 }
466478
467479 for pass in & cgcx. plugin_passes {
468- let pass = CString :: new ( pass. clone ( ) ) . unwrap ( ) ;
469- if !llvm :: LLVMRustAddPass ( mpm , pass. as_ptr ( ) ) {
470- cgcx . handler . err ( & format ! ( "a plugin asked for LLVM pass {:?} but LLVM \
471- does not recognize it", pass) ) ;
480+ if ! addpass ( pass) {
481+ cgcx . handler . err ( & format ! ( "a plugin asked for LLVM pass \
482+ `{}` but LLVM does not \
483+ recognize it", pass) ) ;
472484 }
473485 }
474486
@@ -520,7 +532,6 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
520532 llvm:: LLVMRustAddAnalysisPasses ( tm, cpm, llmod) ;
521533 llvm:: LLVMRustAddLibraryInfo ( cpm, llmod, no_builtins) ;
522534 f ( cpm) ;
523- llvm:: LLVMDisposePassManager ( cpm) ;
524535 }
525536
526537 if config. emit_bc {
@@ -537,13 +548,15 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
537548 let out = path2cstr ( & out) ;
538549 with_codegen ( tm, llmod, config. no_builtins , |cpm| {
539550 llvm:: LLVMRustPrintModule ( cpm, llmod, out. as_ptr ( ) ) ;
551+ llvm:: LLVMDisposePassManager ( cpm) ;
540552 } )
541553 }
542554
543555 if config. emit_asm {
544556 let path = output_names. with_extension ( & format ! ( "{}.s" , name_extra) ) ;
545557 with_codegen ( tm, llmod, config. no_builtins , |cpm| {
546- write_output_file ( cgcx. handler , tm, cpm, llmod, & path, llvm:: AssemblyFileType ) ;
558+ write_output_file ( cgcx. handler , tm, cpm, llmod, & path,
559+ llvm:: AssemblyFileType ) ;
547560 } ) ;
548561 }
549562
@@ -1008,25 +1021,16 @@ unsafe fn configure_llvm(sess: &Session) {
10081021 use std:: sync:: Once ;
10091022 static INIT : Once = Once :: new ( ) ;
10101023
1011- // Copy what clang does by turning on loop vectorization at O2 and
1012- // slp vectorization at O3
1013- let vectorize_loop = !sess. opts . cg . no_vectorize_loops &&
1014- ( sess. opts . optimize == config:: Default ||
1015- sess. opts . optimize == config:: Aggressive ) ;
1016- let vectorize_slp = !sess. opts . cg . no_vectorize_slp &&
1017- sess. opts . optimize == config:: Aggressive ;
1018-
10191024 let mut llvm_c_strs = Vec :: new ( ) ;
10201025 let mut llvm_args = Vec :: new ( ) ;
1026+
10211027 {
10221028 let mut add = |arg : & str | {
10231029 let s = CString :: new ( arg) . unwrap ( ) ;
10241030 llvm_args. push ( s. as_ptr ( ) ) ;
10251031 llvm_c_strs. push ( s) ;
10261032 } ;
10271033 add ( "rustc" ) ; // fake program name
1028- if vectorize_loop { add ( "-vectorize-loops" ) ; }
1029- if vectorize_slp { add ( "-vectorize-slp" ) ; }
10301034 if sess. time_llvm_passes ( ) { add ( "-time-passes" ) ; }
10311035 if sess. print_llvm_passes ( ) { add ( "-debug-pass=Structure" ) ; }
10321036
@@ -1084,41 +1088,40 @@ unsafe fn populate_llvm_passes(fpm: llvm::PassManagerRef,
10841088 mpm : llvm:: PassManagerRef ,
10851089 llmod : ModuleRef ,
10861090 opt : llvm:: CodeGenOptLevel ,
1087- no_builtins : bool ) {
1091+ config : & ModuleConfig ) {
10881092 // Create the PassManagerBuilder for LLVM. We configure it with
10891093 // reasonable defaults and prepare it to actually populate the pass
10901094 // manager.
10911095 let builder = llvm:: LLVMPassManagerBuilderCreate ( ) ;
1096+
1097+ llvm:: LLVMRustConfigurePassManagerBuilder ( builder, opt,
1098+ config. merge_functions ,
1099+ config. vectorize_slp ,
1100+ config. vectorize_loop ) ;
1101+
1102+ llvm:: LLVMRustAddBuilderLibraryInfo ( builder, llmod, config. no_builtins ) ;
1103+
1104+ // Here we match what clang does (kinda). For O0 we only inline
1105+ // always-inline functions (but don't add lifetime intrinsics), at O1 we
1106+ // inline with lifetime intrinsics, and O2+ we add an inliner with a
1107+ // thresholds copied from clang.
10921108 match opt {
10931109 llvm:: CodeGenLevelNone => {
1094- // Don't add lifetime intrinsics at O0
10951110 llvm:: LLVMRustAddAlwaysInlinePass ( builder, false ) ;
10961111 }
10971112 llvm:: CodeGenLevelLess => {
10981113 llvm:: LLVMRustAddAlwaysInlinePass ( builder, true ) ;
10991114 }
1100- // numeric values copied from clang
11011115 llvm:: CodeGenLevelDefault => {
1102- llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder,
1103- 225 ) ;
1116+ llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder, 225 ) ;
11041117 }
11051118 llvm:: CodeGenLevelAggressive => {
1106- llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder,
1107- 275 ) ;
1119+ llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder, 275 ) ;
11081120 }
11091121 }
1110- llvm:: LLVMPassManagerBuilderSetOptLevel ( builder, opt as c_uint ) ;
1111- llvm:: LLVMRustAddBuilderLibraryInfo ( builder, llmod, no_builtins) ;
11121122
11131123 // Use the builder to populate the function/module pass managers.
11141124 llvm:: LLVMPassManagerBuilderPopulateFunctionPassManager ( builder, fpm) ;
11151125 llvm:: LLVMPassManagerBuilderPopulateModulePassManager ( builder, mpm) ;
11161126 llvm:: LLVMPassManagerBuilderDispose ( builder) ;
1117-
1118- match opt {
1119- llvm:: CodeGenLevelDefault | llvm:: CodeGenLevelAggressive => {
1120- llvm:: LLVMRustAddPass ( mpm, "mergefunc\0 " . as_ptr ( ) as * const _ ) ;
1121- }
1122- _ => { }
1123- } ;
11241127}
0 commit comments