Skip to content

Commit ac51008

Browse files
committed
Turn HIR indexing into a query
1 parent 40d951e commit ac51008

File tree

6 files changed

+116
-61
lines changed

6 files changed

+116
-61
lines changed

src/librustc/dep_graph/graph.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -675,8 +675,6 @@ impl DepGraph {
675675
}
676676
} else {
677677
match dep_dep_node.kind {
678-
DepKind::Hir |
679-
DepKind::HirBody |
680678
DepKind::CrateMetadata => {
681679
if dep_dep_node.extract_def_id(tcx).is_none() {
682680
// If the node does not exist anymore, we
@@ -720,7 +718,7 @@ impl DepGraph {
720718
None => {
721719
if !tcx.sess.has_errors() {
722720
bug!("try_mark_previous_green() - Forcing the DepNode \
723-
should have set its color")
721+
should have set its color - dep node {:?}", dep_dep_node)
724722
} else {
725723
// If the query we just forced has resulted
726724
// in some kind of compilation error, we

src/librustc/hir/map/mod.rs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ use crate::dep_graph::{DepGraph, DepNode, DepKind, DepNodeIndex};
77

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

10-
use crate::middle::cstore::CrateStoreDyn;
11-
1210
use rustc_target::spec::abi::Abi;
1311
use rustc_data_structures::svh::Svh;
1412
use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID};
@@ -21,6 +19,7 @@ use crate::hir::itemlikevisit::ItemLikeVisitor;
2119
use crate::hir::print::Nested;
2220
use crate::util::nodemap::FxHashMap;
2321
use crate::util::common::time;
22+
use crate::ich::StableHashingContext;
2423

2524
use std::io;
2625
use std::result::Result::Err;
@@ -1231,31 +1230,34 @@ impl Named for StructField { fn name(&self) -> Name { self.ident.name } }
12311230
impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } }
12321231
impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } }
12331232

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

12431238
let (map, crate_hash) = {
1244-
let hcx = crate::ich::StableHashingContext::new(sess, &forest.krate, definitions, cstore);
1245-
1246-
let mut collector = NodeCollector::root(sess,
1247-
&forest.krate,
1248-
&forest.dep_graph,
1249-
&definitions,
1250-
&hir_to_node_id,
1251-
hcx);
1252-
intravisit::walk_crate(&mut collector, &forest.krate);
1253-
1254-
let crate_disambiguator = sess.local_crate_disambiguator();
1255-
let cmdline_args = sess.opts.dep_tracking_hash();
1239+
let krate = tcx.hir_forest.untracked_krate();
1240+
let hcx = StableHashingContext::new(
1241+
tcx.sess,
1242+
krate,
1243+
&tcx.hir_defs,
1244+
tcx.cstore
1245+
);
1246+
let mut collector = NodeCollector::root(
1247+
tcx.sess,
1248+
krate,
1249+
&tcx.dep_graph,
1250+
&tcx.hir_defs,
1251+
&hir_to_node_id,
1252+
hcx
1253+
);
1254+
intravisit::walk_crate(&mut collector, krate);
1255+
1256+
let crate_disambiguator = tcx.sess.local_crate_disambiguator();
1257+
let cmdline_args = tcx.sess.opts.dep_tracking_hash();
12561258
collector.finalize_and_compute_crate_hash(
12571259
crate_disambiguator,
1258-
cstore,
1260+
tcx.cstore,
12591261
cmdline_args
12601262
)
12611263
};
@@ -1273,15 +1275,15 @@ pub fn map_crate<'hir>(sess: &crate::session::Session,
12731275
}
12741276

12751277
let map = Map {
1276-
forest,
1277-
dep_graph: forest.dep_graph.clone(),
1278+
forest: &tcx.hir_forest,
1279+
dep_graph: tcx.dep_graph.clone(),
12781280
crate_hash,
12791281
map,
12801282
hir_to_node_id,
1281-
definitions,
1283+
definitions: &tcx.hir_defs,
12821284
};
12831285

1284-
time(sess, "validate hir map", || {
1286+
time(tcx.sess, "validate hir map", || {
12851287
hir_id_validator::check_crate(&map);
12861288
});
12871289

src/librustc/query/mod.rs

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

src/librustc/ty/context.rs

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5050
StableHasher, StableHasherResult,
5151
StableVec};
5252
use arena::{TypedArena, SyncDroplessArena};
53+
use rustc_data_structures::cold_path;
5354
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
54-
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal};
55+
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal, AtomicCell};
5556
use std::any::Any;
5657
use std::borrow::Borrow;
5758
use std::cmp::Ordering;
@@ -93,6 +94,8 @@ impl<'tcx> AllArenas<'tcx> {
9394
/// Internal storage
9495
#[derive(Default)]
9596
pub struct GlobalArenas<'tcx> {
97+
pub hir_map: TypedArena<hir_map::Map<'tcx>>,
98+
9699
// internings
97100
layout: TypedArena<LayoutDetails>,
98101

@@ -1003,10 +1006,10 @@ impl<'gcx> Deref for TyCtxt<'_, 'gcx, '_> {
10031006
}
10041007

10051008
pub struct GlobalCtxt<'tcx> {
1006-
global_arenas: &'tcx WorkerLocal<GlobalArenas<'tcx>>,
1009+
pub global_arenas: &'tcx WorkerLocal<GlobalArenas<'tcx>>,
10071010
global_interners: CtxtInterners<'tcx>,
10081011

1009-
cstore: &'tcx CrateStoreDyn,
1012+
pub(crate) cstore: &'tcx CrateStoreDyn,
10101013

10111014
pub sess: &'tcx Session,
10121015

@@ -1024,7 +1027,11 @@ pub struct GlobalCtxt<'tcx> {
10241027
/// Export map produced by name resolution.
10251028
export_map: FxHashMap<DefId, Lrc<Vec<Export>>>,
10261029

1027-
hir_map: hir_map::Map<'tcx>,
1030+
pub hir_forest: hir::map::Forest,
1031+
1032+
pub hir_defs: hir::map::Definitions,
1033+
1034+
hir_map: AtomicCell<Option<&'tcx hir_map::Map<'tcx>>>,
10281035

10291036
/// A map from DefPathHash -> DefId. Includes DefIds from the local crate
10301037
/// as well as all upstream crates. Only populated in incremental mode.
@@ -1098,7 +1105,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
10981105

10991106
#[inline(always)]
11001107
pub fn hir(self) -> &'a hir_map::Map<'gcx> {
1101-
&self.hir_map
1108+
let value = self.hir_map.load();
1109+
if unlikely!(value.is_none()) {
1110+
// We can use `with_ignore` here because the hir map does its own tracking
1111+
cold_path(|| self.dep_graph.with_ignore(|| {
1112+
let map = self.hir_map(LOCAL_CRATE);
1113+
self.hir_map.store(Some(map));
1114+
map
1115+
}))
1116+
} else {
1117+
value.unwrap()
1118+
}
11021119
}
11031120

11041121
pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics {
@@ -1202,7 +1219,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12021219
extern_providers: ty::query::Providers<'tcx>,
12031220
arenas: &'tcx AllArenas<'tcx>,
12041221
resolutions: ty::Resolutions,
1205-
hir: hir_map::Map<'tcx>,
1222+
hir_forest: hir::map::Forest,
1223+
hir_defs: hir::map::Definitions,
12061224
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
12071225
crate_name: &str,
12081226
tx: mpsc::Sender<Box<dyn Any + Send>>,
@@ -1213,7 +1231,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12131231
});
12141232
let interners = CtxtInterners::new(&arenas.interner);
12151233
let common_types = CommonTypes::new(&interners);
1216-
let dep_graph = hir.dep_graph.clone();
1234+
let dep_graph = hir_forest.dep_graph.clone();
12171235
let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
12181236
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
12191237
providers[LOCAL_CRATE] = local_providers;
@@ -1229,7 +1247,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12291247
upstream_def_path_tables
12301248
.iter()
12311249
.map(|&(cnum, ref rc)| (cnum, &**rc))
1232-
.chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())))
1250+
.chain(iter::once((LOCAL_CRATE, hir_defs.def_path_table())))
12331251
};
12341252

