Revert "Clean up CodegenUnit name generation."

This reverts commit 2c5cd9ce53.
This commit is contained in:
Michael Woerister 2018-07-16 08:58:40 +02:00
parent 0830cc92bd
commit 6064efe928
5 changed files with 57 additions and 154 deletions

View File

@ -8,16 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use hir::def_id::{DefId, CrateNum};
use hir::def_id::DefId;
use syntax::ast::NodeId;
use syntax::symbol::{Symbol, InternedString};
use syntax::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)]
@ -174,80 +173,6 @@ 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> {

View File

@ -26,7 +26,6 @@ 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;
@ -1186,14 +1185,6 @@ 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)

View File

@ -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,37 +72,12 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
return;
}
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 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 dep_node = DepNode::new(self.tcx,
DepConstructor::CompileCodegenUnit(cgu_name));
DepConstructor::CompileCodegenUnit(mangled_cgu_name));
if let Some(loaded_from_cache) = self.tcx.dep_graph.was_loaded_from_cache(&dep_node) {
match (disposition, loaded_from_cache) {
@ -110,13 +85,13 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
self.tcx.sess.span_err(
attr.span,
&format!("expected module named `{}` to be Reused but is Codegened",
user_path));
mname));
}
(Disposition::Codegened, true) => {
self.tcx.sess.span_err(
attr.span,
&format!("expected module named `{}` to be Codegened but is Reused",
user_path));
mname));
}
(Disposition::Reused, true) |
(Disposition::Codegened, false) => {
@ -124,19 +99,7 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
}
}
} else {
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));
self.tcx.sess.span_err(attr.span, &format!("no module named `{}`", mname));
}
}

View File

@ -104,7 +104,7 @@
use monomorphize::collector::InliningMap;
use rustc::dep_graph::WorkProductId;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::hir::def_id::DefId;
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::InternedString;
use syntax::symbol::{Symbol, InternedString};
use rustc::mir::mono::MonoItem;
use monomorphize::item::{MonoItemExt, InstantiationMode};
@ -204,9 +204,16 @@ 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 {
CodegenUnit::build_cgu_name(tcx, LOCAL_CRATE, &["fallback"], Some("cgu"))
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()
}
}
pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mono_items: I,
strategy: PartitioningStrategy,
@ -217,7 +224,8 @@ 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));
@ -226,7 +234,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(tcx, &mut initial_partitioning, count);
merge_codegen_units(&mut initial_partitioning, count, &tcx.crate_name.as_str());
debug_dump(tcx, "POST MERGING:", initial_partitioning.codegen_units.iter());
}
@ -320,7 +328,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| {
@ -483,9 +491,9 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
fn merge_codegen_units<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>,
initial_partitioning: &mut PreInliningPartitioning<'tcx>,
target_cgu_count: usize) {
fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<'tcx>,
target_cgu_count: usize,
crate_name: &str) {
assert!(target_cgu_count >= 1);
let codegen_units = &mut initial_partitioning.codegen_units;
@ -514,7 +522,7 @@ fn merge_codegen_units<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>,
}
for (index, cgu) in codegen_units.iter_mut().enumerate() {
cgu.set_name(numbered_codegen_unit_name(tcx, index));
cgu.set_name(numbered_codegen_unit_name(crate_name, index));
}
}
@ -719,26 +727,42 @@ 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());
let components = def_path.data.iter().take_while(|part| {
match part.data {
DefPathData::Module(..) => true,
_ => false,
}
}).map(|part| part.data.as_interned_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());
}
let volatile_suffix = if volatile {
Some("volatile")
if volatile {
cgu_name.push_str(".volatile");
}
let cgu_name = if tcx.sess.opts.debugging_opts.human_readable_cgu_names {
cgu_name
} else {
None
CodegenUnit::mangle_name(&cgu_name)
};
CodegenUnit::build_cgu_name(tcx, def_path.krate, components, volatile_suffix)
Symbol::intern(&cgu_name[..]).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 numbered_codegen_unit_name(crate_name: &str, index: usize) -> InternedString {
Symbol::intern(&format!("{}{}", crate_name, index)).as_interned_str()
}
fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

View File

@ -11,7 +11,7 @@
// revisions:rpass1 rpass2
// compile-flags: -Z query-dep-graph
#![rustc_partition_reused(module="generic-fallback.cgu", cfg="rpass2")]
#![rustc_partition_reused(module="__rustc_fallback_codegen_unit", cfg="rpass2")]
#![feature(rustc_attrs)]
#![crate_type="rlib"]