From 0830cc92bd4c8dd8451931799acb4ada59d6bc88 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 16 Jul 2018 08:58:29 +0200 Subject: [PATCH] Revert "Clean up LLVM module naming (just use CodegenUnit names)." This reverts commit f6894ebe664d111259a91a2b5fcc1236ca413436. --- src/librustc_codegen_llvm/back/link.rs | 7 +++ src/librustc_codegen_llvm/back/lto.rs | 11 ++-- src/librustc_codegen_llvm/back/write.rs | 3 +- src/librustc_codegen_llvm/base.rs | 78 +++++++++++++++---------- src/librustc_codegen_llvm/context.rs | 5 +- src/librustc_codegen_llvm/lib.rs | 4 +- 6 files changed, 69 insertions(+), 39 deletions(-) diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs index 9e45da4cb6859..a7f0910a6fccc 100644 --- a/src/librustc_codegen_llvm/back/link.rs +++ b/src/librustc_codegen_llvm/back/link.rs @@ -45,6 +45,13 @@ use std::process::{Output, Stdio}; use std::str; use syntax::attr; +/// The LLVM module name containing crate-metadata. This includes a `.` on +/// purpose, so it cannot clash with the name of a user-defined module. +pub const METADATA_MODULE_NAME: &'static str = "crate.metadata"; + +// same as for metadata above, but for allocator shim +pub const ALLOCATOR_MODULE_NAME: &'static str = "crate.allocator"; + pub use rustc_codegen_utils::link::{find_crate_name, filename_for_input, default_output_for_target, invalid_output_for_target, build_link_meta, out_filename, check_file_is_writeable}; diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index a68f22b2651f9..ef03e76f94682 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -238,7 +238,7 @@ fn fat_lto(cgcx: &CodegenContext, .expect("must be codegen'ing at least one module"); let module = modules.remove(costliest_module); let llmod = module.llvm().expect("can't lto pre-codegened modules").llmod; - info!("using {:?} as a base module", module.name); + info!("using {:?} as a base module", module.llmod_id); // For all other modules we codegened we'll need to link them into our own // bitcode. All modules were codegened in their own LLVM context, however, @@ -248,7 +248,7 @@ fn fat_lto(cgcx: &CodegenContext, for module in modules { let llvm = module.llvm().expect("can't lto pre-codegened modules"); let buffer = ModuleBuffer::new(llvm.llmod); - let llmod_id = CString::new(&module.name[..]).unwrap(); + let llmod_id = CString::new(&module.llmod_id[..]).unwrap(); serialized_modules.push((SerializedModule::Local(buffer), llmod_id)); } @@ -376,9 +376,9 @@ fn thin_lto(cgcx: &CodegenContext, // the most expensive portion of this small bit of global // analysis! for (i, module) in modules.iter().enumerate() { - info!("local module: {} - {}", i, module.name); + info!("local module: {} - {}", i, module.llmod_id); let llvm = module.llvm().expect("can't lto precodegened module"); - let name = CString::new(module.name.clone()).unwrap(); + let name = CString::new(module.llmod_id.clone()).unwrap(); let buffer = ThinBuffer::new(llvm.llmod); thin_modules.push(llvm::ThinLTOModule { identifier: name.as_ptr(), @@ -387,7 +387,7 @@ fn thin_lto(cgcx: &CodegenContext, }); thin_buffers.push(buffer); module_names.push(name); - timeline.record(&module.name); + timeline.record(&module.llmod_id); } // FIXME: All upstream crates are deserialized internally in the @@ -676,6 +676,7 @@ impl ThinModule { llcx, tm, }), + llmod_id: self.name().to_string(), name: self.name().to_string(), kind: ModuleKind::Regular, }; diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 2179999125b61..d36142af56c65 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -694,7 +694,7 @@ unsafe fn codegen(cgcx: &CodegenContext, if config.emit_bc_compressed { let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION); - let data = bytecode::encode(&module.name, data); + let data = bytecode::encode(&module.llmod_id, data); if let Err(e) = fs::write(&dst, data) { diag_handler.err(&format!("failed to write bytecode: {}", e)); } @@ -1306,6 +1306,7 @@ fn execute_work_item(cgcx: &CodegenContext, assert_eq!(bytecode_compressed.is_some(), config.emit_bc_compressed); Ok(WorkItemResult::Compiled(CompiledModule { + llmod_id: module.llmod_id.clone(), name: module_name, kind: ModuleKind::Regular, pre_existing: true, diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 603ee78585ea6..9a625720f4d09 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -739,18 +739,15 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let link_meta = link::build_link_meta(crate_hash); // Codegen the metadata. - let metadata_cgu_name = CodegenUnit::build_cgu_name(tcx, - LOCAL_CRATE, - &["crate"], - Some("metadata")).as_str() - .to_string(); + let llmod_id = "metadata"; let (metadata_llcx, metadata_llmod, metadata) = time(tcx.sess, "write metadata", || { - write_metadata(tcx, &metadata_cgu_name, &link_meta) + write_metadata(tcx, llmod_id, &link_meta) }); let metadata_module = ModuleCodegen { - name: metadata_cgu_name, + name: link::METADATA_MODULE_NAME.to_string(), + llmod_id: llmod_id.to_string(), source: ModuleSource::Codegened(ModuleLlvm { llcx: metadata_llcx, llmod: metadata_llmod, @@ -813,30 +810,26 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Codegen an allocator shim, if any let allocator_module = if let Some(kind) = *tcx.sess.allocator_kind.get() { - let llmod_id = CodegenUnit::build_cgu_name(tcx, - LOCAL_CRATE, - &["crate"], - Some("allocator")).as_str() - .to_string(); - let (llcx, llmod) = unsafe { - context::create_context_and_module(tcx.sess, &llmod_id) - }; - let modules = ModuleLlvm { - llmod, - llcx, - tm: create_target_machine(tcx.sess, false), - }; - time(tcx.sess, "write allocator module", || { - unsafe { + unsafe { + let llmod_id = "allocator"; + let (llcx, llmod) = + context::create_context_and_module(tcx.sess, llmod_id); + let modules = ModuleLlvm { + llmod, + llcx, + tm: create_target_machine(tcx.sess, false), + }; + time(tcx.sess, "write allocator module", || { allocator::codegen(tcx, &modules, kind) - } - }); + }); - Some(ModuleCodegen { - name: llmod_id, - source: ModuleSource::Codegened(modules), - kind: ModuleKind::Allocator, - }) + Some(ModuleCodegen { + name: link::ALLOCATOR_MODULE_NAME.to_string(), + llmod_id: llmod_id.to_string(), + source: ModuleSource::Codegened(modules), + kind: ModuleKind::Allocator, + }) + } } else { None }; @@ -879,10 +872,21 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // succeed it means that none of the dependencies has changed // and we can safely re-use. if let Some(dep_node_index) = tcx.dep_graph.try_mark_green(tcx, dep_node) { + // Append ".rs" to LLVM module identifier. + // + // LLVM code generator emits a ".file filename" directive + // for ELF backends. Value of the "filename" is set as the + // LLVM module identifier. Due to a LLVM MC bug[1], LLVM + // crashes if the module identifier is same as other symbols + // such as a function name in the module. + // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 + let llmod_id = format!("{}.rs", cgu.name()); + let module = ModuleCodegen { name: cgu.name().to_string(), source: ModuleSource::Preexisting(buf), kind: ModuleKind::Regular, + llmod_id, }; tcx.dep_graph.mark_loaded_from_cache(dep_node_index, true); write::submit_codegened_module_to_llvm(tcx, module, 0); @@ -1191,8 +1195,21 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, { let cgu_name = cgu.name().to_string(); + // Append ".rs" to LLVM module identifier. + // + // LLVM code generator emits a ".file filename" directive + // for ELF backends. Value of the "filename" is set as the + // LLVM module identifier. Due to a LLVM MC bug[1], LLVM + // crashes if the module identifier is same as other symbols + // such as a function name in the module. + // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 + let llmod_id = format!("{}-{}.rs", + cgu.name(), + tcx.crate_disambiguator(LOCAL_CRATE) + .to_fingerprint().to_hex()); + // Instantiate monomorphizations without filling out definitions yet... - let cx = CodegenCx::new(tcx, cgu); + let cx = CodegenCx::new(tcx, cgu, &llmod_id); let module = { let mono_items = cx.codegen_unit .items_in_deterministic_order(cx.tcx); @@ -1250,6 +1267,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, name: cgu_name, source: ModuleSource::Codegened(llvm_module), kind: ModuleKind::Regular, + llmod_id, } }; diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 80187f939b452..b774d7c5def21 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -214,7 +214,8 @@ pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (Cont impl<'a, 'tcx> CodegenCx<'a, 'tcx> { pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, - codegen_unit: Arc>) + codegen_unit: Arc>, + llmod_id: &str) -> CodegenCx<'a, 'tcx> { // An interesting part of Windows which MSVC forces our hand on (and // apparently MinGW didn't) is the usage of `dllimport` and `dllexport` @@ -267,7 +268,7 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> { unsafe { let (llcx, llmod) = create_context_and_module(&tcx.sess, - &codegen_unit.name().as_str()); + &llmod_id[..]); let dbg_cx = if tcx.sess.opts.debuginfo != NoDebugInfo { let dctx = debuginfo::CrateDebugContext::new(llmod); diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index af3a512c37620..e575c7ad68491 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -258,8 +258,8 @@ struct ModuleCodegen { /// unique amongst **all** crates. Therefore, it should contain /// something unique to this crate (e.g., a module path) as well /// as the crate name and disambiguator. - /// We currently generate these names via CodegenUnit::build_cgu_name(). name: String, + llmod_id: String, source: ModuleSource, kind: ModuleKind, } @@ -306,6 +306,7 @@ impl ModuleCodegen { }; CompiledModule { + llmod_id: self.llmod_id, name: self.name.clone(), kind: self.kind, pre_existing, @@ -319,6 +320,7 @@ impl ModuleCodegen { #[derive(Debug)] struct CompiledModule { name: String, + llmod_id: String, kind: ModuleKind, pre_existing: bool, object: Option,