Skip to content

Commit 88b1d8a

Browse files
committed
Make index_hir incremental.
1 parent 0212c70 commit 88b1d8a

File tree

6 files changed

+111
-149
lines changed

6 files changed

+111
-149
lines changed

compiler/rustc_hir/src/definitions.rs

+6
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

+1-4
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,7 @@ macro_rules! arena_types {
9292
[] predicates: rustc_middle::ty::PredicateInner<$tcx>,
9393

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

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

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

+64-102
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::arena::Arena;
21
use crate::hir::map::Map;
32
use crate::hir::{IndexedHir, OwnerNodes, ParentedNode};
43
use crate::ich::StableHashingContext;
@@ -7,7 +6,6 @@ use rustc_data_structures::fx::FxHashMap;
76
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
87
use rustc_hir as hir;
98
use rustc_hir::def_id::LocalDefId;
10-
use rustc_hir::def_id::CRATE_DEF_ID;
119
use rustc_hir::definitions;
1210
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
1311
use rustc_hir::*;
@@ -20,25 +18,21 @@ use std::iter::repeat;
2018

2119
/// A visitor that walks over the HIR and collects `Node`s into a HIR map.
2220
pub(super) struct NodeCollector<'a, 'hir> {
23-
arena: &'hir Arena<'hir>,
24-
2521
/// The crate
2622
krate: &'hir Crate<'hir>,
2723

2824
/// Source map
2925
source_map: &'a SourceMap,
3026

31-
map: IndexVec<LocalDefId, Option<&'hir mut OwnerNodes<'hir>>>,
32-
parenting: FxHashMap<LocalDefId, HirId>,
27+
nodes: OwnerNodes<'hir>,
28+
parenting: FxHashMap<LocalDefId, ItemLocalId>,
3329

3430
/// The parent of this node
35-
parent_node: hir::HirId,
31+
parent_node: hir::ItemLocalId,
3632

37-
current_dep_node_owner: LocalDefId,
33+
owner: LocalDefId,
3834

3935
definitions: &'a definitions::Definitions,
40-
41-
hcx: StableHashingContext<'a>,
4236
}
4337

4438
fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V) {
@@ -62,58 +56,47 @@ fn hash_body(
6256
stable_hasher.finish()
6357
}
6458

65-
impl<'a, 'hir> NodeCollector<'a, 'hir> {
66-
pub(super) fn root(
67-
sess: &'a Session,
68-
arena: &'hir Arena<'hir>,
69-
krate: &'hir Crate<'hir>,
70-
definitions: &'a definitions::Definitions,
71-
hcx: StableHashingContext<'a>,
72-
) -> NodeCollector<'a, 'hir> {
73-
let mut collector = NodeCollector {
74-
arena,
75-
krate,
76-
source_map: sess.source_map(),
77-
parent_node: hir::CRATE_HIR_ID,
78-
current_dep_node_owner: CRATE_DEF_ID,
79-
definitions,
80-
hcx,
81-
map: IndexVec::from_fn_n(|_| None, definitions.def_index_count()),
82-
parenting: FxHashMap::default(),
83-
};
84-
collector.insert_owner(CRATE_DEF_ID, OwnerNode::Crate(krate.module()));
85-
86-
collector
87-
}
88-
89-
pub(super) fn finalize_and_compute_crate_hash(mut self) -> IndexedHir<'hir> {
90-
// Insert bodies into the map
91-
for (id, body) in self.krate.bodies.iter() {
92-
let bodies = &mut self.map[id.hir_id.owner].as_mut().unwrap().bodies;
93-
assert!(bodies.insert(id.hir_id.local_id, body).is_none());
94-
}
95-
IndexedHir { map: self.map, parenting: self.parenting }
96-
}
97-
98-
fn insert_owner(&mut self, owner: LocalDefId, node: OwnerNode<'hir>) {
99-
let hash = hash_body(&mut self.hcx, node);
100-
101-
let mut nodes = IndexVec::new();
102-
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: node.into() }));
103-
104-
debug_assert!(self.map[owner].is_none());
105-
self.map[owner] =
106-
Some(self.arena.alloc(OwnerNodes { hash, nodes, bodies: FxHashMap::default() }));
107-
}
59+
pub(super) fn collect(
60+
sess: &'a Session,
61+
krate: &'hir Crate<'hir>,
62+
definitions: &'a definitions::Definitions,
63+
mut hcx: StableHashingContext<'a>,
64+
owner: LocalDefId,
65+
) -> Option<IndexedHir<'hir>> {
66+
let item = *krate.owners.get(owner)?.as_ref()?;
67+
let hash = hash_body(&mut hcx, item);
68+
let mut nodes = IndexVec::new();
69+
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: item.into() }));
70+
let mut collector = NodeCollector {
71+
krate,
72+
source_map: sess.source_map(),
73+
owner,
74+
parent_node: ItemLocalId::new(0),
75+
definitions,
76+
nodes: OwnerNodes { hash, nodes, bodies: FxHashMap::default() },
77+
parenting: FxHashMap::default(),
78+
};
79+
80+
match item {
81+
OwnerNode::Crate(citem) => collector.visit_mod(&citem, citem.inner, hir::CRATE_HIR_ID),
82+
OwnerNode::Item(item) => collector.visit_item(item),
83+
OwnerNode::TraitItem(item) => collector.visit_trait_item(item),
84+
OwnerNode::ImplItem(item) => collector.visit_impl_item(item),
85+
OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
86+
};
87+
88+
Some(IndexedHir { nodes: collector.nodes, parenting: collector.parenting })
89+
}
10890

