Skip to content

Commit 0ca5730

Browse files
committed
Turn HIR indexing into a query
1 parent 12e8c74 commit 0ca5730

File tree

7 files changed

+115
-60
lines changed

7 files changed

+115
-60
lines changed

src/librustc/arena.rs

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ macro_rules! arena_types {
3131
rustc::hir::def_id::DefId,
3232
rustc::ty::subst::SubstsRef<$tcx>
3333
)>,
34+
[few] hir_map: rustc::hir::map::Map<$tcx>,
3435
[few, decode] mir_keys: rustc::util::nodemap::DefIdSet,
3536
[decode] specialization_graph: rustc::traits::specialization_graph::Graph,
3637
[] region_scope_tree: rustc::middle::region::ScopeTree,

src/librustc/dep_graph/graph.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -674,8 +674,6 @@ impl DepGraph {
674674
}
675675
} else {
676676
match dep_dep_node.kind {
677-
DepKind::Hir |
678-
DepKind::HirBody |
679677
DepKind::CrateMetadata => {
680678
if dep_dep_node.extract_def_id(tcx).is_none() {
681679
// If the node does not exist anymore, we
@@ -719,7 +717,7 @@ impl DepGraph {
719717
None => {
720718
if !tcx.sess.has_errors() {
721719
bug!("try_mark_previous_green() - Forcing the DepNode \
722-
should have set its color")
720+
should have set its color - dep node {:?}", dep_dep_node)
723721
} else {
724722
// If the query we just forced has resulted
725723
// in some kind of compilation error, we

src/librustc/hir/map/mod.rs

+28-25
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ use crate::dep_graph::{DepGraph, DepNode, DepKind, DepNodeIndex};
88

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

11-
use crate::middle::cstore::CrateStoreDyn;
12-
1311
use rustc_target::spec::abi::Abi;
1412
use rustc_data_structures::svh::Svh;
1513
use rustc_data_structures::indexed_vec::IndexVec;
@@ -24,9 +22,11 @@ use crate::hir::itemlikevisit::ItemLikeVisitor;
2422
use crate::hir::print::Nested;
2523
use crate::util::nodemap::FxHashMap;
2624
use crate::util::common::time;
25+
use crate::ich::StableHashingContext;
2726

2827
use std::result::Result::Err;
2928
use crate::ty::query::Providers;
29+
use crate::ty::TyCtxt;
3030

3131
pub mod blocks;
3232
mod collector;
@@ -1135,45 +1135,48 @@ impl Named for StructField { fn name(&self) -> Name { self.ident.name } }
11351135
impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } }
11361136
impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } }
11371137

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

11471143
let (map, crate_hash) = {
1148-
let hcx = crate::ich::StableHashingContext::new(sess, &forest.krate, definitions, cstore);
1149-
1150-
let mut collector = NodeCollector::root(sess,
1151-
&forest.krate,
1152-
&forest.dep_graph,
1153-
&definitions,
1154-
&hir_to_node_id,
1155-
hcx);
1156-
intravisit::walk_crate(&mut collector, &forest.krate);
1157-
1158-
let crate_disambiguator = sess.local_crate_disambiguator();
1159-
let cmdline_args = sess.opts.dep_tracking_hash();
1144+
let krate = tcx.hir_forest.untracked_krate();
1145+
let hcx = StableHashingContext::new(
1146+
tcx.sess,
1147+
krate,
1148+
&tcx.hir_defs,
1149+
tcx.cstore
1150+
);
1151+
let mut collector = NodeCollector::root(
1152+
tcx.sess,
1153+
krate,
1154+
&tcx.dep_graph,
1155+
&tcx.hir_defs,
1156+
&hir_to_node_id,
1157+
hcx
1158+
);
1159+
intravisit::walk_crate(&mut collector, krate);
1160+
1161+
let crate_disambiguator = tcx.sess.local_crate_disambiguator();
1162+
let cmdline_args = tcx.sess.opts.dep_tracking_hash();
11601163
collector.finalize_and_compute_crate_hash(
11611164
crate_disambiguator,
1162-
cstore,
1165+
tcx.cstore,
11631166
cmdline_args
11641167
)
11651168
};
11661169

11671170
let map = Map {
1168-
forest,
1169-
dep_graph: forest.dep_graph.clone(),
1171+
forest: &tcx.hir_forest,
1172+
dep_graph: tcx.dep_graph.clone(),
11701173
crate_hash,
11711174
map,
11721175
hir_to_node_id,
1173-
definitions,
1176+
definitions: &tcx.hir_defs,
11741177
};
11751178

1176-
time(sess, "validate hir map", || {
1179+
time(tcx.sess, "validate hir map", || {
11771180
hir_id_validator::check_crate(&map);
11781181
});
11791182

src/librustc/query/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ use syntax_pos::symbol::InternedString;
3131
// as they will raise an fatal error on query cycles instead.
3232
rustc_queries! {
3333
Other {
34+
query hir_map(_: CrateNum) -> &'tcx hir::map::Map<'tcx> {
35+
no_hash
36+
eval_always
37+
desc { "indexing HIR" }
38+
}
39+
3440
/// Records the type of every item.
3541
query type_of(key: DefId) -> Ty<'tcx> {
3642
cache_on_disk_if { key.is_local() }

src/librustc/ty/context.rs

+41-20
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5252
StableHasher, StableHasherResult,
5353
StableVec};
5454
use arena::SyncDroplessArena;
55+
use rustc_data_structures::cold_path;
5556
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
56-
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal};
57+
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal, AtomicCell};
5758
use std::any::Any;
5859
use std::borrow::Borrow;
5960
use std::cmp::Ordering;
@@ -990,7 +991,7 @@ pub struct GlobalCtxt<'tcx> {
990991

991992
interners: CtxtInterners<'tcx>,
992993

993-
cstore: &'tcx CrateStoreDyn,
994+
pub(crate) cstore: &'tcx CrateStoreDyn,
994995

995996
pub sess: &'tcx Session,
996997

@@ -1017,7 +1018,11 @@ pub struct GlobalCtxt<'tcx> {
10171018
/// Export map produced by name resolution.
10181019
export_map: FxHashMap<DefId, Vec<Export<hir::HirId>>>,
10191020

1020-
hir_map: hir_map::Map<'tcx>,
1021+
pub hir_forest: hir::map::Forest,
1022+
1023+
pub hir_defs: hir::map::Definitions,
1024+
1025+
hir_map: AtomicCell<Option<&'tcx hir_map::Map<'tcx>>>,
10211026

10221027
/// A map from DefPathHash -> DefId. Includes DefIds from the local crate
10231028
/// as well as all upstream crates. Only populated in incremental mode.
@@ -1084,7 +1089,17 @@ impl<'tcx> TyCtxt<'tcx> {
10841089

10851090
#[inline(always)]
10861091
pub fn hir(self) -> &'tcx hir_map::Map<'tcx> {
1087-
&self.hir_map
1092+
let value = self.hir_map.load();
1093+
if unlikely!(value.is_none()) {
1094+
// We can use `with_ignore` here because the hir map does its own tracking
1095+
cold_path(|| self.dep_graph.with_ignore(|| {
1096+
let map = self.hir_map(LOCAL_CRATE);
1097+
self.hir_map.store(Some(map));
1098+
map
1099+
}))
1100+
} else {
1101+
value.unwrap()
1102+
}
10881103
}
10891104

10901105
pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
@@ -1169,7 +1184,8 @@ impl<'tcx> TyCtxt<'tcx> {
11691184
extern_providers: ty::query::Providers<'tcx>,
11701185
arenas: &'tcx AllArenas,
11711186
resolutions: ty::Resolutions,
1172-
hir: hir_map::Map<'tcx>,
1187+
hir_forest: hir::map::Forest,
1188+
hir_defs: hir::map::Definitions,
11731189
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
11741190
crate_name: &str,
11751191
tx: mpsc::Sender<Box<dyn Any + Send>>,
@@ -1188,7 +1204,7 @@ impl<'tcx> TyCtxt<'tcx> {
11881204
let common_types = CommonTypes::new(&interners);
11891205
let common_lifetimes = CommonLifetimes::new(&interners);
11901206
let common_consts = CommonConsts::new(&interners, &common_types);
1191-
let dep_graph = hir.dep_graph.clone();
1207+
let dep_graph = hir_forest.dep_graph.clone();
11921208
let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
11931209
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
11941210
providers[LOCAL_CRATE] = local_providers;
@@ -1204,7 +1220,7 @@ impl<'tcx> TyCtxt<'tcx> {
12041220
upstream_def_path_tables
12051221
.iter()
12061222
.map(|&(cnum, ref rc)| (cnum, &**rc))
1207-
.chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())))
1223+
.chain(iter::once((LOCAL_CRATE, hir_defs.def_path_table())))
12081224
};
12091225

12101226
// Precompute the capacity of the hashmap so we don't have to
@@ -1227,7 +1243,7 @@ impl<'tcx> TyCtxt<'tcx> {
12271243

12281244
let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
12291245
for (k, v) in resolutions.trait_map {
1230-
let hir_id = hir.node_to_hir_id(k);
1246+
let hir_id = hir_defs.node_to_hir_id(k);
12311247
let map = trait_map.entry(hir_id.owner).or_default();
12321248
map.insert(hir_id.local_id, StableVec::new(v));
12331249
}
@@ -1245,25 +1261,27 @@ impl<'tcx> TyCtxt<'tcx> {
12451261
trait_map,
12461262
export_map: resolutions.export_map.into_iter().map(|(k, v)| {
12471263
let exports: Vec<_> = v.into_iter().map(|e| {
1248-
e.map_id(|id| hir.node_to_hir_id(id))
1264+
e.map_id(|id| hir_defs.node_to_hir_id(id))
12491265
}).collect();
12501266
(k, exports)
12511267
}).collect(),
12521268
maybe_unused_trait_imports:
12531269
resolutions.maybe_unused_trait_imports
12541270
.into_iter()
1255-
.map(|id| hir.local_def_id_from_node_id(id))
1271+
.map(|id| hir_defs.local_def_id(id))
12561272
.collect(),
12571273
maybe_unused_extern_crates:
12581274
resolutions.maybe_unused_extern_crates
12591275
.into_iter()
1260-
.map(|(id, sp)| (hir.local_def_id_from_node_id(id), sp))
1276+
.map(|(id, sp)| (hir_defs.local_def_id(id), sp))
12611277
.collect(),
12621278
glob_map: resolutions.glob_map.into_iter().map(|(id, names)| {
1263-
(hir.local_def_id_from_node_id(id), names)
1279+
(hir_defs.local_def_id(id), names)
12641280
}).collect(),
12651281
extern_prelude: resolutions.extern_prelude,
1266-
hir_map: hir,
1282+
hir_forest,
1283+
hir_defs,
1284+
hir_map: AtomicCell::new(None),
12671285
def_path_hash_to_def_id,
12681286
queries: query::Queries::new(
12691287
providers,
@@ -1377,7 +1395,9 @@ impl<'tcx> TyCtxt<'tcx> {
13771395
#[inline]
13781396
pub fn def_path_hash(self, def_id: DefId) -> hir_map::DefPathHash {
13791397
if def_id.is_local() {
1380-
self.hir().definitions().def_path_hash(def_id.index)
1398+
// This is used when creating dep nodes, which happens when executing queries,
1399+
// so we can't use hir() here
1400+
self.hir_defs.def_path_hash(def_id.index)
13811401
} else {
13821402
self.cstore.def_path_hash(def_id)
13831403
}
@@ -1416,12 +1436,13 @@ impl<'tcx> TyCtxt<'tcx> {
14161436

14171437
#[inline(always)]
14181438
pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> {
1419-
let krate = self.gcx.hir_map.forest.untracked_krate();
1420-
1421-
StableHashingContext::new(self.sess,
1422-
krate,
1423-
self.hir().definitions(),
1424-
self.cstore)
1439+
// This is used when executing queries. Also used when dealing with query cycles
1440+
StableHashingContext::new(
1441+
self.sess,
1442+
self.hir_forest.untracked_krate(),
1443+
&self.hir_defs,
1444+
self.cstore
1445+
)
14251446
}
14261447

14271448
// This method makes sure that we have a DepNode and a Fingerprint for

src/librustc/ty/query/plumbing.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
//! generate the actual methods on tcx which find and execute the provider,
33
//! manage the caches, and so forth.
44
5-
use crate::dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex};
5+
use crate::dep_graph::{DepNodeIndex, DepNode, DepConstructor, DepKind, SerializedDepNodeIndex};
66
use crate::ty::tls;
77
use crate::ty::{self, TyCtxt};
88
use crate::ty::query::Query;
99
use crate::ty::query::config::{QueryConfig, QueryDescription};
1010
use crate::ty::query::job::{QueryJob, QueryResult, QueryInfo};
11+
use crate::hir::def_id::LOCAL_CRATE;
1112

1213
use crate::util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
1314

@@ -1220,14 +1221,28 @@ pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool {
12201221
($query:ident, $key:expr) => { force_ex!(tcx, $query, $key) }
12211222
};
12221223

1224+
let force_hir_map = || {
1225+
tcx.force_query::<crate::ty::query::queries::hir_map<'_>>(
1226+
LOCAL_CRATE,
1227+
DUMMY_SP,
1228+
DepNode::new(tcx, DepConstructor::hir_map(LOCAL_CRATE)),
1229+
);
1230+
};
1231+
12231232
rustc_dep_node_force!([dep_node, tcx]
1233+
// Created by the Hir map query
1234+
DepKind::AllLocalTraitImpls |
1235+
DepKind::Krate => force_hir_map(),
1236+
DepKind::HirBody |
1237+
DepKind::Hir => {
1238+
// Ensure the def_id exists
1239+
def_id!();
1240+
force_hir_map();
1241+
}
1242+
12241243
// These are inputs that are expected to be pre-allocated and that
12251244
// should therefore always be red or green already
1226-
DepKind::AllLocalTraitImpls |
1227-
DepKind::Krate |
12281245
DepKind::CrateMetadata |
1229-
DepKind::HirBody |
1230-
DepKind::Hir |
12311246

12321247
// This are anonymous nodes
12331248
DepKind::TraitSelect |

src/librustc_interface/passes.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,7 @@ pub fn prepare_outputs(
761761

762762
pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
763763
providers.analysis = analysis;
764+
providers.hir_map = hir_map;
764765
proc_macro_decls::provide(providers);
765766
plugin::build::provide(providers);
766767
hir::provide(providers);
@@ -806,7 +807,7 @@ impl BoxedGlobalCtxt {
806807

807808
pub fn create_global_ctxt(
808809
compiler: &Compiler,
809-
mut hir_forest: hir::map::Forest,
810+
hir_forest: hir::map::Forest,
810811
defs: hir::map::Definitions,
811812
resolutions: Resolutions,
812813
outputs: OutputFilenames,
@@ -825,11 +826,6 @@ pub fn create_global_ctxt(
825826
let global_ctxt: Option<GlobalCtxt<'_>>;
826827
let arenas = AllArenas::new();
827828

828-
// Construct the HIR map
829-
let hir_map = time(sess, "indexing hir", || {
830-
hir::map::map_crate(sess, cstore, &mut hir_forest, &defs)
831-
});
832-
833829
let query_result_on_disk_cache = time(sess, "load query result cache", || {
834830
rustc_incremental::load_query_result_cache(sess)
835831
});
@@ -849,7 +845,8 @@ pub fn create_global_ctxt(
849845
extern_providers,
850846
&arenas,
851847
resolutions,
852-
hir_map,
848+
hir_forest,
849+
defs,
853850
query_result_on_disk_cache,
854851
&crate_name,
855852
tx,
@@ -876,6 +873,20 @@ pub fn create_global_ctxt(
876873
result
877874
}
878875

876+
fn hir_map<'tcx>(
877+
tcx: TyCtxt<'tcx>,
878+
cnum: CrateNum,
879+
) -> &'tcx hir::map::Map<'tcx> {
880+
assert_eq!(cnum, LOCAL_CRATE);
881+
882+
// Construct the HIR map
883+
let hir_map = time(tcx.sess, "indexing hir", || {
884+
hir::map::map_crate(tcx)
885+
});
886+
887+
tcx.arena.alloc(hir_map)
888+
}
889+
879890
/// Runs the resolution, type-checking, region checking and other
880891
/// miscellaneous analysis passes on the crate.
881892
fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {

0 commit comments

Comments
 (0)