Skip to content

Commit

Permalink
Turn HIR indexing into a query
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Mar 15, 2019
1 parent 7115263 commit 30e23f6
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 52 deletions.
1 change: 1 addition & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ define_dep_nodes!( <'tcx>
[eval_always] PrivacyAccessLevels(CrateNum),
[eval_always] CheckPrivateInPublic(CrateNum),
[eval_always] Analysis(CrateNum),
[eval_always] HirMap(CrateNum),

// Represents the MIR for a fn; also used as the task node for
// things read/modify that MIR.
Expand Down
2 changes: 0 additions & 2 deletions src/librustc/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -675,8 +675,6 @@ impl DepGraph {
}
} else {
match dep_dep_node.kind {
DepKind::Hir |
DepKind::HirBody |
DepKind::CrateMetadata => {
if dep_dep_node.extract_def_id(tcx).is_none() {
// If the node does not exist anymore, we
Expand Down
36 changes: 15 additions & 21 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ use crate::dep_graph::{DepGraph, DepNode, DepKind, DepNodeIndex};

use crate::hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId, DefIndexAddressSpace};

use crate::middle::cstore::CrateStoreDyn;

use rustc_target::spec::abi::Abi;
use rustc_data_structures::svh::Svh;
use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID};
Expand Down Expand Up @@ -1231,31 +1229,27 @@ impl Named for StructField { fn name(&self) -> Name { self.ident.name } }
impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } }
impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } }

pub fn map_crate<'hir>(sess: &crate::session::Session,
cstore: &CrateStoreDyn,
forest: &'hir Forest,
definitions: &'hir Definitions)
-> Map<'hir> {
pub fn map_crate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Map<'tcx> {
// Build the reverse mapping of `node_to_hir_id`.
let hir_to_node_id = definitions.node_to_hir_id.iter_enumerated()
let hir_to_node_id = tcx.hir_defs.node_to_hir_id.iter_enumerated()
.map(|(node_id, &hir_id)| (hir_id, node_id)).collect();

let (map, crate_hash) = {
let hcx = crate::ich::StableHashingContext::new(sess, &forest.krate, definitions, cstore);
let hcx = tcx.create_stable_hashing_context();

let mut collector = NodeCollector::root(sess,
&forest.krate,
&forest.dep_graph,
&definitions,
let mut collector = NodeCollector::root(tcx.sess,
&tcx.hir_forest.untracked_krate(),
&tcx.dep_graph,
&tcx.hir_defs,
&hir_to_node_id,
hcx);
intravisit::walk_crate(&mut collector, &forest.krate);
intravisit::walk_crate(&mut collector, &tcx.hir_forest.untracked_krate());

let crate_disambiguator = sess.local_crate_disambiguator();
let cmdline_args = sess.opts.dep_tracking_hash();
let crate_disambiguator = tcx.sess.local_crate_disambiguator();
let cmdline_args = tcx.sess.opts.dep_tracking_hash();
collector.finalize_and_compute_crate_hash(
crate_disambiguator,
cstore,
tcx.cstore,
cmdline_args
)
};
Expand All @@ -1273,15 +1267,15 @@ pub fn map_crate<'hir>(sess: &crate::session::Session,
}

let map = Map {
forest,
dep_graph: forest.dep_graph.clone(),
forest: &tcx.hir_forest,
dep_graph: tcx.dep_graph.clone(),
crate_hash,
map,
hir_to_node_id,
definitions,
definitions: &tcx.hir_defs,
};

