@@ -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