12351253
// Precompute the capacity of the hashmap so we don't have to
@@ -1252,7 +1270,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12521270

12531271
let mut trait_map: FxHashMap<_, Lrc<FxHashMap<_, _>>> = FxHashMap::default();
12541272
for (k, v) in resolutions.trait_map {
1255-
let hir_id = hir.node_to_hir_id(k);
1273+
let hir_id = hir_defs.node_to_hir_id(k);
12561274
let map = trait_map.entry(hir_id.owner).or_default();
12571275
Lrc::get_mut(map).unwrap()
12581276
.insert(hir_id.local_id,
@@ -1271,23 +1289,25 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12711289
(k, Lrc::new(v))
12721290
}).collect(),
12731291
freevars: resolutions.freevars.into_iter().map(|(k, v)| {
1274-
(hir.local_def_id(k), Lrc::new(v))
1292+
(hir_defs.local_def_id(k), Lrc::new(v))
12751293
}).collect(),
12761294
maybe_unused_trait_imports:
12771295
resolutions.maybe_unused_trait_imports
12781296
.into_iter()
1279-
.map(|id| hir.local_def_id(id))
1297+
.map(|id| hir_defs.local_def_id(id))
12801298
.collect(),
12811299
maybe_unused_extern_crates:
12821300
resolutions.maybe_unused_extern_crates
12831301
.into_iter()
1284-
.map(|(id, sp)| (hir.local_def_id(id), sp))
1302+
.map(|(id, sp)| (hir_defs.local_def_id(id), sp))
12851303
.collect(),
12861304
glob_map: resolutions.glob_map.into_iter().map(|(id, names)| {
1287-
(hir.local_def_id(id), names)
1305+
(hir_defs.local_def_id(id), names)
12881306
}).collect(),
12891307
extern_prelude: resolutions.extern_prelude,
1290-
hir_map: hir,
1308+
hir_forest,
1309+
hir_defs,
1310+
hir_map: AtomicCell::new(None),
12911311
def_path_hash_to_def_id,
12921312
queries: query::Queries::new(
12931313
providers,
@@ -1391,7 +1411,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13911411
#[inline]
13921412
pub fn def_path_hash(self, def_id: DefId) -> hir_map::DefPathHash {
13931413
if def_id.is_local() {
1394-
self.hir().definitions().def_path_hash(def_id.index)
1414+
// This is used when creating dep nodes, which happens when executing queries,
1415+
// so we can't use hir() here
1416+
self.hir_defs.def_path_hash(def_id.index)
13951417
} else {
13961418
self.cstore.def_path_hash(def_id)
13971419
}
@@ -1430,12 +1452,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
14301452

14311453
#[inline(always)]
14321454
pub fn create_stable_hashing_context(self) -> StableHashingContext<'a> {
1433-
let krate = self.gcx.hir_map.forest.untracked_krate();
1434-
1435-
StableHashingContext::new(self.sess,
1436-
krate,
1437-
self.hir().definitions(),
1438-
self.cstore)
1455+
// This is used when executing queries. Also used when dealing with query cycles
1456+
StableHashingContext::new(
1457+
self.sess,
1458+
self.hir_forest.untracked_krate(),
1459+
&self.hir_defs,
1460+
self.cstore
1461+
)
14391462
}
14401463

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

src/librustc/ty/query/plumbing.rs

Lines changed: 20 additions & 5 deletions
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

@@ -1192,14 +1193,28 @@ pub fn force_from_dep_node<'tcx>(
11921193
($query:ident, $key:expr) => { force_ex!(tcx, $query, $key) }
11931194
};
11941195