91+
impl<'a, 'hir> NodeCollector<'a, 'hir> {
10992
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
110-
debug_assert_eq!(self.current_dep_node_owner, hir_id.owner);
93+
debug_assert_eq!(self.owner, hir_id.owner);
11194
debug_assert_ne!(hir_id.local_id.as_u32(), 0);
11295

11396
// Make sure that the DepNode of some node coincides with the HirId
11497
// owner of that node.
11598
if cfg!(debug_assertions) {
116-
if hir_id.owner != self.current_dep_node_owner {
99+
if hir_id.owner != self.owner {
117100
let node_str = match self.definitions.opt_hir_id_to_local_def_id(hir_id) {
118101
Some(def_id) => self.definitions.def_path(def_id).to_string_no_crate_verbose(),
119102
None => format!("{:?}", node),
@@ -125,58 +108,37 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
125108
current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
126109
self.source_map.span_to_diagnostic_string(span),
127110
node_str,
128-
self.definitions
129-
.def_path(self.current_dep_node_owner)
130-
.to_string_no_crate_verbose(),
131-
self.current_dep_node_owner,
111+
self.definitions.def_path(self.owner).to_string_no_crate_verbose(),
112+
self.owner,
132113
self.definitions.def_path(hir_id.owner).to_string_no_crate_verbose(),
133114
hir_id.owner,
134115
)
135116
}
136117
}
137118

138-
let nodes = self.map[hir_id.owner].as_mut().unwrap();
139-
140-
debug_assert_eq!(self.parent_node.owner, self.current_dep_node_owner);
141119
insert_vec_map(
142-
&mut nodes.nodes,
120+
&mut self.nodes.nodes,
143121
hir_id.local_id,
144-
ParentedNode { parent: self.parent_node.local_id, node: node },
122+
ParentedNode { parent: self.parent_node, node: node },
145123
);
146124
}
147125

148126
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
127+
debug_assert_eq!(parent_node_id.owner, self.owner);
149128
let parent_node = self.parent_node;
150-
self.parent_node = parent_node_id;
129+
self.parent_node = parent_node_id.local_id;
151130
f(self);
152131
self.parent_node = parent_node;
153132
}
154133

