Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 67ad3c3

Browse files
committedMar 19, 2025
Auto merge of #138705 - oli-obk:hir-split, r=<try>
[perf] Decouple directly accessing a HIR owner from ast lowering r? `@ghost`
2 parents a7fc463 + 5671229 commit 67ad3c3

File tree

9 files changed

+83
-83
lines changed

9 files changed

+83
-83
lines changed
 

‎compiler/rustc_ast_lowering/src/lib.rs

+2-30
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,15 @@ use std::sync::Arc;
4747
use rustc_ast::node_id::NodeMap;
4848
use rustc_ast::{self as ast, *};
4949
use rustc_attr_parsing::{AttributeParser, OmitDoc};
50-
use rustc_data_structures::fingerprint::Fingerprint;
5150
use rustc_data_structures::sorted_map::SortedMap;
52-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
5351
use rustc_data_structures::tagged_ptr::TaggedRef;
5452
use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
5553
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
5654
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
5755
use rustc_hir::{
5856
self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, ParamName, TraitCandidate,
5957
};
60-
use rustc_index::{Idx, IndexSlice, IndexVec};
58+
use rustc_index::{Idx, IndexVec};
6159
use rustc_macros::extension;
6260
use rustc_middle::span_bug;
6361
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
@@ -408,29 +406,6 @@ fn index_crate<'a>(
408406
}
409407
}
410408

411-
/// Compute the hash for the HIR of the full crate.
412-
/// This hash will then be part of the crate_hash which is stored in the metadata.
413-
fn compute_hir_hash(
414-
tcx: TyCtxt<'_>,
415-
owners: &IndexSlice<LocalDefId, hir::MaybeOwner<'_>>,
416-
) -> Fingerprint {
417-
let mut hir_body_nodes: Vec<_> = owners
418-
.iter_enumerated()
419-
.filter_map(|(def_id, info)| {
420-
let info = info.as_owner()?;
421-
let def_path_hash = tcx.hir_def_path_hash(def_id);
422-
Some((def_path_hash, info))
423-
})
424-
.collect();
425-
hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
426-
427-
tcx.with_stable_hashing_context(|mut hcx| {
428-
let mut stable_hasher = StableHasher::new();
429-
hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher);
430-
stable_hasher.finish()
431-
})
432-
}
433-
434409
pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
435410
let sess = tcx.sess;
436411
// Queries that borrow `resolver_for_lowering`.
@@ -460,10 +435,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
460435
drop(ast_index);
461436
sess.time("drop_ast", || drop(krate));
462437

463-
// Don't hash unless necessary, because it's expensive.
464-
let opt_hir_hash =
465-
if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
466-
hir::Crate { owners, opt_hir_hash }
438+
hir::Crate { owners }
467439
}
468440

469441
#[derive(Copy, Clone, PartialEq, Debug)]

‎compiler/rustc_hir/src/definitions.rs

+4
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ impl DefPathTable {
9191
DefPathHash::new(self.stable_crate_id, hash)
9292
}
9393

94+
pub fn def_keys(&self) -> impl Iterator<Item = DefIndex> + ExactSizeIterator {
95+
self.index_to_key.iter_enumerated().map(|(index, _)| index)
96+
}
97+
9498
pub fn enumerated_keys_and_path_hashes(
9599
&self,
96100
) -> impl Iterator<Item = (DefIndex, &DefKey, DefPathHash)> + ExactSizeIterator {

‎compiler/rustc_hir/src/hir.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -1314,11 +1314,15 @@ pub struct AttributeMap<'tcx> {
13141314
}
13151315

13161316
impl<'tcx> AttributeMap<'tcx> {
1317-
pub const EMPTY: &'static AttributeMap<'static> = &AttributeMap {
1318-
map: SortedMap::new(),
1319-
opt_hash: Some(Fingerprint::ZERO),
1320-
define_opaque: None,
1321-
};
1317+
pub const EMPTY: &'static AttributeMap<'static> = &Self::empty();
1318+
1319+
pub const fn empty() -> AttributeMap<'static> {
1320+
AttributeMap {
1321+
map: SortedMap::new(),
1322+
opt_hash: Some(Fingerprint::ZERO),
1323+
define_opaque: None,
1324+
}
1325+
}
13221326

