Skip to content

Commit c09eaea

Browse files
committed
Make index_hir incremental.
1 parent ed3c8e8 commit c09eaea

File tree

6 files changed

+115
-142
lines changed

6 files changed

+115
-142
lines changed

compiler/rustc_hir/src/definitions.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ impl DefPathTable {
9292
.iter_enumerated()
9393
.map(move |(index, key)| (index, key, &self.def_path_hashes[index]))
9494
}
95+
96+
pub fn all_def_path_hashes_and_def_ids(
97+
&self,
98+
) -> impl Iterator<Item = (&DefPathHash, DefIndex)> + '_ {
99+
self.def_path_hashes.iter_enumerated().map(move |(index, hash)| (hash, index))
100+
}
95101
}
96102

97103
/// The definition table containing node definitions.

compiler/rustc_middle/src/arena.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,7 @@ macro_rules! arena_types {
9393
[] predicates: rustc_middle::ty::PredicateInner<$tcx>,
9494

9595
// HIR query types
96-
[few] indexed_hir: rustc_middle::hir::IndexedHir<$tcx>,
97-
[few] hir_definitions: rustc_hir::definitions::Definitions,
98-
[] hir_owner: rustc_middle::hir::Owner<$tcx>,
99-
[] hir_owner_nodes: rustc_middle::hir::OwnerNodes<$tcx>,
96+
[] indexed_hir: rustc_middle::hir::IndexedHir<$tcx>,
10097

10198
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
10299
// since we need to allocate this type on both the `rustc_hir` arena

compiler/rustc_middle/src/hir/map/collector.rs

Lines changed: 68 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
use crate::arena::Arena;
21
use crate::hir::map::Map;
32
use crate::hir::{IndexedHir, OwnerNodes, ParentedNode};
43
use rustc_data_structures::fx::FxHashMap;
54
use rustc_hir as hir;
65
use rustc_hir::def_id::LocalDefId;
7-
use rustc_hir::def_id::CRATE_DEF_ID;
86
use rustc_hir::definitions;
97
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
108
use rustc_hir::*;
@@ -17,21 +15,19 @@ use std::iter::repeat;
1715

1816
/// A visitor that walks over the HIR and collects `Node`s into a HIR map.
1917
pub(super) struct NodeCollector<'a, 'hir> {
20-
arena: &'hir Arena<'hir>,
21-
2218
/// The crate
2319
krate: &'hir Crate<'hir>,
2420

2521
/// Source map
2622
source_map: &'a SourceMap,
2723

28-
map: IndexVec<LocalDefId, Option<&'hir mut OwnerNodes<'hir>>>,
29-
parenting: FxHashMap<LocalDefId, HirId>,
24+
nodes: OwnerNodes<'hir>,
25+
parenting: FxHashMap<LocalDefId, ItemLocalId>,
3026

3127
/// The parent of this node
32-
parent_node: hir::HirId,
28+
parent_node: hir::ItemLocalId,
3329

34-
current_dep_node_owner: LocalDefId,
30+
owner: LocalDefId,
3531

3632
definitions: &'a definitions::Definitions,
3733
}
@@ -46,53 +42,51 @@ fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V
4642
map[k] = Some(v);
4743
}
4844