155-
fn with_dep_node_owner(&mut self, dep_node_owner: LocalDefId, f: impl FnOnce(&mut Self)) {
156-
let prev_owner = self.current_dep_node_owner;
157-
let prev_parent = self.parent_node;
158-
159-
self.current_dep_node_owner = dep_node_owner;
160-
self.parent_node = HirId::make_owner(dep_node_owner);
161-
f(self);
162-
self.current_dep_node_owner = prev_owner;
163-
self.parent_node = prev_parent;
164-
}
165-
166134
fn insert_nested(&mut self, item: LocalDefId) {
167-
#[cfg(debug_assertions)]
168-
{
169-
let dk_parent = self.definitions.def_key(item).parent.unwrap();
170-
let dk_parent = LocalDefId { local_def_index: dk_parent };
171-
let dk_parent = self.definitions.local_def_id_to_hir_id(dk_parent);
172-
debug_assert_eq!(
173-
dk_parent.owner, self.parent_node.owner,
174-
"Different parents for {:?}",
175-
item
176-
)
135+
let dk_parent = self.definitions.def_key(item).parent.unwrap();
136+
let dk_parent = LocalDefId { local_def_index: dk_parent };
137+
let dk_parent = self.definitions.local_def_id_to_hir_id(dk_parent);
138+
debug_assert_eq!(dk_parent.owner, self.owner, "Different parents for {:?}", item);
139+
if dk_parent.local_id != self.parent_node {
140+
self.parenting.insert(item, self.parent_node);
177141
}
178-
179-
assert_eq!(self.parenting.insert(item, self.parent_node), None);
180142
}
181143
}
182144

@@ -194,26 +156,25 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
194156
fn visit_nested_item(&mut self, item: ItemId) {
195157
debug!("visit_nested_item: {:?}", item);
196158
self.insert_nested(item.def_id);
197-
self.visit_item(self.krate.item(item));
198159
}
199160

200161
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
201162
self.insert_nested(item_id.def_id);
202-
self.visit_trait_item(self.krate.trait_item(item_id));
203163
}
204164

205165
fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
206166
self.insert_nested(item_id.def_id);
207-
self.visit_impl_item(self.krate.impl_item(item_id));
208167
}
209168

210169
fn visit_nested_foreign_item(&mut self, foreign_id: ForeignItemId) {
211170
self.insert_nested(foreign_id.def_id);
212-
self.visit_foreign_item(self.krate.foreign_item(foreign_id));
213171
}
214172

215173
fn visit_nested_body(&mut self, id: BodyId) {
216-
self.visit_body(self.krate.body(id));
174+
let body = self.krate.body(id);
175+
debug_assert_eq!(id.hir_id.owner, self.owner);
176+
assert!(self.nodes.bodies.insert(id.hir_id.local_id, body).is_none());
177+
self.visit_body(body);
217178
}
218179