time(sess, "validate hir map", || {
time(tcx.sess, "validate hir map", || {
hir_id_validator::check_crate(&map);
});

Expand Down
59 changes: 41 additions & 18 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
StableHasher, StableHasherResult,
StableVec};
use arena::{TypedArena, SyncDroplessArena};
use rustc_data_structures::cold_path;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal};
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal, AtomicCell};
use std::any::Any;
use std::borrow::Borrow;
use std::cmp::Ordering;
Expand Down Expand Up @@ -93,6 +94,8 @@ impl<'tcx> AllArenas<'tcx> {
/// Internal storage
#[derive(Default)]
pub struct GlobalArenas<'tcx> {
pub hir_map: TypedArena<hir_map::Map<'tcx>>,

// internings
layout: TypedArena<LayoutDetails>,

Expand Down Expand Up @@ -990,10 +993,10 @@ impl<'gcx> Deref for TyCtxt<'_, 'gcx, '_> {
}

pub struct GlobalCtxt<'tcx> {
global_arenas: &'tcx WorkerLocal<GlobalArenas<'tcx>>,
pub global_arenas: &'tcx WorkerLocal<GlobalArenas<'tcx>>,
global_interners: CtxtInterners<'tcx>,

cstore: &'tcx CrateStoreDyn,
pub(crate) cstore: &'tcx CrateStoreDyn,

pub sess: &'tcx Session,

Expand All @@ -1011,7 +1014,11 @@ pub struct GlobalCtxt<'tcx> {
/// Export map produced by name resolution.
export_map: FxHashMap<DefId, Lrc<Vec<Export>>>,

hir_map: hir_map::Map<'tcx>,
pub hir_forest: hir::map::Forest,

pub hir_defs: hir::map::Definitions,

hir_map: AtomicCell<Option<&'tcx hir_map::Map<'tcx>>>,

/// A map from DefPathHash -> DefId. Includes DefIds from the local crate
/// as well as all upstream crates. Only populated in incremental mode.
Expand Down Expand Up @@ -1085,7 +1092,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

#[inline(always)]
pub fn hir(self) -> &'a hir_map::Map<'gcx> {
&self.hir_map
let value = self.hir_map.load();
if unlikely!(value.is_none()) {
cold_path(|| {
let map = self.hir_map(LOCAL_CRATE);
self.hir_map.store(Some(map));
map
})
} else {
value.unwrap()
}
}

pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics {
Expand Down Expand Up @@ -1189,7 +1205,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
extern_providers: ty::query::Providers<'tcx>,
arenas: &'tcx AllArenas<'tcx>,
resolutions: ty::Resolutions,
hir: hir_map::Map<'tcx>,
hir_forest: hir::map::Forest,
hir_defs: hir::map::Definitions,
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
crate_name: &str,
tx: mpsc::Sender<Box<dyn Any + Send>>,
Expand All @@ -1200,7 +1217,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
});
let interners = CtxtInterners::new(&arenas.interner);
let common_types = CommonTypes::new(&interners);
let dep_graph = hir.dep_graph.clone();
let dep_graph = hir_forest.dep_graph.clone();
let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
providers[LOCAL_CRATE] = local_providers;
Expand All @@ -1216,7 +1233,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
upstream_def_path_tables
.iter()
.map(|&(cnum, ref rc)| (cnum, &**rc))
.chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())))
.chain(iter::once((LOCAL_CRATE, hir_defs.def_path_table())))
};

// Precompute the capacity of the hashmap so we don't have to
Expand All @@ -1239,7 +1256,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

let mut trait_map: FxHashMap<_, Lrc<FxHashMap<_, _>>> = FxHashMap::default();
for (k, v) in resolutions.trait_map {
let hir_id = hir.node_to_hir_id(k);
let hir_id = hir_defs.node_to_hir_id(k);
let map = trait_map.entry(hir_id.owner).or_default();
Lrc::get_mut(map).unwrap()
.insert(hir_id.local_id,
Expand All @@ -1258,23 +1275,25 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
(k, Lrc::new(v))
}).collect(),
freevars: resolutions.freevars.into_iter().map(|(k, v)| {
(hir.local_def_id(k), Lrc::new(v))
(hir_defs.local_def_id(k), Lrc::new(v))
}).collect(),
maybe_unused_trait_imports:
resolutions.maybe_unused_trait_imports
.into_iter()
.map(|id| hir.local_def_id(id))
.map(|id| hir_defs.local_def_id(id))
.collect(),
maybe_unused_extern_crates:
resolutions.maybe_unused_extern_crates
.into_iter()
.map(|(id, sp)| (hir.local_def_id(id), sp))
.map(|(id, sp)| (hir_defs.local_def_id(id), sp))
.collect(),
glob_map: resolutions.glob_map.into_iter().map(|(id, names)| {
(hir.local_def_id(id), names)
(hir_defs.local_def_id(id), names)
}).collect(),
extern_prelude: resolutions.extern_prelude,
hir_map: hir,
hir_forest,
hir_defs,
hir_map: AtomicCell::new(None),
def_path_hash_to_def_id,
queries: query::Queries::new(
providers,
Expand Down Expand Up @@ -1369,7 +1388,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// be a non-local `DefPath`.
pub fn def_path(self, id: DefId) -> hir_map::DefPath {
if id.is_local() {
self.hir().def_path(id)
// FIXME: This is used in some panic path? Don't use hir()
self.hir_defs.def_path(id.index)
} else {
self.cstore.def_path(id)
}
Expand All @@ -1378,7 +1398,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
#[inline]
pub fn def_path_hash(self, def_id: DefId) -> hir_map::DefPathHash {
if def_id.is_local() {
self.hir().definitions().def_path_hash(def_id.index)
// FIXME: This is used when executing the hir query, can't use hir() here
self.hir_defs.def_path_hash(def_id.index)
} else {
self.cstore.def_path_hash(def_id)
}
Expand Down Expand Up @@ -1417,11 +1438,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

#[inline(always)]
pub fn create_stable_hashing_context(self) -> StableHashingContext<'a> {
let krate = self.gcx.hir_map.forest.untracked_krate();
// FIXME: This is used when executing the hir query, can't use hir() here.
// Also used when dealing with query cycles
let krate = self.hir_forest.untracked_krate();

StableHashingContext::new(self.sess,
krate,
self.hir().definitions(),
&self.hir_defs,
self.cstore)
}

Expand Down
6 changes: 6 additions & 0 deletions src/librustc/ty/query/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::analysis<'tcx> {
}
}

