@@ -216,7 +216,7 @@ pub mod write {
216
216
use lib;
217
217
218
218
use std:: c_str:: ToCStr ;
219
- use std:: libc:: c_uint;
219
+ use std:: libc:: { c_uint, c_int } ;
220
220
use std:: path:: Path ;
221
221
use std:: run;
222
222
use std:: str;
@@ -257,17 +257,7 @@ pub mod write {
257
257
}
258
258
}
259
259
260
- // Copy what clan does by turning on loop vectorization at O2 and
261
- // slp vectorization at O3
262
- let vectorize_loop = !sess. no_vectorize_loops ( ) &&
263
- ( sess. opts . optimize == session:: Default ||
264
- sess. opts . optimize == session:: Aggressive ) ;
265
- let vectorize_slp = !sess. no_vectorize_slp ( ) &&
266
- sess. opts . optimize == session:: Aggressive ;
267
- llvm:: LLVMRustSetLLVMOptions ( sess. print_llvm_passes ( ) ,
268
- vectorize_loop,
269
- vectorize_slp,
270
- sess. time_llvm_passes ( ) ) ;
260
+ configure_llvm ( sess) ;
271
261
272
262
let OptLevel = match sess. opts . optimize {
273
263
session:: No => lib:: llvm:: CodeGenLevelNone ,
@@ -293,12 +283,9 @@ pub mod write {
293
283
// Create the two optimizing pass managers. These mirror what clang
294
284
// does, and are by populated by LLVM's default PassManagerBuilder.
295
285
// Each manager has a different set of passes, but they also share
296
- // some common passes. Each one is initialized with the analyis
297
- // passes the target requires, and then further passes are added.
286
+ // some common passes.
298
287
let fpm = llvm:: LLVMCreateFunctionPassManagerForModule ( llmod) ;
299
288
let mpm = llvm:: LLVMCreatePassManager ( ) ;
300
- llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
301
- llvm:: LLVMRustAddAnalysisPasses ( tm, mpm, llmod) ;
302
289
303
290
// If we're verifying or linting, add them to the function pass
304
291
// manager.
@@ -308,32 +295,11 @@ pub mod write {
308
295
if !sess. no_verify ( ) { assert ! ( addpass( "verify" ) ) ; }
309
296
if sess. lint_llvm ( ) { assert ! ( addpass( "lint" ) ) ; }
310
297
311
- // Create the PassManagerBuilder for LLVM. We configure it with
312
- // reasonable defaults and prepare it to actually populate the pass
313
- // manager.
314
- let builder = llvm:: LLVMPassManagerBuilderCreate ( ) ;
315
- match sess. opts . optimize {
316
- session:: No => {
317
- // Don't add lifetime intrinsics add O0
318
- llvm:: LLVMRustAddAlwaysInlinePass ( builder, false ) ;
319
- }
320
- // numeric values copied from clang
321
- session:: Less => {
322
- llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder,
323
- 225 ) ;
324
- }
325
- session:: Default | session:: Aggressive => {
326
- llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder,
327
- 275 ) ;
328
- }
298
+ if !sess. no_prepopulate_passes ( ) {
299
+ llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
300
+ llvm:: LLVMRustAddAnalysisPasses ( tm, mpm, llmod) ;
301
+ populate_llvm_passess ( fpm, mpm, llmod, OptLevel ) ;
329
302
}
330
- llvm:: LLVMPassManagerBuilderSetOptLevel ( builder, OptLevel as c_uint ) ;
331
- llvm:: LLVMRustAddBuilderLibraryInfo ( builder, llmod) ;
332
-
333
- // Use the builder to populate the function/module pass managers.
334
- llvm:: LLVMPassManagerBuilderPopulateFunctionPassManager ( builder, fpm) ;
335
- llvm:: LLVMPassManagerBuilderPopulateModulePassManager ( builder, mpm) ;
336
- llvm:: LLVMPassManagerBuilderDispose ( builder) ;
337
303
338
304
for pass in sess. opts . custom_passes . iter ( ) {
339
305
do pass. with_c_str |s| {
@@ -424,6 +390,74 @@ pub mod write {
424
390
sess. abort_if_errors ( ) ;
425
391
}
426
392
}
393
+
394
+ unsafe fn configure_llvm ( sess : Session ) {
395
+ // Copy what clan does by turning on loop vectorization at O2 and
396
+ // slp vectorization at O3
397
+ let vectorize_loop = !sess. no_vectorize_loops ( ) &&
398
+ ( sess. opts . optimize == session:: Default ||
399
+ sess. opts . optimize == session:: Aggressive ) ;
400
+ let vectorize_slp = !sess. no_vectorize_slp ( ) &&
401
+ sess. opts . optimize == session:: Aggressive ;
402
+
403
+ let mut llvm_c_strs = ~[ ] ;
404
+ let mut llvm_args = ~[ ] ;
405
+ let add = |arg : & str | {
406
+ let s = arg. to_c_str ( ) ;
407
+ llvm_args. push ( s. with_ref ( |p| p) ) ;
408
+ llvm_c_strs. push ( s) ;
409
+ } ;
410
+ add ( "rustc" ) ; // fake program name
411
+ add ( "-arm-enable-ehabi" ) ;
412
+ add ( "-arm-enable-ehabi-descriptors" ) ;
413
+ if vectorize_loop { add ( "-vectorize-loops" ) ; }
414
+ if vectorize_slp { add ( "-vectorize-slp" ) ; }
415
+ if sess. time_llvm_passes ( ) { add ( "-time-passes" ) ; }
416
+ if sess. print_llvm_passes ( ) { add ( "-debug-pass=Structure" ) ; }
417
+
418
+ for arg in sess. opts . llvm_args . iter ( ) {
419
+ add ( * arg) ;
420
+ }
421
+
422
+ do llvm_args. as_imm_buf |p, len| {
423
+ llvm:: LLVMRustSetLLVMOptions ( len as c_int , p) ;
424
+ }
425
+ }
426
+
427
+ unsafe fn populate_llvm_passess ( fpm : lib:: llvm:: PassManagerRef ,
428
+ mpm : lib:: llvm:: PassManagerRef ,
429
+ llmod : ModuleRef ,
430
+ opt : lib:: llvm:: CodeGenOptLevel ) {
431
+ // Create the PassManagerBuilder for LLVM. We configure it with
432
+ // reasonable defaults and prepare it to actually populate the pass
433
+ // manager.
434
+ let builder = llvm:: LLVMPassManagerBuilderCreate ( ) ;
435
+ match opt {
436
+ lib:: llvm:: CodeGenLevelNone => {
437
+ // Don't add lifetime intrinsics add O0
438
+ llvm:: LLVMRustAddAlwaysInlinePass ( builder, false ) ;
439
+ }
440
+ lib:: llvm:: CodeGenLevelLess => {
441
+ llvm:: LLVMRustAddAlwaysInlinePass ( builder, true ) ;
442
+ }
443
+ // numeric values copied from clang
444
+ lib:: llvm:: CodeGenLevelDefault => {
445
+ llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder,
446
+ 225 ) ;
447
+ }
448
+ lib:: llvm:: CodeGenLevelAggressive => {
449
+ llvm:: LLVMPassManagerBuilderUseInlinerWithThreshold ( builder,
450
+ 275 ) ;
451
+ }
452
+ }
453
+ llvm:: LLVMPassManagerBuilderSetOptLevel ( builder, opt as c_uint ) ;
454
+ llvm:: LLVMRustAddBuilderLibraryInfo ( builder, llmod) ;
455
+
456
+ // Use the builder to populate the function/module pass managers.
457
+ llvm:: LLVMPassManagerBuilderPopulateFunctionPassManager ( builder, fpm) ;
458
+ llvm:: LLVMPassManagerBuilderPopulateModulePassManager ( builder, mpm) ;
459
+ llvm:: LLVMPassManagerBuilderDispose ( builder) ;
460
+ }
427
461
}
428
462
429
463
0 commit comments