13231327
#[inline]
13241328
pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
@@ -1421,8 +1425,6 @@ impl<'tcx> MaybeOwner<'tcx> {
14211425
#[derive(Debug)]
14221426
pub struct Crate<'hir> {
14231427
pub owners: IndexVec<LocalDefId, MaybeOwner<'hir>>,
1424-
// Only present when incr. comp. is enabled.
1425-
pub opt_hir_hash: Option<Fingerprint>,
14261428
}
14271429

14281430
#[derive(Debug, Clone, Copy, HashStable_Generic)]

‎compiler/rustc_hir/src/stable_hash_impls.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_span::def_id::DefPathHash;
33

44
use crate::HashIgnoredAttrId;
55
use crate::hir::{
6-
AttributeMap, BodyId, Crate, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId,
6+
AttributeMap, BodyId, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId,
77
};
88
use crate::hir_id::{HirId, ItemLocalId};
99

@@ -111,13 +111,6 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for AttributeMap
111111
}
112112
}
113113

114-
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Crate<'_> {
115-
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
116-
let Crate { owners: _, opt_hir_hash } = self;
117-
opt_hir_hash.unwrap().hash_stable(hcx, hasher)
118-
}
119-
}
120-
121114
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for HashIgnoredAttrId {
122115
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
123116
hcx.hash_attr_id(self, hasher)

‎compiler/rustc_middle/src/arena.rs

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ macro_rules! arena_types {
116116
[decode] specialization_graph: rustc_middle::traits::specialization_graph::Graph,
117117
[] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls,
118118
[] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>,
119+
[] owner_info: rustc_hir::OwnerInfo<'tcx>,
119120
]);
120121
)
121122
}

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