49-
impl<'a, 'hir: 'a> NodeCollector<'a, 'hir> {
50-
pub(super) fn root(
51-
sess: &'a Session,
52-
arena: &'hir Arena<'hir>,
53-
krate: &'hir Crate<'hir>,
54-
definitions: &'a definitions::Definitions,
55-
) -> NodeCollector<'a, 'hir> {
56-
let mut collector = NodeCollector {
57-
arena,
58-
krate,
59-
source_map: sess.source_map(),
60-
parent_node: hir::CRATE_HIR_ID,
61-
current_dep_node_owner: CRATE_DEF_ID,
62-
definitions,
63-
map: IndexVec::from_fn_n(|_| None, definitions.def_index_count()),
64-
parenting: FxHashMap::default(),
65-
};
66-
collector.insert_owner(CRATE_DEF_ID, OwnerNode::Crate(krate.module()));
67-
68-
collector
69-
}
70-
71-
pub(super) fn finalize_and_compute_crate_hash(self) -> IndexedHir<'hir> {
72-
IndexedHir { map: self.map, parenting: self.parenting }
73-
}
74-
75-
fn insert_owner(&mut self, owner: LocalDefId, node: OwnerNode<'hir>) {
76-
let mut nodes = IndexVec::new();
77-
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: node.into() }));
78-
79-
let info = self.krate.owners[owner].as_ref().unwrap();
80-
let hash = info.hash;
81-
let node_hash = info.node_hash;
82-
let bodies = &info.bodies;
83-
84-
debug_assert!(self.map[owner].is_none());
85-
self.map[owner] = Some(self.arena.alloc(OwnerNodes { hash, node_hash, nodes, bodies }));
86-
}
45+
pub(super) fn collect<'a, 'hir: 'a>(
46+
sess: &'a Session,
47+
krate: &'hir Crate<'hir>,
48+
definitions: &'a definitions::Definitions,
49+
owner: LocalDefId,
50+
) -> Option<IndexedHir<'hir>> {
51+
let info = krate.owners.get(owner)?.as_ref()?;
52+
let item = info.node;
53+
let mut nodes = IndexVec::new();
54+
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: item.into() }));
55+
let mut collector = NodeCollector {
56+
krate,
57+
source_map: sess.source_map(),
58+
owner,
59+
parent_node: ItemLocalId::new(0),
60+
definitions,
61+
nodes: OwnerNodes {
62+
hash: info.hash,
63+
node_hash: info.node_hash,
64+
nodes,
65+
bodies: &info.bodies,
66+
},
67+
parenting: FxHashMap::default(),
68+
};
69+
70+
match item {
71+
OwnerNode::Crate(citem) => collector.visit_mod(&citem, citem.inner, hir::CRATE_HIR_ID),
72+
OwnerNode::Item(item) => collector.visit_item(item),
73+
OwnerNode::TraitItem(item) => collector.visit_trait_item(item),
74+
OwnerNode::ImplItem(item) => collector.visit_impl_item(item),
75+
OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
76+
};
77+
78+
Some(IndexedHir { nodes: collector.nodes, parenting: collector.parenting })
79+
}
8780

81+
impl<'a, 'hir> NodeCollector<'a, 'hir> {
8882
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
89-
debug_assert_eq!(self.current_dep_node_owner, hir_id.owner);
83+
debug_assert_eq!(self.owner, hir_id.owner);
9084
debug_assert_ne!(hir_id.local_id.as_u32(), 0);
9185

9286
// Make sure that the DepNode of some node coincides with the HirId
9387
// owner of that node.
9488
if cfg!(debug_assertions) {
95-
if hir_id.owner != self.current_dep_node_owner {
89+
if hir_id.owner != self.owner {
9690
let node_str = match self.definitions.opt_hir_id_to_local_def_id(hir_id) {
9791
Some(def_id) => self.definitions.def_path(def_id).to_string_no_crate_verbose(),
9892
None => format!("{:?}", node),
@@ -104,62 +98,41 @@ impl<'a, 'hir: 'a> NodeCollector<'a, 'hir> {
10498
current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
10599
self.source_map.span_to_diagnostic_string(span),
106100
node_str,
107-
self.definitions
108-
.def_path(self.current_dep_node_owner)
109-
.to_string_no_crate_verbose(),
110-
self.current_dep_node_owner,
101+
self.definitions.def_path(self.owner).to_string_no_crate_verbose(),
102+
self.owner,
111103
self.definitions.def_path(hir_id.owner).to_string_no_crate_verbose(),
112104
hir_id.owner,
113105
)
114106
}
115107
}
116108

117-
let nodes = self.map[hir_id.owner].as_mut().unwrap();
118-
119-
debug_assert_eq!(self.parent_node.owner, self.current_dep_node_owner);
120109
insert_vec_map(
121-
&mut nodes.nodes,
110+
&mut self.nodes.nodes,
122111
hir_id.local_id,
123-
ParentedNode { parent: self.parent_node.local_id, node: node },
112+
ParentedNode { parent: self.parent_node, node: node },
124113
);
125114
}
126115

127116
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
117+
debug_assert_eq!(parent_node_id.owner, self.owner);
128118
let parent_node = self.parent_node;
129-
self.parent_node = parent_node_id;
119+
self.parent_node = parent_node_id.local_id;
130120
f(self);
131121
self.parent_node = parent_node;
132122
}
133123