impl<'tcx> QueryDescription<'tcx> for queries::hir_map<'tcx> {
fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
"indexing HIR".into()
}
}

impl<'tcx> QueryDescription<'tcx> for queries::lint_levels<'tcx> {
fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
"computing the lint levels for items in this crate".into()
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/ty/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ pub use self::on_disk_cache::OnDiskCache;
// as they will raise an fatal error on query cycles instead.
define_queries! { <'tcx>
Other {
[no_hash] fn hir_map: HirMap(CrateNum) -> &'tcx hir::map::Map<'tcx>,

/// Run analysis passes on the crate
[] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>,

Expand Down
15 changes: 11 additions & 4 deletions src/librustc/ty/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1187,13 +1187,19 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
// FIXME(#45015): We should try move this boilerplate code into a macro
// somehow.
match dep_node.kind {
// Created by the Hir map query
DepKind::AllLocalTraitImpls |
DepKind::Krate => {
force!(hir_map, LOCAL_CRATE);
}
DepKind::HirBody |
DepKind::Hir => {
force!(hir_map, krate!());
}

// These are inputs that are expected to be pre-allocated and that
// should therefore always be red or green already
DepKind::AllLocalTraitImpls |
DepKind::Krate |
DepKind::CrateMetadata |
DepKind::HirBody |
DepKind::Hir |

// This are anonymous nodes
DepKind::TraitSelect |
Expand Down Expand Up @@ -1363,6 +1369,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::OriginalCrateName => { force!(original_crate_name, krate!()); }
DepKind::ExtraFileName => { force!(extra_filename, krate!()); }
DepKind::Analysis => { force!(analysis, krate!()); }
DepKind::HirMap => { force!(hir_map, krate!()); }

DepKind::AllTraitImplementations => {
force!(all_trait_implementations, krate!());
Expand Down
25 changes: 18 additions & 7 deletions src/librustc_interface/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,7 @@ pub fn prepare_outputs(

pub fn default_provide(providers: &mut ty::query::Providers) {
providers.analysis = analysis;
providers.hir_map = hir_map;
proc_macro_decls::provide(providers);
plugin::build::provide(providers);
hir::provide(providers);
Expand Down Expand Up @@ -805,7 +806,7 @@ impl BoxedGlobalCtxt {

pub fn create_global_ctxt(
compiler: &Compiler,
mut hir_forest: hir::map::Forest,
hir_forest: hir::map::Forest,
defs: hir::map::Definitions,
resolutions: Resolutions,
outputs: OutputFilenames,
Expand All @@ -824,11 +825,6 @@ pub fn create_global_ctxt(
let global_ctxt: Option<GlobalCtxt<'_>>;
let arenas = AllArenas::new();

// Construct the HIR map
let hir_map = time(sess, "indexing hir", || {
hir::map::map_crate(sess, cstore, &mut hir_forest, &defs)
});

let query_result_on_disk_cache = time(sess, "load query result cache", || {
rustc_incremental::load_query_result_cache(sess)
});
Expand All @@ -848,7 +844,8 @@ pub fn create_global_ctxt(
extern_providers,
&arenas,
resolutions,
hir_map,
hir_forest,
defs,
query_result_on_disk_cache,
&crate_name,
tx,
Expand Down Expand Up @@ -877,6 +874,20 @@ pub fn create_global_ctxt(
result
}

fn hir_map<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
cnum: CrateNum,
) -> &'tcx hir::map::Map<'tcx> {
assert_eq!(cnum, LOCAL_CRATE);

// Construct the HIR map
let hir_map = time(tcx.sess, "indexing hir", || {
hir::map::map_crate(tcx)
});

tcx.global_arenas.hir_map.alloc(hir_map)
}

/// Runs the resolution, type-checking, region checking and other
/// miscellaneous analysis passes on the crate.
fn analysis<'tcx>(
Expand Down

0 comments on commit 30e23f6

Please sign in to comment.