Skip to content

Commit 4be9e3e

Browse files
committed
Turn HIR indexing into a query
1 parent 57446d0 commit 4be9e3e

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,10 +22,12 @@ 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::io;
2928
use std::result::Result::Err;
3029
use crate::ty::query::Providers;
30+
use crate::ty::TyCtxt;
3131

3232
pub mod blocks;
3333
mod collector;
@@ -1257,45 +1257,48 @@ impl Named for StructField { fn name(&self) -> Name { self.ident.name } }
12571257
impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } }
12581258
impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } }
12591259

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

12691265
let (map, crate_hash) = {
1270-
let hcx = crate::ich::StableHashingContext::new(sess, &forest.krate, definitions, cstore);
1271-
1272-
let mut collector = NodeCollector::root(sess,
1273-
&forest.krate,
1274-
&forest.dep_graph,
1275-
&definitions,
1276-
&hir_to_node_id,
1277-
hcx);
1278-
intravisit::walk_crate(&mut collector, &forest.krate);
1279-
1280-
let crate_disambiguator = sess.local_crate_disambiguator();
1281-
let cmdline_args = sess.opts.dep_tracking_hash();
1266+
let krate = tcx.hir_forest.untracked_krate();
1267+
let hcx = StableHashingContext::new(
1268+
tcx.sess,
1269+
krate,
1270+
&tcx.hir_defs,
1271+
tcx.cstore
1272+
);
1273+
let mut collector = NodeCollector::root(
1274+
tcx.sess,
1275+
krate,
1276+
&tcx.dep_graph,
1277+
&tcx.hir_defs,
1278+
&hir_to_node_id,
1279+
hcx
1280+
);
1281+
intravisit::walk_crate(&mut collector, krate);
1282+
1283+
let crate_disambiguator = tcx.sess.local_crate_disambiguator();
1284+
let cmdline_args = tcx.sess.opts.dep_tracking_hash();
12821285
collector.finalize_and_compute_crate_hash(
12831286
crate_disambiguator,
1284-
cstore,
1287+
tcx.cstore,
12851288
cmdline_args
12861289
)
12871290
};
12881291

12891292
let map = Map {
1290-
forest,
1291-
dep_graph: forest.dep_graph.clone(),
1293+
forest: &tcx.hir_forest,
1294+
dep_graph: tcx.dep_graph.clone(),
12921295
crate_hash,
12931296
map,
12941297
hir_to_node_id,
1295-
definitions,
1298+
definitions: &tcx.hir_defs,
12961299
};
12971300

1298-
time(sess, "validate hir map", || {
1301+
time(tcx.sess, "validate hir map", || {
12991302
hir_id_validator::check_crate(&map);
13001303
});
13011304

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 { key.is_local() }

src/librustc/ty/context.rs

+41-20
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5454
StableHasher, StableHasherResult,
5555
StableVec};
5656
use arena::SyncDroplessArena;
57+
use rustc_data_structures::cold_path;
5758
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
58-
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal};
59+
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal, AtomicCell};
5960
use std::any::Any;
6061
use std::borrow::Borrow;
6162
use std::cmp::Ordering;
@@ -1035,7 +1036,7 @@ pub struct GlobalCtxt<'tcx> {
10351036
global_interners: CtxtInterners<'tcx>,
10361037
local_interners: CtxtInterners<'tcx>,
10371038

1038-
cstore: &'tcx CrateStoreDyn,
1039+
pub(crate) cstore: &'tcx CrateStoreDyn,
10391040

10401041
pub sess: &'tcx Session,
10411042

@@ -1062,7 +1063,11 @@ pub struct GlobalCtxt<'tcx> {
10621063
/// Export map produced by name resolution.
10631064
export_map: FxHashMap<DefId, Vec<Export<hir::HirId>>>,
10641065

1065-
hir_map: hir_map::Map<'tcx>,
1066+
pub hir_forest: hir::map::Forest,
1067+
1068+
pub hir_defs: hir::map::Definitions,
1069+
1070+
hir_map: AtomicCell<Option<&'tcx hir_map::Map<'tcx>>>,
10661071

10671072
/// A map from DefPathHash -> DefId. Includes DefIds from the local crate
10681073
/// as well as all upstream crates. Only populated in incremental mode.
@@ -1131,7 +1136,17 @@ impl<'tcx> TyCtxt<'tcx> {
11311136

11321137
#[inline(always)]
11331138
pub fn hir(self) -> &'tcx hir_map::Map<'tcx> {
1134-
&self.hir_map
1139+
let value = self.hir_map.load();
1140+
if unlikely!(value.is_none()) {
1141+
// We can use `with_ignore` here because the hir map does its own tracking
1142+
cold_path(|| self.dep_graph.with_ignore(|| {
1143+
let map = self.hir_map(LOCAL_CRATE);
1144+
self.hir_map.store(Some(map));
1145+
map
1146+
}))
1147+
} else {
1148+
value.unwrap()
1149+
}
11351150
}
11361151

11371152
pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
@@ -1221,7 +1236,8 @@ impl<'tcx> TyCtxt<'tcx> {
12211236
extern_providers: ty::query::Providers<'tcx>,
12221237
arenas: &'tcx AllArenas,
12231238
resolutions: ty::Resolutions,
1224-
hir: hir_map::Map<'tcx>,
1239+
hir_forest: hir::map::Forest,
1240+
hir_defs: hir::map::Definitions,
12251241
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
12261242
crate_name: &str,
12271243
tx: mpsc::Sender<Box<dyn Any + Send>>,
@@ -1241,7 +1257,7 @@ impl<'tcx> TyCtxt<'tcx> {
12411257
let common_types = CommonTypes::new(&interners);
12421258
let common_lifetimes = CommonLifetimes::new(&interners);
12431259
let common_consts = CommonConsts::new(&interners, &common_types);
1244-
let dep_graph = hir.dep_graph.clone();
1260+
let dep_graph = hir_forest.dep_graph.clone();
12451261
let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
12461262
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
12471263
providers[LOCAL_CRATE] = local_providers;
@@ -1257,7 +1273,7 @@ impl<'tcx> TyCtxt<'tcx> {
12571273
upstream_def_path_tables
12581274
.iter()
12591275
.map(|&(cnum, ref rc)| (cnum, &**rc))
1260-
.chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())))
1276+
.chain(iter::once((LOCAL_CRATE, hir_defs.def_path_table())))
12611277
};
12621278