134-
fn with_dep_node_owner(&mut self, dep_node_owner: LocalDefId, f: impl FnOnce(&mut Self)) {
135-
let prev_owner = self.current_dep_node_owner;
136-
let prev_parent = self.parent_node;
137-
138-
self.current_dep_node_owner = dep_node_owner;
139-
self.parent_node = HirId::make_owner(dep_node_owner);
140-
f(self);
141-
self.current_dep_node_owner = prev_owner;
142-
self.parent_node = prev_parent;
143-
}
144-
145124
fn insert_nested(&mut self, item: LocalDefId) {
146-
#[cfg(debug_assertions)]
147-
{
148-
let dk_parent = self.definitions.def_key(item).parent.unwrap();
149-
let dk_parent = LocalDefId { local_def_index: dk_parent };
150-
let dk_parent = self.definitions.local_def_id_to_hir_id(dk_parent);
151-
debug_assert_eq!(
152-
dk_parent.owner, self.parent_node.owner,
153-
"Different parents for {:?}",
154-
item
155-
)
125+
let dk_parent = self.definitions.def_key(item).parent.unwrap();
126+
let dk_parent = LocalDefId { local_def_index: dk_parent };
127+
let dk_parent = self.definitions.local_def_id_to_hir_id(dk_parent);
128+
debug_assert_eq!(dk_parent.owner, self.owner, "Different parents for {:?}", item);
129+
if dk_parent.local_id != self.parent_node {
130+
self.parenting.insert(item, self.parent_node);
156131
}
157-
158-
assert_eq!(self.parenting.insert(item, self.parent_node), None);
159132
}
160133
}
161134

162-
impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
135+
impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
163136
type Map = Map<'hir>;
164137

165138
/// Because we want to track parent items and so forth, enable
@@ -173,26 +146,24 @@ impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
173146
fn visit_nested_item(&mut self, item: ItemId) {
174147
debug!("visit_nested_item: {:?}", item);
175148
self.insert_nested(item.def_id);
176-
self.visit_item(self.krate.item(item));
177149
}
178150

179151
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
180152
self.insert_nested(item_id.def_id);
181-
self.visit_trait_item(self.krate.trait_item(item_id));
182153
}
183154

184155
fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
185156
self.insert_nested(item_id.def_id);
186-
self.visit_impl_item(self.krate.impl_item(item_id));
187157
}
188158

189159
fn visit_nested_foreign_item(&mut self, foreign_id: ForeignItemId) {
190160
self.insert_nested(foreign_id.def_id);
191-
self.visit_foreign_item(self.krate.foreign_item(foreign_id));
192161
}
193162

194163
fn visit_nested_body(&mut self, id: BodyId) {
195-
self.visit_body(self.krate.body(id));
164+
let body = self.krate.body(id);
165+
debug_assert_eq!(id.hir_id.owner, self.owner);
166+
self.visit_body(body);
196167
}
197168

