@@ -329,33 +329,55 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
329329 let mpm = llvm:: LLVMCreatePassManager ( ) ;
330330
331331 {
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 | {
335333 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 ( ) )
350335 } ;
351336
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+ }
353376
354377 // Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need
355378 // to make sure we run LLVM's NameAnonGlobals pass when emitting bitcode; otherwise
356379 // we'll get errors in LLVM.
357380 let using_thin_buffers = config. bitcode_needed ( ) ;
358- let mut have_name_anon_globals_pass = false ;
359381 if !config. no_prepopulate_passes {
360382 llvm:: LLVMRustAddAnalysisPasses ( tm, fpm, llmod) ;
361383 llvm:: LLVMRustAddAnalysisPasses ( tm, mpm, llmod) ;
@@ -364,34 +386,22 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
364386 let prepare_for_thin_lto = cgcx. lto == Lto :: Thin || cgcx. lto == Lto :: ThinLocal ||
365387 ( cgcx. lto != Lto :: Fat && cgcx. opts . cg . linker_plugin_lto . enabled ( ) ) ;
366388 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 ) ;
367391 llvm:: LLVMPassManagerBuilderPopulateFunctionPassManager ( b, fpm) ;
368392 llvm:: LLVMPassManagerBuilderPopulateModulePassManager ( b, mpm) ;
369393 } ) ;
370394
371395 have_name_anon_globals_pass = have_name_anon_globals_pass || prepare_for_thin_lto;
372396 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 ( ) ) ;
383398 have_name_anon_globals_pass = true ;
384399 }
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) ;
395405 }
396406 }
397407
0 commit comments