1196+
let force_hir_map = || {
1197+
tcx.force_query::<crate::ty::query::queries::hir_map<'_>>(
1198+
LOCAL_CRATE,
1199+
DUMMY_SP,
1200+
DepNode::new(tcx, DepConstructor::hir_map(LOCAL_CRATE)),
1201+
);
1202+
};
1203+
11951204
rustc_dep_node_force!([dep_node, tcx]
1205+
// Created by the Hir map query
1206+
DepKind::AllLocalTraitImpls |
1207+
DepKind::Krate => force_hir_map(),
1208+
DepKind::HirBody |
1209+
DepKind::Hir => {
1210+
// Ensure the def_id exists
1211+
def_id!();
1212+
force_hir_map();
1213+
}
1214+
11961215
// These are inputs that are expected to be pre-allocated and that
11971216
// should therefore always be red or green already
1198-
DepKind::AllLocalTraitImpls |
1199-
DepKind::Krate |
12001217
DepKind::CrateMetadata |
1201-
DepKind::HirBody |
1202-
DepKind::Hir |
12031218

12041219
// This are anonymous nodes
12051220
DepKind::TraitSelect |

src/librustc_interface/passes.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,7 @@ pub fn prepare_outputs(
762762

763763
pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
764764
providers.analysis = analysis;
765+
providers.hir_map = hir_map;
765766
proc_macro_decls::provide(providers);
766767
plugin::build::provide(providers);
767768
hir::provide(providers);
@@ -807,7 +808,7 @@ impl BoxedGlobalCtxt {
807808

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

829-
// Construct the HIR map
830-
let hir_map = time(sess, "indexing hir", || {
831-
hir::map::map_crate(sess, cstore, &mut hir_forest, &defs)
832-
});
833-
834830
let query_result_on_disk_cache = time(sess, "load query result cache", || {
835831
rustc_incremental::load_query_result_cache(sess)
836832
});
@@ -850,7 +846,8 @@ pub fn create_global_ctxt(
850846
extern_providers,
851847
&arenas,
852848
resolutions,
853-
hir_map,
849+
hir_forest,
850+
defs,
854851
query_result_on_disk_cache,
855852
&crate_name,
856853
tx,
@@ -879,6 +876,20 @@ pub fn create_global_ctxt(
879876
result
880877
}
881878

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

0 commit comments

Comments
 (0)