summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-07-13 22:06:38 +0000
committerbors <bors@rust-lang.org>2018-07-13 22:06:38 +0000
commita14a361c2c80fdcd0270766e0bd57104e608988e (patch)
treeb99e7d5c2a0ea280dd37ed069907b86e3ca05af9 /src
parent254f8796b729810846e2b97620032ecaf103db33 (diff)
parente045a6cd8c0235a26ef11e6cd9a13ebd817f1265 (diff)
downloadrust-a14a361c2c80fdcd0270766e0bd57104e608988e.tar.gz
Auto merge of #52266 - michaelwoerister:incr-thinlto-preliminaries, r=alexcrichton
Preliminary work for incremental ThinLTO. Since implementing incremental ThinLTO is a bit more involved than I initially thought, I'm splitting out some of the things that already work. This PR (1) adds a way accessing some ThinLTO information in `rustc` and (2) does some cleanup around CGU/object file naming (which makes things quite a bit nicer). This is probably best reviewed one commit at a time.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/mir/mono.rs79
-rw-r--r--src/librustc/session/mod.rs9
-rw-r--r--src/librustc_codegen_llvm/back/link.rs7
-rw-r--r--src/librustc_codegen_llvm/back/lto.rs151
-rw-r--r--src/librustc_codegen_llvm/back/write.rs3
-rw-r--r--src/librustc_codegen_llvm/base.rs102
-rw-r--r--src/librustc_codegen_llvm/context.rs5
-rw-r--r--src/librustc_codegen_llvm/lib.rs6
-rw-r--r--src/librustc_incremental/assert_module_sources.rs53
-rw-r--r--src/librustc_incremental/lib.rs1
-rw-r--r--src/librustc_incremental/persist/mod.rs1
-rw-r--r--src/librustc_llvm/ffi.rs9
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs68
-rw-r--r--src/rustllvm/PassWrapper.cpp29
-rw-r--r--src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs6
-rw-r--r--src/test/codegen-units/item-collection/generic-drop-glue.rs12
-rw-r--r--src/test/codegen-units/item-collection/instantiation-through-vtable.rs4
-rw-r--r--src/test/codegen-units/item-collection/non-generic-drop-glue.rs4
-rw-r--r--src/test/codegen-units/item-collection/transitive-drop-glue.rs18
-rw-r--r--src/test/codegen-units/item-collection/tuple-drop-glue.rs8
-rw-r--r--src/test/codegen-units/item-collection/unsizing.rs8
-rw-r--r--src/test/incremental/issue-39828/auxiliary/generic.rs2
-rw-r--r--src/test/run-make-fulldeps/cross-lang-lto/Makefile8
-rw-r--r--src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile2
-rw-r--r--src/tools/compiletest/src/runtest.rs33
25 files changed, 457 insertions, 171 deletions
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index 79566fbbc11..5ca0dda7545 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc/mir/mono.rs
@@ -8,15 +8,16 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use hir::def_id::DefId;
+use hir::def_id::{DefId, CrateNum};
use syntax::ast::NodeId;
-use syntax::symbol::InternedString;
+use syntax::symbol::{Symbol, InternedString};
use ty::{Instance, TyCtxt};
use util::nodemap::FxHashMap;
use rustc_data_structures::base_n;
use rustc_data_structures::stable_hasher::{HashStable, StableHasherResult,
StableHasher};
use ich::{Fingerprint, StableHashingContext, NodeIdHashingMode};
+use std::fmt;
use std::hash::Hash;
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
@@ -173,6 +174,80 @@ impl<'tcx> CodegenUnit<'tcx> {
self.size_estimate = Some(size_estimate + delta);
}
}
+
+ /// CGU names should fulfill the following requirements:
+ /// - They should be able to act as a file name on any kind of file system
+ /// - They should not collide with other CGU names, even for different versions
+ /// of the same crate.
+ ///
+ /// Consequently, we don't use special characters except for '.' and '-' and we
+ /// prefix each name with the crate-name and crate-disambiguator.
+ ///
+ /// This function will build CGU names of the form:
+ ///
+ /// ```
+ /// <crate-name>.<crate-disambiguator>(-<component>)*[.<special-suffix>]
+ /// ```
+ ///
+ /// The '.' before `<special-suffix>` makes sure that names with a special
+ /// suffix can never collide with a name built out of regular Rust
+ /// identifiers (e.g. module paths).
+ pub fn build_cgu_name<I, C, S>(tcx: TyCtxt,
+ cnum: CrateNum,
+ components: I,
+ special_suffix: Option<S>)
+ -> InternedString
+ where I: IntoIterator<Item=C>,
+ C: fmt::Display,
+ S: fmt::Display,
+ {
+ let cgu_name = CodegenUnit::build_cgu_name_no_mangle(tcx,
+ cnum,
+ components,
+ special_suffix);
+
+ if tcx.sess.opts.debugging_opts.human_readable_cgu_names {
+ cgu_name
+ } else {
+ let cgu_name = &cgu_name.as_str()[..];
+ Symbol::intern(&CodegenUnit::mangle_name(cgu_name)).as_interned_str()
+ }
+ }
+
+ /// Same as `CodegenUnit::build_cgu_name()` but will never mangle the
+ /// resulting name.
+ pub fn build_cgu_name_no_mangle<I, C, S>(tcx: TyCtxt,
+ cnum: CrateNum,
+ components: I,
+ special_suffix: Option<S>)
+ -> InternedString
+ where I: IntoIterator<Item=C>,
+ C: fmt::Display,
+ S: fmt::Display,
+ {
+ use std::fmt::Write;
+
+ let mut cgu_name = String::with_capacity(64);
+
+ // Start out with the crate name and disambiguator
+ write!(cgu_name,
+ "{}.{}",
+ tcx.crate_name(cnum),
+ tcx.crate_disambiguator(cnum)).unwrap();
+
+ // Add the components
+ for component in components {
+ write!(cgu_name, "-{}", component).unwrap();
+ }
+
+ if let Some(special_suffix) = special_suffix {
+ // We add a dot in here so it cannot clash with anything in a regular
+ // Rust identifier
+ write!(cgu_name, ".{}", special_suffix).unwrap();
+ }
+
+ Symbol::intern(&cgu_name[..]).as_interned_str()
+ }
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for CodegenUnit<'tcx> {
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index ad1df0a1348..c28b49756f0 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -26,6 +26,7 @@ use util::nodemap::{FxHashMap, FxHashSet};
use util::common::{duration_to_secs_str, ErrorReported};
use util::common::ProfileQueriesMsg;
+use rustc_data_structures::base_n;
use rustc_data_structures::sync::{self, Lrc, Lock, LockCell, OneThread, Once, RwLock};
use syntax::ast::NodeId;
@@ -1185,6 +1186,14 @@ impl CrateDisambiguator {
}
}
+impl fmt::Display for CrateDisambiguator {
+ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ let (a, b) = self.0.as_value();
+ let as_u128 = a as u128 | ((b as u128) << 64);
+ f.write_str(&base_n::encode(as_u128, base_n::CASE_INSENSITIVE))
+ }
+}
+
impl From<Fingerprint> for CrateDisambiguator {
fn from(fingerprint: Fingerprint) -> CrateDisambiguator {
CrateDisambiguator(fingerprint)
diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs
index a7f0910a6fc..9e45da4cb68 100644
--- a/src/librustc_codegen_llvm/back/link.rs
+++ b/src/librustc_codegen_llvm/back/link.rs
@@ -45,13 +45,6 @@ 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 a33f8b569d0..55499552f5c 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -20,16 +20,23 @@ use rustc::hir::def_id::LOCAL_CRATE;
use rustc::middle::exported_symbols::SymbolExportLevel;
use rustc::session::config::{self, Lto};
use rustc::util::common::time_ext;
+use rustc_data_structures::fx::FxHashMap;
use time_graph::Timeline;
use {ModuleCodegen, ModuleLlvm, ModuleKind, ModuleSource};
use libc;
-use std::ffi::CString;
+use std::ffi::{CString, CStr};
+use std::fs::File;
+use std::io;
+use std::mem;
+use std::path::Path;
use std::ptr;
use std::slice;
use std::sync::Arc;
+pub const THIN_LTO_IMPORTS_INCR_COMP_FILE_NAME: &str = "thin-lto-imports.bin";
+
pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool {
match crate_type {
config::CrateTypeExecutable |
@@ -193,7 +200,7 @@ pub(crate) fn run(cgcx: &CodegenContext,
}
Lto::Thin |
Lto::ThinLocal => {
- thin_lto(&diag_handler, modules, upstream_modules, &arr, timeline)
+ thin_lto(cgcx, &diag_handler, modules, upstream_modules, &arr, timeline)
}
Lto::No => unreachable!(),
}
@@ -231,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.llmod_id);
+ info!("using {:?} as a base module", module.name);
// 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,
@@ -241,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.llmod_id[..]).unwrap();
+ let llmod_id = CString::new(&module.name[..]).unwrap();
serialized_modules.push((SerializedModule::Local(buffer), llmod_id));
}
@@ -346,7 +353,8 @@ impl Drop for Linker {
/// calculating the *index* for ThinLTO. This index will then be shared amongst
/// all of the `LtoModuleCodegen` units returned below and destroyed once
/// they all go out of scope.
-fn thin_lto(diag_handler: &Handler,
+fn thin_lto(cgcx: &CodegenContext,
+ diag_handler: &Handler,
modules: Vec<ModuleCodegen>,
serialized_modules: Vec<(SerializedModule, CString)>,
symbol_white_list: &[*const libc::c_char],
@@ -368,9 +376,9 @@ fn thin_lto(diag_handler: &Handler,
// the most expensive portion of this small bit of global
// analysis!
for (i, module) in modules.iter().enumerate() {
- info!("local module: {} - {}", i, module.llmod_id);
+ info!("local module: {} - {}", i, module.name);
let llvm = module.llvm().expect("can't lto precodegened module");
- let name = CString::new(module.llmod_id.clone()).unwrap();
+ let name = CString::new(module.name.clone()).unwrap();
let buffer = ThinBuffer::new(llvm.llmod);
thin_modules.push(llvm::ThinLTOModule {
identifier: name.as_ptr(),
@@ -379,7 +387,7 @@ fn thin_lto(diag_handler: &Handler,
});
thin_buffers.push(buffer);
module_names.push(name);
- timeline.record(&module.llmod_id);
+ timeline.record(&module.name);
}
// FIXME: All upstream crates are deserialized internally in the
@@ -424,6 +432,18 @@ fn thin_lto(diag_handler: &Handler,
let msg = format!("failed to prepare thin LTO context");
return Err(write::llvm_err(&diag_handler, msg))
}
+
+ // Save the ThinLTO import information for incremental compilation.
+ if let Some(ref incr_comp_session_dir) = cgcx.incr_comp_session_dir {
+ let path = incr_comp_session_dir.join(THIN_LTO_IMPORTS_INCR_COMP_FILE_NAME);
+ let imports = ThinLTOImports::from_thin_lto_data(data);
+ if let Err(err) = imports.save_to_file(&path) {
+ let msg = format!("Error while writing ThinLTO import data: {}",
+ err);
+ return Err(write::llvm_err(&diag_handler, msg));
+ }
+ }
+
let data = ThinData(data);
info!("thin LTO data created");
timeline.record("data");
@@ -656,7 +676,6 @@ impl ThinModule {
llcx,
tm,
}),
- llmod_id: self.name().to_string(),
name: self.name().to_string(),
kind: ModuleKind::Regular,
};
@@ -776,3 +795,117 @@ impl ThinModule {
Ok(module)
}
}
+
+
+#[derive(Debug)]
+pub struct ThinLTOImports {
+ // key = llvm name of importing module, value = list of modules it imports from
+ imports: FxHashMap<String, Vec<String>>,
+}
+
+impl ThinLTOImports {
+
+ pub fn new() -> ThinLTOImports {
+ ThinLTOImports {
+ imports: FxHashMap(),
+ }
+ }
+
+ /// Load the ThinLTO import map from ThinLTOData.
+ unsafe fn from_thin_lto_data(data: *const llvm::ThinLTOData) -> ThinLTOImports {
+
+ fn module_name_to_str(c_str: &CStr) -> &str {
+ match c_str.to_str() {
+ Ok(s) => s,
+ Err(e) => {
+ bug!("Encountered non-utf8 LLVM module name `{}`: {}",
+ c_str.to_string_lossy(),
+ e)
+ }
+ }
+ }
+
+ unsafe extern "C" fn imported_module_callback(payload: *mut libc::c_void,
+ importing_module_name: *const libc::c_char,
+ imported_module_name: *const libc::c_char) {
+ let map = &mut* (payload as *mut ThinLTOImports);
+
+ let importing_module_name = CStr::from_ptr(importing_module_name);
+ let importing_module_name = module_name_to_str(&importing_module_name);
+ let imported_module_name = CStr::from_ptr(imported_module_name);
+ let imported_module_name = module_name_to_str(&imported_module_name);
+
+ if !map.imports.contains_key(importing_module_name) {
+ map.imports.insert(importing_module_name.to_owned(), vec![]);
+ }
+
+ map.imports
+ .get_mut(importing_module_name)
+ .unwrap()
+ .push(imported_module_name.to_owned());
+ }
+
+ let mut map = ThinLTOImports {
+ imports: FxHashMap(),
+ };
+
+ llvm::LLVMRustGetThinLTOModuleImports(data,
+ imported_module_callback,
+ &mut map as *mut _ as *mut libc::c_void);
+ map
+ }
+
+ pub fn save_to_file(&self, path: &Path) -> io::Result<()> {
+ use std::io::Write;
+
+ let file = File::create(path)?;
+ let mut writer = io::BufWriter::new(file);
+
+ for (importing_module_name, imported_modules) in &self.imports {
+ writeln!(writer, "{}", importing_module_name)?;
+
+ for imported_module in imported_modules {
+ writeln!(writer, " {}", imported_module)?;
+ }
+
+ writeln!(writer)?;
+ }
+
+ Ok(())
+ }
+
+ pub fn load_from_file(path: &Path) -> io::Result<ThinLTOImports> {
+ use std::io::BufRead;
+
+ let mut imports = FxHashMap();
+ let mut current_module = None;
+ let mut current_imports = vec![];
+
+ let file = File::open(path)?;
+
+ for line in io::BufReader::new(file).lines() {
+ let line = line?;
+
+ if line.is_empty() {
+ let importing_module = current_module
+ .take()
+ .expect("Importing module not set");
+
+ imports.insert(importing_module,
+ mem::replace(&mut current_imports, vec![]));
+ } else if line.starts_with(" ") {
+ // This is an imported module
+ assert_ne!(current_module, None);
+ current_imports.push(line.trim().to_string());
+ } else {
+ // This is the beginning of a new module
+ assert_eq!(current_module, None);
+ current_module = Some(line.trim().to_string());
+ }
+ }
+
+ Ok(ThinLTOImports {
+ imports
+ })
+ }
+}
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 467782518f6..99daf4b0ed6 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -696,7 +696,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.llmod_id, data);
+ let data = bytecode::encode(&module.name, data);
if let Err(e) = fs::write(&dst, data) {
diag_handler.err(&format!("failed to write bytecode: {}", e));
}
@@ -1308,7 +1308,6 @@ 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 ea26e271c9b..451e5cf9a60 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -29,7 +29,7 @@ use super::ModuleCodegen;
use super::ModuleKind;
use abi;
-use back::link;
+use back::{link, lto};
use back::write::{self, OngoingCodegen, create_target_machine};
use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param};
use llvm;
@@ -739,15 +739,18 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let link_meta = link::build_link_meta(crate_hash);
// Codegen the metadata.
- let llmod_id = "metadata";
+ let metadata_cgu_name = CodegenUnit::build_cgu_name(tcx,
+ LOCAL_CRATE,
+ &["crate"],
+ Some("metadata")).as_str()
+ .to_string();
let (metadata_llcx, metadata_llmod, metadata) =
time(tcx.sess, "write metadata", || {
- write_metadata(tcx, llmod_id, &link_meta)
+ write_metadata(tcx, &metadata_cgu_name, &link_meta)
});
let metadata_module = ModuleCodegen {
- name: link::METADATA_MODULE_NAME.to_string(),
- llmod_id: llmod_id.to_string(),
+ name: metadata_cgu_name,
source: ModuleSource::Codegened(ModuleLlvm {
llcx: metadata_llcx,
llmod: metadata_llmod,
@@ -810,26 +813,30 @@ 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() {
- 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", || {
+ 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 {
allocator::codegen(tcx, &modules, kind)
- });
+ }
+ });
- Some(ModuleCodegen {
- name: link::ALLOCATOR_MODULE_NAME.to_string(),
- llmod_id: llmod_id.to_string(),
- source: ModuleSource::Codegened(modules),
- kind: ModuleKind::Allocator,
- })
- }
+ Some(ModuleCodegen {
+ name: llmod_id,
+ source: ModuleSource::Codegened(modules),
+ kind: ModuleKind::Allocator,
+ })
} else {
None
};
@@ -872,21 +879,10 @@ 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);
@@ -1195,21 +1191,8 @@ 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, &llmod_id);
+ let cx = CodegenCx::new(tcx, cgu);
let module = {
let mono_items = cx.codegen_unit
.items_in_deterministic_order(cx.tcx);
@@ -1267,7 +1250,6 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
name: cgu_name,
source: ModuleSource::Codegened(llvm_module),
kind: ModuleKind::Regular,
- llmod_id,
}
};
@@ -1370,6 +1352,27 @@ mod temp_stable_hash_impls {
}
}
+#[allow(unused)]
+fn load_thin_lto_imports(sess: &Session) -> lto::ThinLTOImports {
+ let path = rustc_incremental::in_incr_comp_dir_sess(
+ sess,
+ lto::THIN_LTO_IMPORTS_INCR_COMP_FILE_NAME
+ );
+
+ if !path.exists() {
+ return lto::ThinLTOImports::new();
+ }
+
+ match lto::ThinLTOImports::load_from_file(&path) {
+ Ok(imports) => imports,
+ Err(e) => {
+ let msg = format!("Error while trying to load ThinLTO import data \
+ for incremental compilation: {}", e);
+ sess.fatal(&msg)
+ }
+ }
+}
+
pub fn define_custom_section(cx: &CodegenCx, def_id: DefId) {
use rustc::mir::interpret::GlobalId;
@@ -1408,3 +1411,4 @@ pub fn define_custom_section(cx: &CodegenCx, def_id: DefId) {
);
}
}
+
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index b774d7c5def..80187f939b4 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -214,8 +214,7 @@ 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<CodegenUnit<'tcx>>,
- llmod_id: &str)
+ codegen_unit: Arc<CodegenUnit<'tcx>>)
-> 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`
@@ -268,7 +267,7 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
unsafe {
let (llcx, llmod) = create_context_and_module(&tcx.sess,
- &llmod_id[..]);
+ &codegen_unit.name().as_str());
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 8aa7902021f..af3a512c376 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -90,7 +90,7 @@ mod back {
mod command;
pub mod linker;
pub mod link;
- mod lto;
+ pub mod lto;
pub mod symbol_export;
pub mod write;
mod rpath;
@@ -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,7 +306,6 @@ impl ModuleCodegen {
};
CompiledModule {
- llmod_id: self.llmod_id,
name: self.name.clone(),
kind: self.kind,
pre_existing,
@@ -320,7 +319,6 @@ impl ModuleCodegen {
#[derive(Debug)]
struct CompiledModule {
name: String,
- llmod_id: String,
kind: ModuleKind,
pre_existing: bool,
object: Option<PathBuf>,
diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index df8e0f056af..f6e9ee7b225 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/src/librustc_incremental/assert_module_sources.rs
@@ -27,11 +27,11 @@
//! the HIR doesn't change as a result of the annotations, which might
//! perturb the reuse results.
+use rustc::hir::def_id::LOCAL_CRATE;
use rustc::dep_graph::{DepNode, DepConstructor};
use rustc::mir::mono::CodegenUnit;
use rustc::ty::TyCtxt;
use syntax::ast;
-use syntax_pos::symbol::Symbol;
use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED};
const MODULE: &'static str = "module";
@@ -72,12 +72,37 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
return;
}
- let mname = self.field(attr, MODULE);
- let mangled_cgu_name = CodegenUnit::mangle_name(&mname.as_str());
- let mangled_cgu_name = Symbol::intern(&mangled_cgu_name).as_interned_str();
+ let user_path = self.field(attr, MODULE).as_str().to_string();
+ let crate_name = self.tcx.crate_name(LOCAL_CRATE).as_str().to_string();
+
+ if !user_path.starts_with(&crate_name) {
+ let msg = format!("Found malformed codegen unit name `{}`. \
+ Codegen units names must always start with the name of the \
+ crate (`{}` in this case).", user_path, crate_name);
+ self.tcx.sess.span_fatal(attr.span, &msg);
+ }
+
+ // Split of the "special suffix" if there is one.
+ let (user_path, cgu_special_suffix) = if let Some(index) = user_path.rfind(".") {
+ (&user_path[..index], Some(&user_path[index + 1 ..]))
+ } else {
+ (&user_path[..], None)
+ };
+
+ let mut cgu_path_components = user_path.split("-").collect::<Vec<_>>();
+
+ // Remove the crate name
+ assert_eq!(cgu_path_components.remove(0), crate_name);
+
+ let cgu_name = CodegenUnit::build_cgu_name(self.tcx,
+ LOCAL_CRATE,
+ cgu_path_components,
+ cgu_special_suffix);
+
+ debug!("mapping '{}' to cgu name '{}'", self.field(attr, MODULE), cgu_name);
let dep_node = DepNode::new(self.tcx,
- DepConstructor::CompileCodegenUnit(mangled_cgu_name));
+ DepConstructor::CompileCodegenUnit(cgu_name));
if let Some(loaded_from_cache) = self.tcx.dep_graph.was_loaded_from_cache(&dep_node) {
match (disposition, loaded_from_cache) {
@@ -85,13 +110,13 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
self.tcx.sess.span_err(
attr.span,
&format!("expected module named `{}` to be Reused but is Codegened",
- mname));
+ user_path));
}
(Disposition::Codegened, true) => {
self.tcx.sess.span_err(
attr.span,
&format!("expected module named `{}` to be Codegened but is Reused",
- mname));
+ user_path));
}
(Disposition::Reused, true) |
(Disposition::Codegened, false) => {
@@ -99,7 +124,19 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
}
}
} else {
- self.tcx.sess.span_err(attr.span, &format!("no module named `{}`", mname));
+ let available_cgus = self.tcx
+ .collect_and_partition_mono_items(LOCAL_CRATE)
+ .1
+ .iter()
+ .map(|cgu| format!("{}", cgu.name()))
+ .collect::<Vec<String>>()
+ .join(", ");
+
+ self.tcx.sess.span_err(attr.span,
+ &format!("no module named `{}` (mangled: {}).\nAvailable modules: {}",
+ user_path,
+ cgu_name,
+ available_cgus));
}
}
diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs
index 2ef88041d33..10efa1a2870 100644
--- a/src/librustc_incremental/lib.rs
+++ b/src/librustc_incremental/lib.rs
@@ -44,6 +44,7 @@ pub use persist::copy_cgu_workproducts_to_incr_comp_cache_dir;
pub use persist::save_dep_graph;
pub use persist::save_work_product_index;
pub use persist::in_incr_comp_dir;
+pub use persist::in_incr_comp_dir_sess;
pub use persist::prepare_session_directory;
pub use persist::finalize_session_directory;
pub use persist::delete_workproduct_files;
diff --git a/src/librustc_incremental/persist/mod.rs b/src/librustc_incremental/persist/mod.rs
index e1f00db56d5..17d36ba3fa7 100644
--- a/src/librustc_incremental/persist/mod.rs
+++ b/src/librustc_incremental/persist/mod.rs
@@ -23,6 +23,7 @@ mod file_format;
pub use self::fs::finalize_session_directory;
pub use self::fs::garbage_collect_session_directories;
pub use self::fs::in_incr_comp_dir;
+pub use self::fs::in_incr_comp_dir_sess;
pub use self::fs::prepare_session_directory;
pub use self::load::dep_graph_tcx_init;
pub use self::load::load_dep_graph;
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index 0497de940ca..551f1cda6f0 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -350,6 +350,10 @@ pub enum ThinLTOData {}
/// LLVMRustThinLTOBuffer
pub enum ThinLTOBuffer {}
+// LLVMRustModuleNameCallback
+pub type ThinLTOModuleNameCallback =
+ unsafe extern "C" fn(*mut c_void, *const c_char, *const c_char);
+
/// LLVMRustThinLTOModule
#[repr(C)]
pub struct ThinLTOModule {
@@ -1778,6 +1782,11 @@ extern "C" {
Data: *const ThinLTOData,
Module: ModuleRef,
) -> bool;
+ pub fn LLVMRustGetThinLTOModuleImports(
+ Data: *const ThinLTOData,
+ ModuleNameCallback: ThinLTOModuleNameCallback,
+ CallbackPayload: *mut c_void,
+ );
pub fn LLVMRustFreeThinLTOData(Data: *mut ThinLTOData);
pub fn LLVMRustParseBitcodeForThinLTO(
Context: ContextRef,
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index 5f15870d6fb..73b430bc041 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -104,7 +104,7 @@
use monomorphize::collector::InliningMap;
use rustc::dep_graph::WorkProductId;
-use rustc::hir::def_id::DefId;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::hir::map::DefPathData;
use rustc::mir::mono::{Linkage, Visibility};
use rustc::middle::exported_symbols::SymbolExportLevel;
@@ -114,7 +114,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet};
use std::collections::hash_map::Entry;
use std::cmp;
use syntax::ast::NodeId;
-use syntax::symbol::{Symbol, InternedString};
+use syntax::symbol::InternedString;
use rustc::mir::mono::MonoItem;
use monomorphize::item::{MonoItemExt, InstantiationMode};
@@ -204,16 +204,9 @@ impl<'tcx> CodegenUnitExt<'tcx> for CodegenUnit<'tcx> {
// Anything we can't find a proper codegen unit for goes into this.
fn fallback_cgu_name(tcx: TyCtxt) -> InternedString {
- const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";
-
- if tcx.sess.opts.debugging_opts.human_readable_cgu_names {
- Symbol::intern(FALLBACK_CODEGEN_UNIT).as_interned_str()
- } else {
- Symbol::intern(&CodegenUnit::mangle_name(FALLBACK_CODEGEN_UNIT)).as_interned_str()
- }
+ CodegenUnit::build_cgu_name(tcx, LOCAL_CRATE, &["fallback"], Some("cgu"))
}
-
pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mono_items: I,
strategy: PartitioningStrategy,
@@ -224,8 +217,7 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// In the first step, we place all regular monomorphizations into their
// respective 'home' codegen unit. Regular monomorphizations are all
// functions and statics defined in the local crate.
- let mut initial_partitioning = place_root_mono_items(tcx,
- mono_items);
+ let mut initial_partitioning = place_root_mono_items(tcx, mono_items);
initial_partitioning.codegen_units.iter_mut().for_each(|cgu| cgu.estimate_size(&tcx));
@@ -234,7 +226,7 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// If the partitioning should produce a fixed count of codegen units, merge
// until that count is reached.
if let PartitioningStrategy::FixedUnitCount(count) = strategy {
- merge_codegen_units(&mut initial_partitioning, count, &tcx.crate_name.as_str());
+ merge_codegen_units(tcx, &mut initial_partitioning, count);
debug_dump(tcx, "POST MERGING:", initial_partitioning.codegen_units.iter());
}
@@ -328,7 +320,7 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
};
let codegen_unit = codegen_units.entry(codegen_unit_name.clone())
- .or_insert_with(make_codegen_unit);
+ .or_insert_with(make_codegen_unit);
let mut can_be_internalized = true;
let default_visibility = |id: DefId, is_generic: bool| {
@@ -491,9 +483,9 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
-fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<'tcx>,
- target_cgu_count: usize,
- crate_name: &str) {
+fn merge_codegen_units<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>,
+ initial_partitioning: &mut PreInliningPartitioning<'tcx>,
+ target_cgu_count: usize) {
assert!(target_cgu_count >= 1);
let codegen_units = &mut initial_partitioning.codegen_units;
@@ -522,7 +514,7 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<
}
for (index, cgu) in codegen_units.iter_mut().enumerate() {
- cgu.set_name(numbered_codegen_unit_name(crate_name, index));
+ cgu.set_name(numbered_codegen_unit_name(tcx, index));
}
}
@@ -727,42 +719,26 @@ fn compute_codegen_unit_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId,
volatile: bool)
-> InternedString {
- // Unfortunately we cannot just use the `ty::item_path` infrastructure here
- // because we need paths to modules and the DefIds of those are not
- // available anymore for external items.
- let mut cgu_name = String::with_capacity(64);
-
let def_path = tcx.def_path(def_id);
- cgu_name.push_str(&tcx.crate_name(def_path.krate).as_str());
-
- for part in tcx.def_path(def_id)
- .data
- .iter()
- .take_while(|part| {
- match part.data {
- DefPathData::Module(..) => true,
- _ => false,
- }
- }) {
- cgu_name.push_str("-");
- cgu_name.push_str(&part.data.as_interned_str().as_str());
- }
- if volatile {
- cgu_name.push_str(".volatile");
- }
+ let components = def_path.data.iter().take_while(|part| {
+ match part.data {
+ DefPathData::Module(..) => true,
+ _ => false,
+ }
+ }).map(|part| part.data.as_interned_str());
- let cgu_name = if tcx.sess.opts.debugging_opts.human_readable_cgu_names {
- cgu_name
+ let volatile_suffix = if volatile {
+ Some("volatile")
} else {
- CodegenUnit::mangle_name(&cgu_name)
+ None
};
- Symbol::intern(&cgu_name[..]).as_interned_str()
+ CodegenUnit::build_cgu_name(tcx, def_path.krate, components, volatile_suffix)
}
-fn numbered_codegen_unit_name(crate_name: &str, index: usize) -> InternedString {
- Symbol::intern(&format!("{}{}", crate_name, index)).as_interned_str()
+fn numbered_codegen_unit_name(tcx: TyCtxt, index: usize) -> InternedString {
+ CodegenUnit::build_cgu_name_no_mangle(tcx, LOCAL_CRATE, &["cgu"], Some(index))
}
fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index a00ff3b345d..1f96b9042ba 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -1099,6 +1099,30 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
return true;
}
+extern "C" typedef void (*LLVMRustModuleNameCallback)(void*, // payload
+ const char*, // importing module name
+ const char*); // imported module name
+
+// Calls `module_name_callback` for each module import done by ThinLTO.
+// The callback is provided with regular null-terminated C strings.
+extern "C" void
+LLVMRustGetThinLTOModuleImports(const LLVMRustThinLTOData *data,
+ LLVMRustModuleNameCallback module_name_callback,
+ void* callback_payload) {
+ for (const auto& importing_module : data->ImportLists) {
+ const std::string importing_module_id = importing_module.getKey().str();
+
+ const auto& imports = importing_module.getValue();
+
+ for (const auto& imported_module : imports) {
+ const std::string imported_module_id = imported_module.getKey().str();
+ module_name_callback(callback_payload,
+ importing_module_id.c_str(),
+ imported_module_id.c_str());
+ }
+ }
+}
+
// This struct and various functions are sort of a hack right now, but the
// problem is that we've got in-memory LLVM modules after we generate and
// optimize all codegen-units for one compilation in rustc. To be compatible
@@ -1280,6 +1304,11 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
report_fatal_error("ThinLTO not available");
}
+extern "C" LLVMRustThinLTOModuleImports
+LLVMRustGetLLVMRustThinLTOModuleImports(const LLVMRustThinLTOData *Data) {
+ report_fatal_error("ThinLTO not available");
+}
+
extern "C" void
LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
report_fatal_error("ThinLTO not available");
diff --git a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
index 49e4b8d43c1..cec88f1c6a2 100644
--- a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
+++ b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
@@ -14,7 +14,7 @@
#![feature(start)]
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<drop_in_place_intrinsic::StructWithDtor[0]> @@ drop_in_place_intrinsic0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<drop_in_place_intrinsic::StructWithDtor[0]> @@ drop_in_place_intrinsic-cgu.0[Internal]
struct StructWithDtor(u32);
impl Drop for StructWithDtor {
@@ -26,7 +26,7 @@ impl Drop for StructWithDtor {
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal]
let x = [StructWithDtor(0), StructWithDtor(1)];
drop_slice_in_place(&x);
@@ -40,7 +40,7 @@ fn drop_slice_in_place(x: &[StructWithDtor]) {
// This is the interesting thing in this test case: Normally we would
// not have drop-glue for the unsized [StructWithDtor]. This has to be
// generated though when the drop_in_place() intrinsic is used.
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal]
::std::ptr::drop_in_place(x as *const _ as *mut [StructWithDtor]);
}
}
diff --git a/src/test/codegen-units/item-collection/generic-drop-glue.rs b/src/test/codegen-units/item-collection/generic-drop-glue.rs
index aad32d1eb7c..5afa519bc59 100644
--- a/src/test/codegen-units/item-collection/generic-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/generic-drop-glue.rs
@@ -47,7 +47,7 @@ enum EnumNoDrop<T1, T2> {
struct NonGenericNoDrop(i32);
struct NonGenericWithDrop(i32);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::NonGenericWithDrop[0]> @@ generic_drop_glue0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::NonGenericWithDrop[0]> @@ generic_drop_glue-cgu.0[Internal]
impl Drop for NonGenericWithDrop {
//~ MONO_ITEM fn generic_drop_glue::{{impl}}[2]::drop[0]
@@ -57,11 +57,11 @@ impl Drop for NonGenericWithDrop {
//~ MONO_ITEM fn generic_drop_glue::start[0]
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<i8, char>> @@ generic_drop_glue0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<i8, char>> @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<i8, char>
let _ = StructWithDrop { x: 0i8, y: 'a' }.x;
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>> @@ generic_drop_glue0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>> @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>
let _ = StructWithDrop { x: "&str", y: NonGenericNoDrop(0) }.y;
@@ -70,17 +70,17 @@ fn start(_: isize, _: *const *const u8) -> isize {
// This is supposed to generate drop-glue because it contains a field that
// needs to be dropped.
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructNoDrop[0]<generic_drop_glue::NonGenericWithDrop[0], f64>> @@ generic_drop_glue0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructNoDrop[0]<generic_drop_glue::NonGenericWithDrop[0], f64>> @@ generic_drop_glue-cgu.0[Internal]
let _ = StructNoDrop { x: NonGenericWithDrop(0), y: 0f64 }.y;
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<i32, i64>> @@ generic_drop_glue0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<i32, i64>> @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<i32, i64>
let _ = match EnumWithDrop::A::<i32, i64>(0) {
EnumWithDrop::A(x) => x,
EnumWithDrop::B(x) => x as i32
};
- //~MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<f64, f32>> @@ generic_drop_glue0[Internal]
+ //~MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<f64, f32>> @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<f64, f32>
let _ = match EnumWithDrop::B::<f64, f32>(1.0) {
EnumWithDrop::A(x) => x,
diff --git a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
index 5c6201da252..d09d343a845 100644
--- a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
+++ b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
@@ -34,13 +34,13 @@ impl<T> Trait for Struct<T> {
fn start(_: isize, _: *const *const u8) -> isize {
let s1 = Struct { _a: 0u32 };
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u32>> @@ instantiation_through_vtable0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u32>> @@ instantiation_through_vtable-cgu.0[Internal]
//~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u32>
//~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u32>
let _ = &s1 as &Trait;
let s1 = Struct { _a: 0u64 };
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u64>> @@ instantiation_through_vtable0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u64>> @@ instantiation_through_vtable-cgu.0[Internal]
//~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u64>
//~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u64>
let _ = &s1 as &Trait;
diff --git a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
index 6ca24aa5b4b..a939dd56cda 100644
--- a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
@@ -15,7 +15,7 @@
#![deny(dead_code)]
#![feature(start)]
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::StructWithDrop[0]> @@ non_generic_drop_glue0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::StructWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
struct StructWithDrop {
x: i32
}
@@ -29,7 +29,7 @@ struct StructNoDrop {
x: i32
}
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::EnumWithDrop[0]> @@ non_generic_drop_glue0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::EnumWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
enum EnumWithDrop {
A(i32)
}
diff --git a/src/test/codegen-units/item-collection/transitive-drop-glue.rs b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
index d20213c109b..7bbc9b6d0fb 100644
--- a/src/test/codegen-units/item-collection/transitive-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
@@ -15,11 +15,11 @@
#![deny(dead_code)]
#![feature(start)]
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Root[0]> @@ transitive_drop_glue0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Root[0]> @@ transitive_drop_glue-cgu.0[Internal]
struct Root(Intermediate);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Intermediate[0]> @@ transitive_drop_glue0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Intermediate[0]> @@ transitive_drop_glue-cgu.0[Internal]
struct Intermediate(Leaf);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Leaf[0]> @@ transitive_drop_glue0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Leaf[0]> @@ transitive_drop_glue-cgu.0[Internal]
struct Leaf;
impl Drop for Leaf {
@@ -40,15 +40,15 @@ impl<T> Drop for LeafGen<T> {
fn start(_: isize, _: *const *const u8) -> isize {
let _ = Root(Intermediate(Leaf));
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<u32>> @@ transitive_drop_glue0[Internal]
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<u32>> @@ transitive_drop_glue0[Internal]
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<u32>> @@ transitive_drop_glue0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<u32>
let _ = RootGen(IntermediateGen(LeafGen(0u32)));
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<i16>> @@ transitive_drop_glue0[Internal]
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<i16>> @@ transitive_drop_glue0[Internal]
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<i16>> @@ transitive_drop_glue0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<i16>
let _ = RootGen(IntermediateGen(LeafGen(0i16)));
diff --git a/src/test/codegen-units/item-collection/tuple-drop-glue.rs b/src/test/codegen-units/item-collection/tuple-drop-glue.rs
index 9e4cc6ea6f0..865570ccfa5 100644
--- a/src/test/codegen-units/item-collection/tuple-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/tuple-drop-glue.rs
@@ -15,7 +15,7 @@
#![deny(dead_code)]
#![feature(start)]
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<tuple_drop_glue::Dropped[0]> @@ tuple_drop_glue0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<tuple_drop_glue::Dropped[0]> @@ tuple_drop_glue-cgu.0[Internal]
struct Dropped;
impl Drop for Dropped {
@@ -26,11 +26,11 @@ impl Drop for Dropped {
//~ MONO_ITEM fn tuple_drop_glue::start[0]
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal]
let x = (0u32, Dropped);
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue0[Internal]
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal]
let x = (0i16, (Dropped, true));
0
diff --git a/src/test/codegen-units/item-collection/unsizing.rs b/src/test/codegen-units/item-collection/unsizing.rs
index adc0eb6c709..5e9a3258c7a 100644
--- a/src/test/codegen-units/item-collection/unsizing.rs
+++ b/src/test/codegen-units/item-collection/unsizing.rs
@@ -59,13 +59,13 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Wrapper<U>> for Wrapper<T>
fn start(_: isize, _: *const *const u8) -> isize {
// simple case
let bool_sized = &true;
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<bool> @@ unsizing0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<bool> @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn unsizing::{{impl}}[0]::foo[0]
let _bool_unsized = bool_sized as &Trait;
let char_sized = &'a';
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<char> @@ unsizing0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<char> @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn unsizing::{{impl}}[1]::foo[0]
let _char_unsized = char_sized as &Trait;
@@ -75,13 +75,13 @@ fn start(_: isize, _: *const *const u8) -> isize {
_b: 2,
_c: 3.0f64
};
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<f64> @@ unsizing0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<f64> @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn unsizing::{{impl}}[2]::foo[0]
let _struct_unsized = struct_sized as &Struct<Trait>;
// custom coercion
let wrapper_sized = Wrapper(&0u32);
- //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ unsizing0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn unsizing::{{impl}}[3]::foo[0]
let _wrapper_sized = wrapper_sized as Wrapper<Trait>;
diff --git a/src/test/incremental/issue-39828/auxiliary/generic.rs b/src/test/incremental/issue-39828/auxiliary/generic.rs
index a562eab1768..5491827af8a 100644
--- a/src/test/incremental/issue-39828/auxiliary/generic.rs
+++ b/src/test/incremental/issue-39828/auxiliary/generic.rs
@@ -11,7 +11,7 @@
// revisions:rpass1 rpass2
// compile-flags: -Z query-dep-graph
-#![rustc_partition_reused(module="__rustc_fallback_codegen_unit", cfg="rpass2")]
+#![rustc_partition_reused(module="generic-fallback.cgu", cfg="rpass2")]
#![feature(rustc_attrs)]
#![crate_type="rlib"]
diff --git a/src/test/run-make-fulldeps/cross-lang-lto/Makefile b/src/test/run-make-fulldeps/cross-lang-lto/Makefile
index efe1b7072ff..dbd0116e5e3 100644
--- a/src/test/run-make-fulldeps/cross-lang-lto/Makefile
+++ b/src/test/run-make-fulldeps/cross-lang-lto/Makefile
@@ -17,22 +17,22 @@ all: staticlib staticlib-fat-lto staticlib-thin-lto rlib exe cdylib rdylib
staticlib: lib.rs
$(BUILD_LIB) --crate-type=staticlib -o $(TMPDIR)/liblib.a
$(call EXTRACT_OBJS, liblib.a)
- $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/liblib.lib0.rcgu.o
+ for file in $(TMPDIR)/liblib.*.rcgu.o; do $(ASSERT_IS_BITCODE_OBJ) $$file; done
staticlib-fat-lto: lib.rs
$(BUILD_LIB) --crate-type=staticlib -o $(TMPDIR)/liblib-fat-lto.a -Clto=fat
$(call EXTRACT_OBJS, liblib-fat-lto.a)
- $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/liblib-fat-lto.lib0.rcgu.o
+ for file in $(TMPDIR)/liblib-fat-lto.*.rcgu.o; do $(ASSERT_IS_BITCODE_OBJ) $$file; done
staticlib-thin-lto: lib.rs
$(BUILD_LIB) --crate-type=staticlib -o $(TMPDIR)/liblib-thin-lto.a -Clto=thin
$(call EXTRACT_OBJS, liblib-thin-lto.a)
- $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/liblib-thin-lto.lib0.rcgu.o
+ for file in $(TMPDIR)/liblib-thin-lto.*.rcgu.o; do $(ASSERT_IS_BITCODE_OBJ) $$file; done
rlib: lib.rs
$(BUILD_LIB) --crate-type=rlib -o $(TMPDIR)/liblib.rlib
$(call EXTRACT_OBJS, liblib.rlib)
- $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/liblib.lib0.rcgu.o
+ for file in $(TMPDIR)/liblib.*.rcgu.o; do $(ASSERT_IS_BITCODE_OBJ) $$file; done
cdylib: lib.rs
$(BUILD_LIB) --crate-type=cdylib --emit=obj -o $(TMPDIR)/cdylib.o
diff --git a/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile b/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile
index 6de4f97df0c..e46390a9d0c 100644
--- a/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile
+++ b/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile
@@ -2,5 +2,5 @@
all:
$(RUSTC) -C extra-filename=bar foo.rs -C save-temps
- rm $(TMPDIR)/foobar.foo0.rcgu.o
+ rm $(TMPDIR)/foobar.foo*0.rcgu.o
rm $(TMPDIR)/$(call BIN,foobar)
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 59ddc16715d..e5fb472afd6 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2209,12 +2209,12 @@ impl<'test> TestCx<'test> {
.stdout
.lines()
.filter(|line| line.starts_with(PREFIX))
- .map(str_to_mono_item)
+ .map(|line| str_to_mono_item(line, true))
.collect();
let expected: Vec<MonoItem> = errors::load_errors(&self.testpaths.file, None)
.iter()
- .map(|e| str_to_mono_item(&e.msg[..]))
+ .map(|e| str_to_mono_item(&e.msg[..], false))
.collect();
let mut missing = Vec::new();
@@ -2299,14 +2299,14 @@ impl<'test> TestCx<'test> {
}
// [MONO_ITEM] name [@@ (cgu)+]
- fn str_to_mono_item(s: &str) -> MonoItem {
+ fn str_to_mono_item(s: &str, cgu_has_crate_disambiguator: bool) -> MonoItem {
let s = if s.starts_with(PREFIX) {
(&s[PREFIX.len()..]).trim()
} else {
s.trim()
};
- let full_string = format!("{}{}", PREFIX, s.trim().to_owned());
+ let full_string = format!("{}{}", PREFIX, s);
let parts: Vec<&str> = s
.split(CGU_MARKER)
@@ -2323,7 +2323,13 @@ impl<'test> TestCx<'test> {
.split(' ')
.map(str::trim)
.filter(|s| !s.is_empty())
- .map(str::to_owned)
+ .map(|s| {
+ if cgu_has_crate_disambiguator {
+ remove_crate_disambiguator_from_cgu(s)
+ } else {
+ s.to_string()
+ }
+ })
.collect()
} else {
HashSet::new()
@@ -2348,6 +2354,23 @@ impl<'test> TestCx<'test> {
string
}
+
+ fn remove_crate_disambiguator_from_cgu(cgu: &str) -> String {
+ // The first '.' is the start of the crate disambiguator
+ let disambiguator_start = cgu.find('.')
+ .expect("Could not find start of crate disambiguator in CGU spec");
+
+ // The first non-alphanumeric character is the end of the disambiguator
+ let disambiguator_end = cgu[disambiguator_start + 1 ..]
+ .find(|c| !char::is_alphanumeric(c))
+ .expect("Could not find end of crate disambiguator in CGU spec")
+ + disambiguator_start + 1;
+
+ let mut result = cgu[0 .. disambiguator_start].to_string();
+ result.push_str(&cgu[disambiguator_end ..]);
+
+ result
+ }
}
fn init_incremental_test(&self) {