@@ -216,7 +216,7 @@ pub mod write {
216216 use lib;
217217
218218 use std:: c_str:: ToCStr ;
219- use std:: libc:: c_uint;
219+ use std:: libc:: { c_uint, c_int } ;
220220 use std:: path:: Path ;
221221 use std:: run;
222222 use std:: str;
@@ -257,17 +257,7 @@ pub mod write {
257257 }
258258 }
259259
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) ;
271261
272262 let OptLevel = match sess. opts . optimize {
273263 session:: No => lib:: llvm:: CodeGenLevelNone ,
@@ -293,12 +283,9 @@ pub mod write {
293283 // Create the two optimizing pass managers. These mirror what clang
294284 // does, and are by populated by LLVM's default PassManagerBuilder.
295285 // 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.
298287 let fpm = llvm:: LLVMCreateFunctionPassManagerForModule ( llmod) ;
299288 let mpm = llvm:: LLVMCreatePassManager ( ) ;
300- llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
301- llvm:: LLVMRustAddAnalysisPasses ( tm, mpm, llmod) ;
302289
303290 // If we're verifying or linting, add them to the function pass
304291 // manager.
@@ -308,32 +295,11 @@ pub mod write {
308295 if !sess. no_verify ( ) { assert ! ( addpass( "verify" ) ) ; }
309296 if sess. lint_llvm ( ) { assert ! ( addpass( "lint" ) ) ; }
310297
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 ) ;
329302 }
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) ;
337303
338304 for pass in sess. opts . custom_passes . iter ( ) {
339305 do pass. with_c_str |s| {
@@ -424,6 +390,74 @@ pub mod write {
424390 sess. abort_if_errors ( ) ;
425391 }
426392 }
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+ }
427461}
428462
429463
0 commit comments