10
10
11
11
use back:: lto;
12
12
use back:: link:: { get_cc_prog, remove} ;
13
- use session:: config:: { OutputFilenames , NoDebugInfo , Passes , SomePasses , AllPasses } ;
13
+ use session:: config:: { OutputFilenames , Passes , SomePasses , AllPasses } ;
14
14
use session:: Session ;
15
15
use session:: config;
16
16
use llvm;
@@ -188,10 +188,6 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
188
188
let opt_level = get_llvm_opt_level ( sess. opts . optimize ) ;
189
189
let use_softfp = sess. opts . cg . soft_float ;
190
190
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
-
195
191
let any_library = sess. crate_types . borrow ( ) . iter ( ) . any ( |ty| {
196
192
* ty != config:: CrateTypeExecutable
197
193
} ) ;
@@ -237,7 +233,6 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
237
233
opt_level,
238
234
true /* EnableSegstk */ ,
239
235
use_softfp,
240
- no_fp_elim,
241
236
!any_library && reloc_model == llvm:: RelocPIC ,
242
237
ffunction_sections,
243
238
fdata_sections,
@@ -279,6 +274,9 @@ struct ModuleConfig {
279
274
no_prepopulate_passes : bool ,
280
275
no_builtins : bool ,
281
276
time_passes : bool ,
277
+ vectorize_loop : bool ,
278
+ vectorize_slp : bool ,
279
+ merge_functions : bool ,
282
280
}
283
281
284
282
unsafe impl Send for ModuleConfig { }
@@ -301,6 +299,9 @@ impl ModuleConfig {
301
299
no_prepopulate_passes : false ,
302
300
no_builtins : false ,
303
301
time_passes : false ,
302
+ vectorize_loop : false ,
303
+ vectorize_slp : false ,
304
+ merge_functions : false ,
304
305
}
305
306
}
306
307
@@ -309,6 +310,18 @@ impl ModuleConfig {
309
310
self . no_prepopulate_passes = sess. opts . cg . no_prepopulate_passes ;
310
311
self . no_builtins = trans. no_builtins ;
311
312
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 ;
312
325
}
313
326
}
314
327
@@ -448,27 +461,26 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
448
461
let pass = CString :: new ( pass) . unwrap ( ) ;
449
462
llvm:: LLVMRustAddPass ( fpm, pass. as_ptr ( ) )
450
463
} ;
451
- if !config. no_verify { assert ! ( addpass( "verify" ) ) ; }
452
464
465
+ if !config. no_verify { assert ! ( addpass( "verify" ) ) ; }
453
466
if !config. no_prepopulate_passes {
454
467
llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
455
468
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) ;
458
470
}
459
471
460
472
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) ) ;
464
476
}
465
477
}
466
478
467
479
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) ) ;
472
484
}
473
485
}
474
486
@@ -520,7 +532,6 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
520
532
llvm:: LLVMRustAddAnalysisPasses ( tm, cpm, llmod) ;
521
533
llvm:: LLVMRustAddLibraryInfo ( cpm, llmod, no_builtins) ;
522
534
f ( cpm) ;
523
- llvm:: LLVMDisposePassManager ( cpm) ;
524
535
}
525
536
526
537
if config. emit_bc {
@@ -537,13 +548,15 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
537
548
let out = path2cstr ( & out) ;
538
549
with_codegen ( tm, llmod, config. no_builtins , |cpm| {
539
550
llvm:: LLVMRustPrintModule ( cpm, llmod, out. as_ptr ( ) ) ;
551
+ llvm:: LLVMDisposePassManager ( cpm) ;
540
552
} )
541
553
}
542
554
543
555
if config. emit_asm {
544
556
let path = output_names. with_extension ( & format ! ( "{}.s" , name_extra) ) ;
545
557
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 ) ;
547
560
} ) ;
548
561
}
549
562
@@ -1008,25 +1021,16 @@ unsafe fn configure_llvm(sess: &Session) {
1008
1021
use std:: sync:: Once ;
1009
1022
static INIT : Once = Once :: new ( ) ;
1010
1023
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
-
1019
1024
let mut llvm_c_strs = Vec :: new ( ) ;
1020
1025
let mut llvm_args = Vec :: new ( ) ;
1026
+
1021
1027
{
1022
1028
let mut add = |arg : & str | {
1023
1029
let s = CString :: new ( arg) . unwrap ( ) ;
1024
1030
llvm_args. push ( s. as_ptr ( ) ) ;
1025
1031
llvm_c_strs. push ( s) ;
1026
1032
} ;
1027
1033
add ( "rustc" ) ; // fake program name
1028
- if vectorize_loop { add ( "-vectorize-loops" ) ; }
1029
- if vectorize_slp { add ( "-vectorize-slp" ) ; }
1030
1034
if sess. time_llvm_passes ( ) { add ( "-time-passes" ) ; }
1031
1035
if sess. print_llvm_passes ( ) { add ( "-debug-pass=Structure" ) ; }
1032
1036
@@ -1084,41 +1088,40 @@ unsafe fn populate_llvm_passes(fpm: llvm::PassManagerRef,
1084
1088
mpm : llvm:: PassManagerRef ,
1085
1089
llmod : ModuleRef ,
1086
1090
opt : llvm:: CodeGenOptLevel ,
1087
- no_builtins : bool ) {
1091
+ config : & ModuleConfig ) {
1088
1092
// Create the PassManagerBuilder for LLVM. We configure it with
1089
1093
// reasonable defaults and prepare it to actually populate the pass
1090
1094
// manager.
1091
1095
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.
1092
1108
match opt {
1093
1109
llvm:: CodeGenLevelNone => {
1094
- // Don't add lifetime intrinsics at O0
1095
1110
llvm:: LLVMRustAddAlwaysInlinePass ( builder, false ) ;
1096
1111
}
1097
1112
llvm:: CodeGenLevelLess => {
1098
1113
llvm:: LLVMRustAddAlwaysInlinePass ( builder, true ) ;
1099
1114
}
1100
- // numeric values copied from clang
1101
1115
llvm:: CodeGenLevelDefault => {
1102
- llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder,
1103
- 225 ) ;
1116
+ llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder, 225 ) ;
1104
1117
}
1105
1118
llvm:: CodeGenLevelAggressive => {
1106
- llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder,
1107
- 275 ) ;
1119
+ llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder, 275 ) ;
1108
1120
}
1109
1121
}
1110
- llvm:: LLVMPassManagerBuilderSetOptLevel ( builder, opt as c_uint ) ;
1111
- llvm:: LLVMRustAddBuilderLibraryInfo ( builder, llmod, no_builtins) ;
1112
1122
1113
1123
// Use the builder to populate the function/module pass managers.
1114
1124
llvm:: LLVMPassManagerBuilderPopulateFunctionPassManager ( builder, fpm) ;
1115
1125
llvm:: LLVMPassManagerBuilderPopulateModulePassManager ( builder, mpm) ;
1116
1126
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
- } ;
1124
1127
}
0 commit comments