Skip to content

Commit 30e23f6

Browse files
committed
Turn HIR indexing into a query
1 parent 7115263 commit 30e23f6

File tree

8 files changed

+94
-52
lines changed

8 files changed

+94
-52
lines changed

src/librustc/dep_graph/dep_node.rs

+1
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ define_dep_nodes!( <'tcx>
440440
[eval_always] PrivacyAccessLevels(CrateNum),
441441
[eval_always] CheckPrivateInPublic(CrateNum),
442442
[eval_always] Analysis(CrateNum),
443+
[eval_always] HirMap(CrateNum),
443444

444445
// Represents the MIR for a fn; also used as the task node for
445446
// things read/modify that MIR.

src/librustc/dep_graph/graph.rs

-2
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

src/librustc/hir/map/mod.rs

+15-21
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};
@@ -1231,31 +1229,27 @@ impl Named for StructField { fn name(&self) -> Name { self.ident.name } }
12311229
impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } }
12321230
impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } }
12331231

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

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

1246-
let mut collector = NodeCollector::root(sess,
1247-
&forest.krate,
1248-
&forest.dep_graph,
1249-
&definitions,
1240+
let mut collector = NodeCollector::root(tcx.sess,
1241+
&tcx.hir_forest.untracked_krate(),
1242+
&tcx.dep_graph,
1243+
&tcx.hir_defs,
12501244
&hir_to_node_id,
12511245
hcx);
1252-
intravisit::walk_crate(&mut collector, &forest.krate);
1246+
intravisit::walk_crate(&mut collector, &tcx.hir_forest.untracked_krate());
12531247

1254-
let crate_disambiguator = sess.local_crate_disambiguator();
1255-
let cmdline_args = sess.opts.dep_tracking_hash();
1248+
let crate_disambiguator = tcx.sess.local_crate_disambiguator();
1249+
let cmdline_args = tcx.sess.opts.dep_tracking_hash();
12561250
collector.finalize_and_compute_crate_hash(
12571251
crate_disambiguator,
1258-
cstore,
1252+
tcx.cstore,
12591253
cmdline_args
12601254
)
12611255
};
@@ -1273,15 +1267,15 @@ pub fn map_crate<'hir>(sess: &crate::session::Session,
12731267
}
12741268

12751269
let map = Map {
1276-
forest,
1277-
dep_graph: forest.dep_graph.clone(),
1270+
forest: &tcx.hir_forest,
1271+
dep_graph: tcx.dep_graph.clone(),
12781272
crate_hash,
12791273
map,
12801274
hir_to_node_id,
1281-
definitions,
1275+
definitions: &tcx.hir_defs,
12821276
};
12831277

1284-
time(sess, "validate hir map", || {
1278+
time(tcx.sess, "validate hir map", || {
12851279
hir_id_validator::check_crate(&map);
12861280
});
12871281

src/librustc/ty/context.rs

+41-18
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

@@ -990,10 +993,10 @@ impl<'gcx> Deref for TyCtxt<'_, 'gcx, '_> {
990993
}
991994

992995
pub struct GlobalCtxt<'tcx> {
993-
global_arenas: &'tcx WorkerLocal<GlobalArenas<'tcx>>,
996+
pub global_arenas: &'tcx WorkerLocal<GlobalArenas<'tcx>>,
994997
global_interners: CtxtInterners<'tcx>,
995998

996-
cstore: &'tcx CrateStoreDyn,
999+
pub(crate) cstore: &'tcx CrateStoreDyn,
9971000

9981001
pub sess: &'tcx Session,
9991002

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

1014-
hir_map: hir_map::Map<'tcx>,
1017+
pub hir_forest: hir::map::Forest,
1018+
1019+
pub hir_defs: hir::map::Definitions,
1020+
1021+
hir_map: AtomicCell<Option<&'tcx hir_map::Map<'tcx>>>,
10151022

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

10861093
#[inline(always)]
10871094
pub fn hir(self) -> &'a hir_map::Map<'gcx> {
1088-
&self.hir_map
1095+
let value = self.hir_map.load();
1096+
if unlikely!(value.is_none()) {
1097+
cold_path(|| {
1098+
let map = self.hir_map(LOCAL_CRATE);
1099+
self.hir_map.store(Some(map));
1100+
map
1101+
})
1102+
} else {
1103+
value.unwrap()
1104+
}
10891105
}
10901106

10911107
pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics {
@@ -1189,7 +1205,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
11891205
extern_providers: ty::query::Providers<'tcx>,
11901206
arenas: &'tcx AllArenas<'tcx>,
11911207
resolutions: ty::Resolutions,
1192-
hir: hir_map::Map<'tcx>,
1208+
hir_forest: hir::map::Forest,
1209+
hir_defs: hir::map::Definitions,
11931210
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
11941211
crate_name: &str,
11951212
tx: mpsc::Sender<Box<dyn Any + Send>>,
@@ -1200,7 +1217,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12001217
});
12011218
let interners = CtxtInterners::new(&arenas.interner);
12021219
let common_types = CommonTypes::new(&interners);
1203-
let dep_graph = hir.dep_graph.clone();
1220+
let dep_graph = hir_forest.dep_graph.clone();
12041221
let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
12051222
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
12061223
providers[LOCAL_CRATE] = local_providers;
@@ -1216,7 +1233,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12161233
upstream_def_path_tables
12171234
.iter()
12181235
.map(|&(cnum, ref rc)| (cnum, &**rc))
1219-
.chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())))
1236+
.chain(iter::once((LOCAL_CRATE, hir_defs.def_path_table())))
12201237
};
12211238

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

