diff options
Diffstat (limited to 'src/librustc_codegen_llvm/back/lto.rs')
| -rw-r--r-- | src/librustc_codegen_llvm/back/lto.rs | 105 |
1 files changed, 62 insertions, 43 deletions
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index a43fbb68dba..c4368d2cb8b 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -62,11 +62,13 @@ fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>, }; let exported_symbols = cgcx.exported_symbols .as_ref().expect("needs exported symbols for LTO"); - let mut symbol_white_list = exported_symbols[&LOCAL_CRATE] - .iter() - .filter_map(symbol_filter) - .collect::<Vec<CString>>(); - let _timer = cgcx.profile_activity("generate_symbol_white_list_for_thinlto"); + let mut symbol_white_list = { + let _timer = cgcx.prof.generic_activity("LLVM_lto_generate_symbol_white_list"); + exported_symbols[&LOCAL_CRATE] + .iter() + .filter_map(symbol_filter) + .collect::<Vec<CString>>() + }; info!("{} symbols to preserve in this crate", symbol_white_list.len()); // If we're performing LTO for the entire crate graph, then for each of our @@ -95,14 +97,17 @@ fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>, } for &(cnum, ref path) in cgcx.each_linked_rlib_for_lto.iter() { - let _timer = cgcx.profile_activity(format!("load: {}", path.display())); let exported_symbols = cgcx.exported_symbols .as_ref().expect("needs exported symbols for LTO"); - symbol_white_list.extend( - exported_symbols[&cnum] - .iter() - .filter_map(symbol_filter)); + { + let _timer = cgcx.prof.generic_activity("LLVM_lto_generate_symbol_white_list"); + symbol_white_list.extend( + exported_symbols[&cnum] + .iter() + .filter_map(symbol_filter)); + } + let _timer = cgcx.prof.generic_activity("LLVM_lto_load_upstream_bitcode"); let archive = ArchiveRO::open(&path).expect("wanted an rlib"); let bytecodes = archive.iter().filter_map(|child| { child.ok().and_then(|c| c.name().map(|name| (name, c))) @@ -189,6 +194,7 @@ fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>, symbol_white_list: &[*const libc::c_char]) -> Result<LtoModuleCodegen<LlvmCodegenBackend>, FatalError> { + let _timer = cgcx.prof.generic_activity("LLVM_fat_lto_build_monolithic_module"); info!("going for a fat lto"); // Sort out all our lists of incoming modules into two lists. @@ -287,6 +293,7 @@ fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>, // save and persist everything with the original module. let mut linker = Linker::new(llmod); for (bc_decoded, name) in serialized_modules { + let _timer = cgcx.prof.generic_activity("LLVM_fat_lto_link_module"); info!("linking {:?}", name); time_ext(cgcx.time_passes, None, &format!("ll link {:?}", name), || { let data = bc_decoded.data(); @@ -388,6 +395,7 @@ fn thin_lto(cgcx: &CodegenContext<LlvmCodegenBackend>, symbol_white_list: &[*const libc::c_char]) -> Result<(Vec<LtoModuleCodegen<LlvmCodegenBackend>>, Vec<WorkProduct>), FatalError> { + let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_global_analysis"); unsafe { info!("going for that thin, thin LTO"); @@ -601,16 +609,6 @@ impl ModuleBuffer { llvm::LLVMRustModuleBufferCreate(m) }) } - - pub fn parse<'a>( - &self, - name: &str, - cx: &'a llvm::Context, - handler: &Handler, - ) -> Result<&'a llvm::Module, FatalError> { - let name = CString::new(name).unwrap(); - parse_module(cx, &name, self.data(), handler) - } } impl ModuleBufferMethods for ModuleBuffer { @@ -723,7 +721,7 @@ pub unsafe fn optimize_thin_module( // Like with "fat" LTO, get some better optimizations if landing pads // are disabled by removing all landing pads. if cgcx.no_landing_pads { - let _timer = cgcx.profile_activity("LLVM_remove_landing_pads"); + let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_remove_landing_pads"); llvm::LLVMRustMarkAllFunctionsNounwind(llmod); save_temp_bitcode(&cgcx, &module, "thin-lto-after-nounwind"); } @@ -736,26 +734,41 @@ pub unsafe fn optimize_thin_module( // // You can find some more comments about these functions in the LLVM // bindings we've got (currently `PassWrapper.cpp`) - if !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod) { - let msg = "failed to prepare thin LTO module"; - return Err(write::llvm_err(&diag_handler, msg)) + { + let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_rename"); + if !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod) { + let msg = "failed to prepare thin LTO module"; + return Err(write::llvm_err(&diag_handler, msg)) + } + save_temp_bitcode(cgcx, &module, "thin-lto-after-rename"); } - save_temp_bitcode(cgcx, &module, "thin-lto-after-rename"); - if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) { - let msg = "failed to prepare thin LTO module"; - return Err(write::llvm_err(&diag_handler, msg)) + + { + let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_resolve_weak"); + if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) { + let msg = "failed to prepare thin LTO module"; + return Err(write::llvm_err(&diag_handler, msg)) + } + save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve"); } - save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve"); - if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) { - let msg = "failed to prepare thin LTO module"; - return Err(write::llvm_err(&diag_handler, msg)) + + { + let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_internalize"); + if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) { + let msg = "failed to prepare thin LTO module"; + return Err(write::llvm_err(&diag_handler, msg)) + } + save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize"); } - save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize"); - if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod) { - let msg = "failed to prepare thin LTO module"; - return Err(write::llvm_err(&diag_handler, msg)) + + { + let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_import"); + if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod) { + let msg = "failed to prepare thin LTO module"; + return Err(write::llvm_err(&diag_handler, msg)) + } + save_temp_bitcode(cgcx, &module, "thin-lto-after-import"); } - save_temp_bitcode(cgcx, &module, "thin-lto-after-import"); // Ok now this is a bit unfortunate. This is also something you won't // find upstream in LLVM's ThinLTO passes! This is a hack for now to @@ -786,18 +799,24 @@ pub unsafe fn optimize_thin_module( // not too much) but for now at least gets LLVM to emit valid DWARF (or // so it appears). Hopefully we can remove this once upstream bugs are // fixed in LLVM. - llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1); - save_temp_bitcode(cgcx, &module, "thin-lto-after-patch"); + { + let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_patch_debuginfo"); + llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1); + save_temp_bitcode(cgcx, &module, "thin-lto-after-patch"); + } // Alright now that we've done everything related to the ThinLTO // analysis it's time to run some optimizations! Here we use the same // `run_pass_manager` as the "fat" LTO above except that we tell it to // populate a thin-specific pass manager, which presumably LLVM treats a // little differently. - info!("running thin lto passes over {}", module.name); - let config = cgcx.config(module.kind); - run_pass_manager(cgcx, &module, config, true); - save_temp_bitcode(cgcx, &module, "thin-lto-after-pm"); + { + let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_optimize"); + info!("running thin lto passes over {}", module.name); + let config = cgcx.config(module.kind); + run_pass_manager(cgcx, &module, config, true); + save_temp_bitcode(cgcx, &module, "thin-lto-after-pm"); + } } Ok(module) } |
