@@ -329,33 +329,55 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
329
329
let mpm = llvm:: LLVMCreatePassManager ( ) ;
330
330
331
331
{
332
- // If we're verifying or linting, add them to the function pass
333
- // manager.
334
- let addpass = |pass_name : & str | {
332
+ let find_pass = |pass_name : & str | {
335
333
let pass_name = SmallCStr :: new ( pass_name) ;
336
- let pass = match llvm:: LLVMRustFindAndCreatePass ( pass_name. as_ptr ( ) ) {
337
- Some ( pass) => pass,
338
- None => return false ,
339
- } ;
340
- let pass_manager = match llvm:: LLVMRustPassKind ( pass) {
341
- llvm:: PassKind :: Function => & * fpm,
342
- llvm:: PassKind :: Module => & * mpm,
343
- llvm:: PassKind :: Other => {
344
- diag_handler. err ( "Encountered LLVM pass kind we can't handle" ) ;
345
- return true
346
- } ,
347
- } ;
348
- llvm:: LLVMRustAddPass ( pass_manager, pass) ;
349
- true
334
+ llvm:: LLVMRustFindAndCreatePass ( pass_name. as_ptr ( ) )
350
335
} ;
351
336
352
- if config. verify_llvm_ir { assert ! ( addpass( "verify" ) ) ; }
337
+ if config. verify_llvm_ir {
338
+ // Verification should run as the very first pass.
339
+ llvm:: LLVMRustAddPass ( fpm, find_pass ( "verify" ) . unwrap ( ) ) ;
340
+ }
341
+
342
+ let mut extra_passes = Vec :: new ( ) ;
343
+ let mut have_name_anon_globals_pass = false ;
344
+
345
+ for pass_name in & config. passes {
346
+ if pass_name == "lint" {
347
+ // Linting should also be performed early, directly on the generated IR.
348
+ llvm:: LLVMRustAddPass ( fpm, find_pass ( "lint" ) . unwrap ( ) ) ;
349
+ continue ;
350
+ }
351
+
352
+ if let Some ( pass) = find_pass ( pass_name) {
353
+ extra_passes. push ( pass) ;
354
+ } else {
355
+ diag_handler. warn ( & format ! ( "unknown pass `{}`, ignoring" , pass_name) ) ;
356
+ }
357
+
358
+ if pass_name == "name-anon-globals" {
359
+ have_name_anon_globals_pass = true ;
360
+ }
361
+ }
362
+
363
+ for pass_name in & cgcx. plugin_passes {
364
+ if let Some ( pass) = find_pass ( pass_name) {
365
+ extra_passes. push ( pass) ;
366
+ } else {
367
+ diag_handler. err ( & format ! ( "a plugin asked for LLVM pass \
368
+ `{}` but LLVM does not \
369
+ recognize it", pass_name) ) ;
370
+ }
371
+
372
+ if pass_name == "name-anon-globals" {
373
+ have_name_anon_globals_pass = true ;
374
+ }
375
+ }
353
376
354
377
// Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need
355
378
// to make sure we run LLVM's NameAnonGlobals pass when emitting bitcode; otherwise
356
379
// we'll get errors in LLVM.
357
380
let using_thin_buffers = config. bitcode_needed ( ) ;
358
- let mut have_name_anon_globals_pass = false ;
359
381
if !config. no_prepopulate_passes {
360
382
llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
361
383
llvm:: LLVMRustAddAnalysisPasses ( tm, mpm, llmod) ;
@@ -364,34 +386,22 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
364
386
let prepare_for_thin_lto = cgcx. lto == Lto :: Thin || cgcx. lto == Lto :: ThinLocal ||
365
387
( cgcx. lto != Lto :: Fat && cgcx. opts . cg . linker_plugin_lto . enabled ( ) ) ;
366
388
with_llvm_pmb ( llmod, & config, opt_level, prepare_for_thin_lto, & mut |b| {
389
+ llvm:: LLVMRustAddLastExtensionPasses (
390
+ b, extra_passes. as_ptr ( ) , extra_passes. len ( ) as size_t ) ;
367
391
llvm:: LLVMPassManagerBuilderPopulateFunctionPassManager ( b, fpm) ;
368
392
llvm:: LLVMPassManagerBuilderPopulateModulePassManager ( b, mpm) ;
369
393
} ) ;
370
394
371
395
have_name_anon_globals_pass = have_name_anon_globals_pass || prepare_for_thin_lto;
372
396
if using_thin_buffers && !prepare_for_thin_lto {
373
- assert ! ( addpass( "name-anon-globals" ) ) ;
374
- have_name_anon_globals_pass = true ;
375
- }
376
- }
377
-
378
- for pass in & config. passes {
379
- if !addpass ( pass) {
380
- diag_handler. warn ( & format ! ( "unknown pass `{}`, ignoring" , pass) ) ;
381
- }
382
- if pass == "name-anon-globals" {
397
+ llvm:: LLVMRustAddPass ( mpm, find_pass ( "name-anon-globals" ) . unwrap ( ) ) ;
383
398
have_name_anon_globals_pass = true ;
384
399
}
385
- }
386
-
387
- for pass in & cgcx. plugin_passes {
388
- if !addpass ( pass) {
389
- diag_handler. err ( & format ! ( "a plugin asked for LLVM pass \
390
- `{}` but LLVM does not \
391
- recognize it", pass) ) ;
392
- }
393
- if pass == "name-anon-globals" {
394
- have_name_anon_globals_pass = true ;
400
+ } else {
401
+ // If we don't use the standard pipeline, directly populate the MPM
402
+ // with the extra passes.
403
+ for pass in extra_passes {
404
+ llvm:: LLVMRustAddPass ( mpm, pass) ;
395
405
}
396
406
}
397
407
0 commit comments