+35-12
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
55
use rustc_data_structures::svh::Svh;
66
use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, try_par_for_each_in};
77
use rustc_hir::def::{DefKind, Res};
8-
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
9-
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
8+
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
9+
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
1010
use rustc_hir::intravisit::Visitor;
1111
use rustc_hir::*;
1212
use rustc_hir_pretty as pprust_hir;
@@ -405,9 +405,8 @@ impl<'tcx> TyCtxt<'tcx> {
405405
where
406406
V: Visitor<'tcx>,
407407
{
408-
let krate = self.hir_crate(());
409-
for info in krate.owners.iter() {
410-
if let MaybeOwner::Owner(info) = info {
408+
for def_id in self.hir_crate_items(()).definitions().chain([CRATE_DEF_ID]) {
409+
if let MaybeOwner::Owner(info) = self.hir_owner(def_id) {
411410
for attrs in info.attrs.map.values() {
412411
walk_list!(visitor, visit_attribute, *attrs);
413412
}
@@ -1130,9 +1129,32 @@ impl<'tcx> pprust_hir::PpAnn for TyCtxt<'tcx> {
11301129
}
11311130
}
11321131

1132+
/// Compute the hash for the HIR of the full crate.
1133+
/// This hash will then be part of the crate_hash which is stored in the metadata.
1134+
fn compute_hir_hash(tcx: TyCtxt<'_>, definitions: &Definitions) -> Fingerprint {
1135+
let mut hir_body_nodes: Vec<_> = definitions
1136+
.def_path_table()
1137+
.def_keys()
1138+
.filter_map(|local_def_index| {
1139+
let def_id = LocalDefId { local_def_index };
1140+
let info = tcx.hir_owner(def_id);
1141+
let info = info.as_owner()?;
1142+
let def_path_hash = tcx.hir_def_path_hash(def_id);
1143+
Some((def_path_hash, info))
1144+
})
1145+
.collect();
1146+
hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
1147+
1148+
tcx.with_stable_hashing_context(|mut hcx| {
1149+
let mut stable_hasher = StableHasher::new();
1150+
hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher);
1151+
stable_hasher.finish()
1152+
})
1153+
}
1154+
11331155
pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
1134-
let krate = tcx.hir_crate(());
1135-
let hir_body_hash = krate.opt_hir_hash.expect("HIR hash missing while computing crate hash");
1156+
let definitions = tcx.untracked().definitions.freeze();
1157+
let hir_body_hash = compute_hir_hash(tcx, definitions);
11361158

11371159
let upstream_crates = upstream_crates(tcx);
11381160

@@ -1175,11 +1197,12 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
11751197
source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
11761198
debugger_visualizers.hash_stable(&mut hcx, &mut stable_hasher);
11771199
if tcx.sess.opts.incremental.is_some() {
1178-
let definitions = tcx.untracked().definitions.freeze();
1179-
let mut owner_spans: Vec<_> = krate
1180-
.owners
1181-
.iter_enumerated()
1182-
.filter_map(|(def_id, info)| {
1200+
let mut owner_spans: Vec<_> = definitions
1201+
.def_path_table()
1202+
.def_keys()
1203+
.filter_map(|local_def_index| {
1204+
let def_id = LocalDefId { local_def_index };
1205+
let info = tcx.hir_owner(def_id);
11831206
let _ = info.as_owner()?;
11841207
let def_path_hash = definitions.def_path_hash(def_id);
11851208
let span = tcx.source_span(def_id);

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

+10-10
Original file line numberDiff line numberDiff line change
@@ -181,19 +181,21 @@ pub fn provide(providers: &mut Providers) {
181181
providers.hir_crate_items = map::hir_crate_items;
182182
providers.crate_hash = map::crate_hash;
183183
providers.hir_module_items = map::hir_module_items;
184-
providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owners[def_id] {
184+
providers.hir_owner =
185+
|tcx, def_id| tcx.hir_crate(()).owners.get(def_id).copied().unwrap_or(MaybeOwner::Phantom);
186+
providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_owner(def_id) {
185187
MaybeOwner::Owner(_) => HirId::make_owner(def_id),
186188
MaybeOwner::NonOwner(hir_id) => hir_id,
187189
MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id),
188190
};
189-
providers.opt_hir_owner_nodes =
190-
|tcx, id| tcx.hir_crate(()).owners.get(id)?.as_owner().map(|i| &i.nodes);
191+
providers.opt_hir_owner_nodes = |tcx, id| tcx.hir_owner(id).as_owner().map(|i| &i.nodes);
191192
providers.hir_owner_parent = |tcx, owner_id| {
192193
tcx.opt_local_parent(owner_id.def_id).map_or(CRATE_HIR_ID, |parent_def_id| {
193194
let parent_owner_id = tcx.local_def_id_to_hir_id(parent_def_id).owner;
194195
HirId {
195196
owner: parent_owner_id,
196-
local_id: tcx.hir_crate(()).owners[parent_owner_id.def_id]
197+
local_id: tcx
198+
.hir_owner(parent_owner_id.def_id)
197199
.unwrap()
198200
.parenting
199201
.get(&owner_id.def_id)
@@ -202,9 +204,8 @@ pub fn provide(providers: &mut Providers) {
202204
}
203205
})
204206
};
205-
providers.hir_attr_map = |tcx, id| {
206-
tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
207-
};
207+
providers.hir_attr_map =
208+
|tcx, id| tcx.hir_owner(id.def_id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs);
208209
providers.def_span = |tcx, def_id| tcx.hir().span(tcx.local_def_id_to_hir_id(def_id));
209210
providers.def_ident_span = |tcx, def_id| {
210211
let hir_id = tcx.local_def_id_to_hir_id(def_id);
@@ -235,7 +236,6 @@ pub fn provide(providers: &mut Providers) {
235236
providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls;
236237
providers.expn_that_defined =
237238
|tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
238-
providers.in_scope_traits_map = |tcx, id| {
239-
tcx.hir_crate(()).owners[id.def_id].as_owner().map(|owner_info| &owner_info.trait_map)
240-
};
239+
providers.in_scope_traits_map =
240+
|tcx, id| tcx.hir_owner(id.def_id).as_owner().map(|owner_info| &owner_info.trait_map);
241241
}

‎compiler/rustc_middle/src/query/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,16 @@ rustc_queries! {
151151
query hir_crate(key: ()) -> &'tcx Crate<'tcx> {
152152
arena_cache
153153
eval_always
154+
no_hash
154155
desc { "getting the crate HIR" }
155156
}
156157

158+
/// A query decoupling the `hir_crate` query from everything else
159+
query hir_owner(key: LocalDefId) -> rustc_hir::MaybeOwner<'tcx> {
160+
desc { |tcx| "getting HIR of `{}`", tcx.def_path_str(key) }
161+
feedable
162+
}
163+
157164
/// All items in the crate.
158165
query hir_crate_items(_: ()) -> &'tcx rustc_middle::hir::ModuleItems {
159166
arena_cache
@@ -174,7 +181,6 @@ rustc_queries! {
174181
/// Returns HIR ID for the given `LocalDefId`.
175182
query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId {
176183
desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key) }
177-
feedable
178184
}
179185

180186
/// Gives access to the HIR node's parent for the HIR owner `key`.
@@ -191,7 +197,6 @@ rustc_queries! {
191197
/// Avoid calling this query directly.
192198
query opt_hir_owner_nodes(key: LocalDefId) -> Option<&'tcx hir::OwnerNodes<'tcx>> {
193199
desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key) }
194-
feedable
195200
}
196201

197202
/// Gives access to the HIR attributes inside the HIR owner `key`.
@@ -200,7 +205,6 @@ rustc_queries! {
200205
/// Avoid calling this query directly.
201206
query hir_attr_map(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> {
202207
desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) }
203-
feedable
204208
}
205209

206210
/// Returns the *default* of the const pararameter given by `DefId`.

‎compiler/rustc_middle/src/ty/context.rs

+14-13
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
3535
use rustc_hir::definitions::Definitions;
3636
use rustc_hir::intravisit::VisitorExt;
3737
use rustc_hir::lang_items::LangItem;
38-
use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate};
38+
use rustc_hir::{self as hir, Attribute, HirId, MaybeOwner, Node, OwnerInfo, TraitCandidate};
3939
use rustc_index::IndexVec;
4040
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
4141
use rustc_query_system::cache::WithDepNode;
@@ -1282,23 +1282,24 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
12821282

12831283
// Fills in all the important parts needed by HIR queries
12841284
pub fn feed_hir(&self) {
1285-
self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1286-
12871285
let node = hir::OwnerNode::Synthetic;
12881286
let bodies = Default::default();
1289-
let attrs = hir::AttributeMap::EMPTY;
1290-
1287+
let attrs = hir::AttributeMap::empty();
12911288
let (opt_hash_including_bodies, _) = self.tcx.hash_owner_nodes(node, &bodies, &attrs.map);
12921289
let node = node.into();
1293-
self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1294-
opt_hash_including_bodies,
1295-
nodes: IndexVec::from_elem_n(
1296-
hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1297-
1,
1298-
),
1299-
bodies,
1290+
self.hir_owner(MaybeOwner::Owner(self.tcx.arena.alloc(OwnerInfo {
1291+
nodes: hir::OwnerNodes {
1292+
opt_hash_including_bodies,
1293+
nodes: IndexVec::from_elem_n(
1294+
hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1295+
1,
1296+
),
1297+
bodies,
1298+
},
1299+
parenting: Default::default(),
1300+
attrs,
1301+
trait_map: Default::default(),
13001302
})));
1301-
self.feed_owner_id().hir_attr_map(attrs);
13021303
}
13031304
}
13041305

0 commit comments

Comments
 (0)
Please sign in to comment.