Skip to content

Some preparatory refactorings for hash-based DepNodes #42504

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 12 additions & 18 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
// except according to those terms.

use hir::def_id::CrateNum;
use ich::Fingerprint;
use rustc_data_structures::stable_hasher::StableHasher;
use std::fmt::Debug;
use std::sync::Arc;
use std::hash::Hash;

macro_rules! try_opt {
($e:expr) => (
Expand Down Expand Up @@ -51,12 +53,9 @@ pub enum DepNode<D: Clone + Debug> {
/// in an extern crate.
MetaData(D),

/// Represents some piece of metadata global to its crate.
GlobalMetaData(D, GlobalMetaDataKind),

/// Represents some artifact that we save to disk. Note that these
/// do not have a def-id as part of their identifier.
WorkProduct(Arc<WorkProductId>),
WorkProduct(WorkProductId),

// Represents different phases in the compiler.
RegionMaps(D),
Expand Down Expand Up @@ -307,7 +306,6 @@ impl<D: Clone + Debug> DepNode<D> {
ItemBodyNestedBodies(ref d) => op(d).map(ItemBodyNestedBodies),
ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic),
IsMirAvailable(ref d) => op(d).map(IsMirAvailable),
GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)),
}
}
}
Expand All @@ -318,17 +316,13 @@ impl<D: Clone + Debug> DepNode<D> {
/// the need to be mapped or unmapped. (This ensures we can serialize
/// them even in the absence of a tcx.)
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct WorkProductId(pub String);
pub struct WorkProductId(pub Fingerprint);

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub enum GlobalMetaDataKind {
Krate,
CrateDeps,
DylibDependencyFormats,
LangItems,
LangItemsMissing,
NativeLibraries,
CodeMap,
Impls,
ExportedSymbols,
impl WorkProductId {
pub fn from_cgu_name(cgu_name: &str) -> WorkProductId {
let mut hasher = StableHasher::new();
cgu_name.len().hash(&mut hasher);
cgu_name.hash(&mut hasher);
WorkProductId(hasher.finish())
}
}
15 changes: 7 additions & 8 deletions src/librustc/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use rustc_data_structures::fx::FxHashMap;
use session::config::OutputType;
use std::cell::{Ref, RefCell};
use std::rc::Rc;
use std::sync::Arc;

use super::dep_node::{DepNode, WorkProductId};
use super::query::DepGraphQuery;
Expand All @@ -35,10 +34,10 @@ struct DepGraphData {
/// things available to us. If we find that they are not dirty, we
/// load the path to the file storing those work-products here into
/// this map. We can later look for and extract that data.
previous_work_products: RefCell<FxHashMap<Arc<WorkProductId>, WorkProduct>>,
previous_work_products: RefCell<FxHashMap<WorkProductId, WorkProduct>>,

/// Work-products that we generate in this run.
work_products: RefCell<FxHashMap<Arc<WorkProductId>, WorkProduct>>,
work_products: RefCell<FxHashMap<WorkProductId, WorkProduct>>,
}

impl DepGraph {
Expand Down Expand Up @@ -120,7 +119,7 @@ impl DepGraph {
/// Indicates that a previous work product exists for `v`. This is
/// invoked during initial start-up based on what nodes are clean
/// (and what files exist in the incr. directory).
pub fn insert_previous_work_product(&self, v: &Arc<WorkProductId>, data: WorkProduct) {
pub fn insert_previous_work_product(&self, v: &WorkProductId, data: WorkProduct) {
debug!("insert_previous_work_product({:?}, {:?})", v, data);
self.data.previous_work_products.borrow_mut()
.insert(v.clone(), data);
Expand All @@ -129,29 +128,29 @@ impl DepGraph {
/// Indicates that we created the given work-product in this run
/// for `v`. This record will be preserved and loaded in the next
/// run.
pub fn insert_work_product(&self, v: &Arc<WorkProductId>, data: WorkProduct) {
pub fn insert_work_product(&self, v: &WorkProductId, data: WorkProduct) {
debug!("insert_work_product({:?}, {:?})", v, data);
self.data.work_products.borrow_mut()
.insert(v.clone(), data);
}

/// Check whether a previous work product exists for `v` and, if
/// so, return the path that leads to it. Used to skip doing work.
pub fn previous_work_product(&self, v: &Arc<WorkProductId>) -> Option<WorkProduct> {
pub fn previous_work_product(&self, v: &WorkProductId) -> Option<WorkProduct> {
self.data.previous_work_products.borrow()
.get(v)
.cloned()
}

/// Access the map of work-products created during this run. Only
/// used during saving of the dep-graph.
pub fn work_products(&self) -> Ref<FxHashMap<Arc<WorkProductId>, WorkProduct>> {
pub fn work_products(&self) -> Ref<FxHashMap<WorkProductId, WorkProduct>> {
self.data.work_products.borrow()
}

/// Access the map of work-products created during the cached run. Only
/// used during saving of the dep-graph.
pub fn previous_work_products(&self) -> Ref<FxHashMap<Arc<WorkProductId>, WorkProduct>> {
pub fn previous_work_products(&self) -> Ref<FxHashMap<WorkProductId, WorkProduct>> {
self.data.previous_work_products.borrow()
}
}
Expand Down
1 change: 0 additions & 1 deletion src/librustc/dep_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ mod thread;
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
pub use self::dep_node::DepNode;
pub use self::dep_node::WorkProductId;
pub use self::dep_node::GlobalMetaDataKind;
pub use self::graph::DepGraph;
pub use self::graph::WorkProduct;
pub use self::query::DepGraphQuery;
Expand Down
118 changes: 106 additions & 12 deletions src/librustc/hir/map/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
//! expressions) that are mostly just leftovers.

use hir;
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace};
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace,
CRATE_DEF_INDEX};
use ich::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::IndexVec;
Expand Down Expand Up @@ -396,6 +397,11 @@ pub enum DefPathData {
ImplTrait,
/// A `typeof` type node.
Typeof,

/// GlobalMetaData identifies a piece of crate metadata that is global to
/// a whole crate (as opposed to just one item). GlobalMetaData components
/// are only supposed to show up right below the crate root.
GlobalMetaData(Ident)
}

#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
Expand Down Expand Up @@ -427,8 +433,8 @@ impl Definitions {

/// Get the number of definitions.
pub fn def_index_counts_lo_hi(&self) -> (usize, usize) {
(self.def_index_to_node[DefIndexAddressSpace::Low.index()].len(),
self.def_index_to_node[DefIndexAddressSpace::High.index()].len())
(self.table.index_to_key[DefIndexAddressSpace::Low.index()].len(),
self.table.index_to_key[DefIndexAddressSpace::High.index()].len())
}

pub fn def_key(&self, index: DefIndex) -> DefKey {
Expand Down Expand Up @@ -469,7 +475,12 @@ impl Definitions {
if def_id.krate == LOCAL_CRATE {
let space_index = def_id.index.address_space().index();
let array_index = def_id.index.as_array_index();
Some(self.def_index_to_node[space_index][array_index])
let node_id = self.def_index_to_node[space_index][array_index];
if node_id != ast::DUMMY_NODE_ID {
Some(node_id)
} else {
None
}
} else {
None
}
Expand Down Expand Up @@ -498,12 +509,16 @@ impl Definitions {

// Create the definition.
let address_space = super::ITEM_LIKE_SPACE;
let index = self.table.allocate(key, def_path_hash, address_space);
let root_index = self.table.allocate(key, def_path_hash, address_space);
assert_eq!(root_index, CRATE_DEF_INDEX);
assert!(self.def_index_to_node[address_space.index()].is_empty());
self.def_index_to_node[address_space.index()].push(ast::CRATE_NODE_ID);
self.node_to_def_index.insert(ast::CRATE_NODE_ID, index);
self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index);

index
// Allocate some other DefIndices that always must exist.
GlobalMetaDataKind::allocate_def_indices(self);

root_index
}

/// Add a definition with a parent definition.
Expand Down Expand Up @@ -550,13 +565,19 @@ impl Definitions {
assert_eq!(index.as_array_index(),
self.def_index_to_node[address_space.index()].len());
self.def_index_to_node[address_space.index()].push(node_id);

// Some things for which we allocate DefIndices don't correspond to
// anything in the AST, so they don't have a NodeId. For these cases
// we don't need a mapping from NodeId to DefIndex.
if node_id != ast::DUMMY_NODE_ID {
debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
self.node_to_def_index.insert(node_id, index);
}

if expansion.is_modern() {
self.expansions.insert(index, expansion);
}

debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
self.node_to_def_index.insert(node_id, index);

index
}

Expand Down Expand Up @@ -594,7 +615,8 @@ impl DefPathData {
LifetimeDef(ident) |
EnumVariant(ident) |
Binding(ident) |
Field(ident) => Some(ident),
Field(ident) |
GlobalMetaData(ident) => Some(ident),

Impl |
CrateRoot |
Expand Down Expand Up @@ -622,7 +644,8 @@ impl DefPathData {
LifetimeDef(ident) |
EnumVariant(ident) |
Binding(ident) |
Field(ident) => {
Field(ident) |
GlobalMetaData(ident) => {
return ident.name.as_str();
}

Expand Down Expand Up @@ -667,3 +690,74 @@ impl ::std::hash::Hash for DefPathData {
}
}
}


// We define the GlobalMetaDataKind enum with this macro because we want to
// make sure that we exhaustively iterate over all variants when registering
// the corresponding DefIndices in the DefTable.
macro_rules! define_global_metadata_kind {
(pub enum GlobalMetaDataKind {
$($variant:ident),*
}) => (
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
RustcEncodable, RustcDecodable)]
pub enum GlobalMetaDataKind {
$($variant),*
}

impl GlobalMetaDataKind {
fn allocate_def_indices(definitions: &mut Definitions) {
$({
let instance = GlobalMetaDataKind::$variant;
definitions.create_def_with_parent(
CRATE_DEF_INDEX,
ast::DUMMY_NODE_ID,
DefPathData::GlobalMetaData(instance.ident()),
DefIndexAddressSpace::High,
Mark::root()
);

// Make sure calling def_index does not crash.
instance.def_index(&definitions.table);
})*
}

pub fn def_index(&self, def_path_table: &DefPathTable) -> DefIndex {
let def_key = DefKey {
parent: Some(CRATE_DEF_INDEX),
disambiguated_data: DisambiguatedDefPathData {
data: DefPathData::GlobalMetaData(self.ident()),
disambiguator: 0,
}
};

def_path_table.key_to_index[&def_key]
}

fn ident(&self) -> Ident {

let string = match *self {
$(
GlobalMetaDataKind::$variant => {
concat!("{{GlobalMetaData::", stringify!($variant), "}}")
}
)*
};

Ident::from_str(string)
}
}
)
}

define_global_metadata_kind!(pub enum GlobalMetaDataKind {
Krate,
CrateDeps,
DylibDependencyFormats,
LangItems,
LangItemsMissing,
NativeLibraries,
CodeMap,
Impls,
ExportedSymbols
});
4 changes: 2 additions & 2 deletions src/librustc/ich/caching_codemap_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ pub struct CachingCodemapView<'tcx> {
time_stamp: usize,
}

impl<'tcx> CachingCodemapView<'tcx> {
pub fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> {
impl<'gcx> CachingCodemapView<'gcx> {
pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> CachingCodemapView<'gcx> {
let codemap = tcx.sess.codemap();
let files = codemap.files();
let first_file = files[0].clone();
Expand Down
Loading