12631279
// Precompute the capacity of the hashmap so we don't have to
@@ -1280,7 +1296,7 @@ impl<'tcx> TyCtxt<'tcx> {
12801296

12811297
let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
12821298
for (k, v) in resolutions.trait_map {
1283-
let hir_id = hir.node_to_hir_id(k);
1299+
let hir_id = hir_defs.node_to_hir_id(k);
12841300
let map = trait_map.entry(hir_id.owner).or_default();
12851301
map.insert(hir_id.local_id, StableVec::new(v));
12861302
}
@@ -1299,25 +1315,27 @@ impl<'tcx> TyCtxt<'tcx> {
12991315
trait_map,
13001316
export_map: resolutions.export_map.into_iter().map(|(k, v)| {
13011317
let exports: Vec<_> = v.into_iter().map(|e| {
1302-
e.map_id(|id| hir.node_to_hir_id(id))
1318+
e.map_id(|id| hir_defs.node_to_hir_id(id))
13031319
}).collect();
13041320
(k, exports)
13051321
}).collect(),
13061322
maybe_unused_trait_imports:
13071323
resolutions.maybe_unused_trait_imports
13081324
.into_iter()
1309-
.map(|id| hir.local_def_id(id))
1325+
.map(|id| hir_defs.local_def_id(id))
13101326
.collect(),
13111327
maybe_unused_extern_crates:
13121328
resolutions.maybe_unused_extern_crates
13131329
.into_iter()
1314-
.map(|(id, sp)| (hir.local_def_id(id), sp))
1330+
.map(|(id, sp)| (hir_defs.local_def_id(id), sp))
13151331
.collect(),
13161332
glob_map: resolutions.glob_map.into_iter().map(|(id, names)| {
1317-
(hir.local_def_id(id), names)
1333+
(hir_defs.local_def_id(id), names)
13181334
}).collect(),
13191335
extern_prelude: resolutions.extern_prelude,
1320-
hir_map: hir,
1336+
hir_forest,
1337+
hir_defs,
1338+
hir_map: AtomicCell::new(None),
13211339
def_path_hash_to_def_id,
13221340
queries: query::Queries::new(
13231341
providers,
@@ -1431,7 +1449,9 @@ impl<'tcx> TyCtxt<'tcx> {
14311449
#[inline]
14321450
pub fn def_path_hash(self, def_id: DefId) -> hir_map::DefPathHash {
14331451
if def_id.is_local() {
1434-
self.hir().definitions().def_path_hash(def_id.index)
1452+
// This is used when creating dep nodes, which happens when executing queries,
1453+
// so we can't use hir() here
1454+
self.hir_defs.def_path_hash(def_id.index)
14351455
} else {
14361456
self.cstore.def_path_hash(def_id)
14371457
}
@@ -1470,12 +1490,13 @@ impl<'tcx> TyCtxt<'tcx> {
14701490

14711491
#[inline(always)]
14721492
pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> {
1473-
let krate = self.gcx.hir_map.forest.untracked_krate();
1474-
1475-
StableHashingContext::new(self.sess,
1476-
krate,
1477-
self.hir().definitions(),
1478-
self.cstore)
1493+
// This is used when executing queries. Also used when dealing with query cycles
1494+
StableHashingContext::new(
1495+
self.sess,
1496+
self.hir_forest.untracked_krate(),
1497+
&self.hir_defs,
1498+
self.cstore
1499+
)
14791500
}
14801501

14811502
// 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

@@ -1187,14 +1188,28 @@ pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool
11871188
($query:ident, $key:expr) => { force_ex!(tcx, $query, $key) }
11881189
};
11891190

1191+
let force_hir_map = || {
1192+
tcx.force_query::<crate::ty::query::queries::hir_map<'_>>(
1193+
LOCAL_CRATE,
1194+
DUMMY_SP,
1195+
DepNode::new(tcx, DepConstructor::hir_map(LOCAL_CRATE)),
1196+
);
1197+
};
1198+
11901199
rustc_dep_node_force!([dep_node, tcx]
1200+
// Created by the Hir map query
1201+
DepKind::AllLocalTraitImpls |
1202+
DepKind::Krate => force_hir_map(),
1203+
DepKind::HirBody |
1204+
DepKind::Hir => {
1205+
// Ensure the def_id exists
1206+
def_id!();
1207+
force_hir_map();
1208+
}
1209+
11911210
// These are inputs that are expected to be pre-allocated and that
11921211
// should therefore always be red or green already
1193-
DepKind::AllLocalTraitImpls |
1194-
DepKind::Krate |
11951212
DepKind::CrateMetadata |
1196-
DepKind::HirBody |
1197-
DepKind::Hir |
11981213

11991214
// This are anonymous nodes
12001215
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>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> {

0 commit comments

Comments
 (0)