diff options
Diffstat (limited to 'src/librustc_codegen_llvm/back/write.rs')
| -rw-r--r-- | src/librustc_codegen_llvm/back/write.rs | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index b135605cf02..253110dcb34 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -329,33 +329,55 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>, let mpm = llvm::LLVMCreatePassManager(); { - // If we're verifying or linting, add them to the function pass - // manager. - let addpass = |pass_name: &str| { + let find_pass = |pass_name: &str| { let pass_name = SmallCStr::new(pass_name); - let pass = match llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) { - Some(pass) => pass, - None => return false, - }; - let pass_manager = match llvm::LLVMRustPassKind(pass) { - llvm::PassKind::Function => &*fpm, - llvm::PassKind::Module => &*mpm, - llvm::PassKind::Other => { - diag_handler.err("Encountered LLVM pass kind we can't handle"); - return true - }, - }; - llvm::LLVMRustAddPass(pass_manager, pass); - true + llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) }; - if config.verify_llvm_ir { assert!(addpass("verify")); } + if config.verify_llvm_ir { + // Verification should run as the very first pass. + llvm::LLVMRustAddPass(fpm, find_pass("verify").unwrap()); + } + + let mut extra_passes = Vec::new(); + let mut have_name_anon_globals_pass = false; + + for pass_name in &config.passes { + if pass_name == "lint" { + // Linting should also be performed early, directly on the generated IR. + llvm::LLVMRustAddPass(fpm, find_pass("lint").unwrap()); + continue; + } + + if let Some(pass) = find_pass(pass_name) { + extra_passes.push(pass); + } else { + diag_handler.warn(&format!("unknown pass `{}`, ignoring", pass_name)); + } + + if pass_name == "name-anon-globals" { + have_name_anon_globals_pass = true; + } + } + + for pass_name in &cgcx.plugin_passes { + if let Some(pass) = find_pass(pass_name) { + extra_passes.push(pass); + } else { + diag_handler.err(&format!("a plugin asked for LLVM pass \ + `{}` but LLVM does not \ + recognize it", pass_name)); + } + + if pass_name == "name-anon-globals" { + have_name_anon_globals_pass = true; + } + } // Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need // to make sure we run LLVM's NameAnonGlobals pass when emitting bitcode; otherwise // we'll get errors in LLVM. let using_thin_buffers = config.bitcode_needed(); - let mut have_name_anon_globals_pass = false; if !config.no_prepopulate_passes { llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod); llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod); @@ -364,34 +386,22 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>, let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal || (cgcx.lto != Lto::Fat && cgcx.opts.cg.linker_plugin_lto.enabled()); with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| { + llvm::LLVMRustAddLastExtensionPasses( + b, extra_passes.as_ptr(), extra_passes.len() as size_t); llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm); llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm); }); have_name_anon_globals_pass = have_name_anon_globals_pass || prepare_for_thin_lto; if using_thin_buffers && !prepare_for_thin_lto { - assert!(addpass("name-anon-globals")); - have_name_anon_globals_pass = true; - } - } - - for pass in &config.passes { - if !addpass(pass) { - diag_handler.warn(&format!("unknown pass `{}`, ignoring", pass)); - } - if pass == "name-anon-globals" { + llvm::LLVMRustAddPass(mpm, find_pass("name-anon-globals").unwrap()); have_name_anon_globals_pass = true; } - } - - for pass in &cgcx.plugin_passes { - if !addpass(pass) { - diag_handler.err(&format!("a plugin asked for LLVM pass \ - `{}` but LLVM does not \ - recognize it", pass)); - } - if pass == "name-anon-globals" { - have_name_anon_globals_pass = true; + } else { + // If we don't use the standard pipeline, directly populate the MPM + // with the extra passes. + for pass in extra_passes { + llvm::LLVMRustAddPass(mpm, pass); } } |