198169
fn visit_param(&mut self, param: &'hir Param<'hir>) {
@@ -205,8 +176,8 @@ impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
205176

206177
fn visit_item(&mut self, i: &'hir Item<'hir>) {
207178
debug!("visit_item: {:?}", i);
208-
self.insert_owner(i.def_id, OwnerNode::Item(i));
209-
self.with_dep_node_owner(i.def_id, |this| {
179+
debug_assert_eq!(i.def_id, self.owner);
180+
self.with_parent(i.hir_id(), |this| {
210181
if let ItemKind::Struct(ref struct_def, _) = i.kind {
211182
// If this is a tuple or unit-like struct, register the constructor.
212183
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
@@ -218,8 +189,8 @@ impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
218189
}
219190

220191
fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) {
221-
self.insert_owner(fi.def_id, OwnerNode::ForeignItem(fi));
222-
self.with_dep_node_owner(fi.def_id, |this| {
192+
debug_assert_eq!(fi.def_id, self.owner);
193+
self.with_parent(fi.hir_id(), |this| {
223194
intravisit::walk_foreign_item(this, fi);
224195
});
225196
}
@@ -236,15 +207,15 @@ impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
236207
}
237208

238209
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
239-
self.insert_owner(ti.def_id, OwnerNode::TraitItem(ti));
240-
self.with_dep_node_owner(ti.def_id, |this| {
210+
debug_assert_eq!(ti.def_id, self.owner);
211+
self.with_parent(ti.hir_id(), |this| {
241212
intravisit::walk_trait_item(this, ti);
242213
});
243214
}
244215

245216
fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) {
246-
self.insert_owner(ii.def_id, OwnerNode::ImplItem(ii));
247-
self.with_dep_node_owner(ii.def_id, |this| {
217+
debug_assert_eq!(ii.def_id, self.owner);
218+
self.with_parent(ii.hir_id(), |this| {
248219
intravisit::walk_impl_item(this, ii);
249220
});
250221
}
@@ -332,7 +303,8 @@ impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
332303
s: Span,
333304
id: HirId,
334305
) {
335-
assert_eq!(self.parent_node, id);
306+
assert_eq!(self.owner, id.owner);
307+
assert_eq!(self.parent_node, id.local_id);
336308
intravisit::walk_fn(self, fk, fd, b, s, id);
337309
}
338310

compiler/rustc_middle/src/hir/map/mod.rs

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use self::collector::NodeCollector;
2-
31
use crate::hir::{IndexedHir, ModuleItems, Owner};
42
use crate::ty::TyCtxt;
53
use rustc_ast as ast;
@@ -318,7 +316,7 @@ impl<'hir> Map<'hir> {
318316
}
319317

320318
pub fn get_parent_node(&self, hir_id: HirId) -> HirId {
321-
self.find_parent_node(hir_id).unwrap_or(CRATE_HIR_ID)
319+
self.find_parent_node(hir_id).unwrap()
322320
}
323321

324322
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
@@ -1067,36 +1065,30 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
10671065
}
10681066
}
10691067

1070-
pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexedHir<'tcx> {
1071-
let _prof_timer = tcx.sess.prof.generic_activity("build_hir_map");
1072-
1073-
// We can access untracked state since we are an eval_always query.
1074-
let mut collector = NodeCollector::root(
1068+
pub(super) fn index_hir<'tcx>(
1069+
tcx: TyCtxt<'tcx>,
1070+
owner: LocalDefId,
1071+
) -> Option<&'tcx IndexedHir<'tcx>> {
1072+
let map = collector::collect(
10751073
tcx.sess,
1076-
&**tcx.arena,
10771074
tcx.untracked_crate,
10781075
&tcx.untracked_resolutions.definitions,
1079-
);
1080-
let top_mod = tcx.untracked_crate.module();
1081-
collector.visit_mod(top_mod, top_mod.inner, CRATE_HIR_ID);
1076+
owner,
1077+
)?;
10821078

1083-
let map = collector.finalize_and_compute_crate_hash();
1084-
tcx.arena.alloc(map)
1079+
Some(&*tcx.arena.alloc(map))
10851080
}
10861081

10871082
pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
1088-
assert_eq!(crate_num, LOCAL_CRATE);
1089-
1090-
// We can access untracked state since we are an eval_always query.
1091-
let mut hcx = tcx.create_stable_hashing_context();
1092-
1083+
debug_assert_eq!(crate_num, LOCAL_CRATE);
10931084
let mut hir_body_nodes: Vec<_> = tcx
1094-
.index_hir(())
1095-
.map
1096-
.iter_enumerated()
1097-
.filter_map(|(def_id, hod)| {
1098-
let def_path_hash = tcx.untracked_resolutions.definitions.def_path_hash(def_id);
1099-
let hash = hod.as_ref()?.hash;
1085+
.untracked_resolutions
1086+
.definitions
1087+
.def_path_table()
1088+
.all_def_path_hashes_and_def_ids()
1089+
.filter_map(|(def_path_hash, local_def_index)| {
1090+
let def_id = LocalDefId { local_def_index };
1091+
let hash = tcx.index_hir(def_id).as_ref()?.nodes.hash;
11001092
Some((def_path_hash, hash, def_id))
11011093
})
11021094
.collect();
@@ -1120,6 +1112,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
11201112

11211113
source_file_names.sort_unstable();
11221114

1115+
let mut hcx = tcx.create_stable_hashing_context();
11231116
let mut stable_hasher = StableHasher::new();
11241117
for (def_path_hash, fingerprint, def_id) in hir_body_nodes.iter() {
11251118
def_path_hash.0.hash_stable(&mut hcx, &mut stable_hasher);

0 commit comments

Comments
 (0)