219180
fn visit_param(&mut self, param: &'hir Param<'hir>) {
@@ -226,8 +187,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
226187

227188
fn visit_item(&mut self, i: &'hir Item<'hir>) {
228189
debug!("visit_item: {:?}", i);
229-
self.insert_owner(i.def_id, OwnerNode::Item(i));
230-
self.with_dep_node_owner(i.def_id, |this| {
190+
debug_assert_eq!(i.def_id, self.owner);
191+
self.with_parent(i.hir_id(), |this| {
231192
if let ItemKind::Struct(ref struct_def, _) = i.kind {
232193
// If this is a tuple or unit-like struct, register the constructor.
233194
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
@@ -239,8 +200,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
239200
}
240201

241202
fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) {
242-
self.insert_owner(fi.def_id, OwnerNode::ForeignItem(fi));
243-
self.with_dep_node_owner(fi.def_id, |this| {
203+
debug_assert_eq!(fi.def_id, self.owner);
204+
self.with_parent(fi.hir_id(), |this| {
244205
intravisit::walk_foreign_item(this, fi);
245206
});
246207
}
@@ -257,15 +218,15 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
257218
}
258219

259220
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
260-
self.insert_owner(ti.def_id, OwnerNode::TraitItem(ti));
261-
self.with_dep_node_owner(ti.def_id, |this| {
221+
debug_assert_eq!(ti.def_id, self.owner);
222+
self.with_parent(ti.hir_id(), |this| {
262223
intravisit::walk_trait_item(this, ti);
263224
});
264225
}
265226

266227
fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) {
267-
self.insert_owner(ii.def_id, OwnerNode::ImplItem(ii));
268-
self.with_dep_node_owner(ii.def_id, |this| {
228+
debug_assert_eq!(ii.def_id, self.owner);
229+
self.with_parent(ii.hir_id(), |this| {
269230
intravisit::walk_impl_item(this, ii);
270231
});
271232
}
@@ -353,7 +314,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
353314
s: Span,
354315
id: HirId,
355316
) {
356-
assert_eq!(self.parent_node, id);
317+
assert_eq!(self.owner, id.owner);
318+
assert_eq!(self.parent_node, id.local_id);
357319
intravisit::walk_fn(self, fk, fd, b, s, id);
358320
}
359321

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

+19-27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use self::collector::NodeCollector;
2-
31
use crate::hir::{AttributeMap, IndexedHir, Owner};
42
use crate::ty::TyCtxt;
53
use rustc_ast as ast;
@@ -306,7 +304,7 @@ impl<'hir> Map<'hir> {
306304
}
307305

308306
pub fn get_parent_node(&self, hir_id: HirId) -> HirId {
309-
self.find_parent_node(hir_id).unwrap_or(CRATE_HIR_ID)
307+
self.find_parent_node(hir_id).unwrap()
310308
}
311309

312310
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
@@ -938,38 +936,31 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
938936
}
939937
}
940938

941-
pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexedHir<'tcx> {
942-
let _prof_timer = tcx.sess.prof.generic_activity("build_hir_map");
943-
944-
// We can access untracked state since we are an eval_always query.
945-
let hcx = tcx.create_stable_hashing_context();
946-
let mut collector = NodeCollector::root(
939+
pub(super) fn index_hir<'tcx>(
940+
tcx: TyCtxt<'tcx>,
941+
owner: LocalDefId,
942+
) -> Option<&'tcx IndexedHir<'tcx>> {
943+
let map = collector::collect(
947944
tcx.sess,
948-
&**tcx.arena,
949945
tcx.untracked_crate,
950946
&tcx.untracked_resolutions.definitions,
951-
hcx,
952-
);
953-
let top_mod = tcx.untracked_crate.module();
954-
collector.visit_mod(top_mod, top_mod.inner, CRATE_HIR_ID);
947+
tcx.create_stable_hashing_context(),
948+
owner,
949+
)?;
955950

956-
let map = collector.finalize_and_compute_crate_hash();
957-
tcx.arena.alloc(map)
951+
Some(&*tcx.arena.alloc(map))
958952
}
959953

960954
pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
961-
assert_eq!(crate_num, LOCAL_CRATE);
962-
963-
// We can access untracked state since we are an eval_always query.
964-
let mut hcx = tcx.create_stable_hashing_context();
965-
955+
debug_assert_eq!(crate_num, LOCAL_CRATE);
966956
let mut hir_body_nodes: Vec<_> = tcx
967-
.index_hir(())
968-
.map
969-
.iter_enumerated()
970-
.filter_map(|(def_id, hod)| {
971-
let def_path_hash = tcx.untracked_resolutions.definitions.def_path_hash(def_id);
972-
let hash = hod.as_ref()?.hash;
957+
.untracked_resolutions
958+
.definitions
959+
.def_path_table()
960+
.all_def_path_hashes_and_def_ids()
961+
.filter_map(|(def_path_hash, local_def_index)| {
962+
let def_id = LocalDefId { local_def_index };
963+
let hash = tcx.index_hir(def_id).as_ref()?.nodes.hash;
973964
Some((def_path_hash, hash, def_id))
974965
})
975966
.collect();
@@ -993,6 +984,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
993984

994985
source_file_names.sort_unstable();
995986

987+
let mut hcx = tcx.create_stable_hashing_context();
996988
let mut stable_hasher = StableHasher::new();
997989
for (def_path_hash, fingerprint, def_id) in hir_body_nodes.iter() {
998990
def_path_hash.0.hash_stable(&mut hcx, &mut stable_hasher);

0 commit comments

Comments
 (0)