12401257
let mut trait_map: FxHashMap<_, Lrc<FxHashMap<_, _>>> = FxHashMap::default();
12411258
for (k, v) in resolutions.trait_map {
1242-
let hir_id = hir.node_to_hir_id(k);
1259+
let hir_id = hir_defs.node_to_hir_id(k);
12431260
let map = trait_map.entry(hir_id.owner).or_default();
12441261
Lrc::get_mut(map).unwrap()
12451262
.insert(hir_id.local_id,
@@ -1258,23 +1275,25 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12581275
(k, Lrc::new(v))
12591276
}).collect(),
12601277
freevars: resolutions.freevars.into_iter().map(|(k, v)| {
1261-
(hir.local_def_id(k), Lrc::new(v))
1278+
(hir_defs.local_def_id(k), Lrc::new(v))
12621279
}).collect(),
12631280
maybe_unused_trait_imports:
12641281
resolutions.maybe_unused_trait_imports
12651282
.into_iter()
1266-
.map(|id| hir.local_def_id(id))
1283+
.map(|id| hir_defs.local_def_id(id))
12671284
.collect(),
12681285
maybe_unused_extern_crates:
12691286
resolutions.maybe_unused_extern_crates
12701287
.into_iter()
1271-
.map(|(id, sp)| (hir.local_def_id(id), sp))
1288+
.map(|(id, sp)| (hir_defs.local_def_id(id), sp))
12721289
.collect(),
12731290
glob_map: resolutions.glob_map.into_iter().map(|(id, names)| {
1274-
(hir.local_def_id(id), names)
1291+
(hir_defs.local_def_id(id), names)
12751292
}).collect(),
12761293
extern_prelude: resolutions.extern_prelude,
1277-
hir_map: hir,
1294+
hir_forest,
1295+
hir_defs,
1296+
hir_map: AtomicCell::new(None),
12781297
def_path_hash_to_def_id,
12791298
queries: query::Queries::new(
12801299
providers,
@@ -1369,7 +1388,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13691388
/// be a non-local `DefPath`.
13701389
pub fn def_path(self, id: DefId) -> hir_map::DefPath {
13711390
if id.is_local() {
1372-
self.hir().def_path(id)
1391+
// FIXME: This is used in some panic path? Don't use hir()
1392+
self.hir_defs.def_path(id.index)
13731393
} else {
13741394
self.cstore.def_path(id)
13751395
}
@@ -1378,7 +1398,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13781398
#[inline]
13791399
pub fn def_path_hash(self, def_id: DefId) -> hir_map::DefPathHash {
13801400
if def_id.is_local() {
1381-
self.hir().definitions().def_path_hash(def_id.index)
1401+
// FIXME: This is used when executing the hir query, can't use hir() here
1402+
self.hir_defs.def_path_hash(def_id.index)
13821403
} else {
13831404
self.cstore.def_path_hash(def_id)
13841405
}
@@ -1417,11 +1438,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
14171438

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

14221445
StableHashingContext::new(self.sess,
14231446
krate,
1424-
self.hir().definitions(),
1447+
&self.hir_defs,
14251448
self.cstore)
14261449
}
14271450

src/librustc/ty/query/config.rs

+6
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::analysis<'tcx> {
623623
}
624624
}
625625

626+
impl<'tcx> QueryDescription<'tcx> for queries::hir_map<'tcx> {
627+
fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
628+
"indexing HIR".into()
629+
}
630+
}
631+
626632
impl<'tcx> QueryDescription<'tcx> for queries::lint_levels<'tcx> {
627633
fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
628634
"computing the lint levels for items in this crate".into()

src/librustc/ty/query/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ pub use self::on_disk_cache::OnDiskCache;
9999
// as they will raise an fatal error on query cycles instead.
100100
define_queries! { <'tcx>
101101
Other {
102+
[no_hash] fn hir_map: HirMap(CrateNum) -> &'tcx hir::map::Map<'tcx>,
103+
102104
/// Run analysis passes on the crate
103105
[] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>,
104106

src/librustc/ty/query/plumbing.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -1187,13 +1187,19 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
11871187
// FIXME(#45015): We should try move this boilerplate code into a macro
11881188
// somehow.
11891189
match dep_node.kind {
1190+
// Created by the Hir map query
1191+
DepKind::AllLocalTraitImpls |
1192+
DepKind::Krate => {
1193+
force!(hir_map, LOCAL_CRATE);
1194+
}
1195+
DepKind::HirBody |
1196+
DepKind::Hir => {
1197+
force!(hir_map, krate!());
1198+
}
1199+
11901200
// These are inputs that are expected to be pre-allocated and that
11911201
// should therefore always be red or green already
1192-
DepKind::AllLocalTraitImpls |
1193-
DepKind::Krate |
11941202
DepKind::CrateMetadata |
1195-
DepKind::HirBody |
1196-
DepKind::Hir |
11971203

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

13671374
DepKind::AllTraitImplementations => {
13681375
force!(all_trait_implementations, krate!());

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);
@@ -805,7 +806,7 @@ impl BoxedGlobalCtxt {
805806

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

827-
// Construct the HIR map
828-
let hir_map = time(sess, "indexing hir", || {
829-
hir::map::map_crate(sess, cstore, &mut hir_forest, &defs)
830-
});
831-
832828
let query_result_on_disk_cache = time(sess, "load query result cache", || {
833829
rustc_incremental::load_query_result_cache(sess)
834830
});
@@ -848,7 +844,8 @@ pub fn create_global_ctxt(
848844
extern_providers,
849845
&arenas,
850846
resolutions,
851-
hir_map,
847+
hir_forest,
848+
defs,
852849
query_result_on_disk_cache,
853850
&crate_name,
854851
tx,
@@ -877,6 +874,20 @@ pub fn create_global_ctxt(
877874
result
878875
}
879876

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

0 commit comments

Comments
 (0)