Skip to content

Commit 792af13

Browse files
committed
Auto merge of rust-lang#138995 - oli-obk:split-resolver, r=<try>
[perf experiment] Split the resolver tables into per-owner tables r? `@ghost` just doing some experiments to see if splitting `hir_crate` is feasible by checking if splitting the resolver's output into per-owner queries is feasible (rust-lang#95004) Basically necessary for rust-lang#138705 as that can't be landed perf-wise while the `hir_crate` query is still a thing
2 parents 19cab6b + 33f5615 commit 792af13

File tree

17 files changed

+372
-241
lines changed

17 files changed

+372
-241
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -482,9 +482,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
482482
let mut generic_args = ThinVec::new();
483483
for (idx, arg) in args.iter().cloned().enumerate() {
484484
if legacy_args_idx.contains(&idx) {
485-
let parent_def_id = self.current_hir_id_owner.def_id;
486485
let node_id = self.next_node_id();
487-
self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, f.span);
486+
self.create_def(node_id, None, DefKind::AnonConst, f.span);
488487
let mut visitor = WillCreateDefIdsVisitor {};
489488
let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) {
490489
AstP(Expr {

compiler/rustc_ast_lowering/src/item.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
8888

8989
#[instrument(level = "debug", skip(self, c))]
9090
fn lower_crate(&mut self, c: &Crate) {
91-
debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
91+
debug_assert_eq!(
92+
self.resolver.owners[&CRATE_NODE_ID].node_id_to_def_id[&CRATE_NODE_ID],
93+
CRATE_DEF_ID
94+
);
9295
self.with_lctx(CRATE_NODE_ID, |lctx| {
9396
let module = lctx.lower_mod(&c.items, &c.spans);
9497
// FIXME(jdonszelman): is dummy span ever a problem here?
@@ -102,6 +105,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
102105
self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
103106
}
104107

108+
#[instrument(level = "debug", skip(self))]
105109
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
106110
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
107111
}

compiler/rustc_ast_lowering/src/lib.rs

+58-15
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#![doc(rust_logo)]
3737
#![feature(assert_matches)]
3838
#![feature(box_patterns)]
39+
#![feature(closure_track_caller)]
3940
#![feature(exact_size_is_empty)]
4041
#![feature(if_let_guard)]
4142
#![feature(let_chains)]
@@ -60,7 +61,7 @@ use rustc_hir::{
6061
use rustc_index::{Idx, IndexSlice, IndexVec};
6162
use rustc_macros::extension;
6263
use rustc_middle::span_bug;
63-
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
64+
use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt};
6465
use rustc_session::parse::{add_feature_diagnostics, feature_err};
6566
use rustc_span::symbol::{Ident, Symbol, kw, sym};
6667
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
@@ -124,6 +125,7 @@ struct LoweringContext<'a, 'hir> {
124125
is_in_dyn_type: bool,
125126

126127
current_hir_id_owner: hir::OwnerId,
128+
current_ast_id_owner: NodeId,
127129
item_local_id_counter: hir::ItemLocalId,
128130
trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
129131

@@ -162,6 +164,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
162164
children: Vec::default(),
163165
contract_ensures: None,
164166
current_hir_id_owner: hir::CRATE_OWNER_ID,
167+
current_ast_id_owner: CRATE_NODE_ID,
165168
item_local_id_counter: hir::ItemLocalId::ZERO,
166169
ident_and_label_to_local_id: Default::default(),
167170
#[cfg(debug_assertions)]
@@ -253,7 +256,7 @@ impl ResolverAstLowering {
253256
///
254257
/// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring
255258
/// should appear at the enclosing `PolyTraitRef`.
256-
fn extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
259+
fn extra_lifetime_params(&self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
257260
self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default()
258261
}
259262
}
@@ -364,17 +367,22 @@ enum AstOwner<'a> {
364367
}
365368

366369
fn index_crate<'a>(
367-
node_id_to_def_id: &NodeMap<LocalDefId>,
370+
owners: &NodeMap<PerOwnerResolverData>,
368371
krate: &'a Crate,
369372
) -> IndexVec<LocalDefId, AstOwner<'a>> {
370-
let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() };
373+
let mut indexer = Indexer {
374+
owners,
375+
node_id_to_def_id: &owners[&CRATE_NODE_ID].node_id_to_def_id,
376+
index: IndexVec::new(),
377+
};
371378
*indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) =
372379
AstOwner::Crate(krate);
373380
visit::walk_crate(&mut indexer, krate);
374381
return indexer.index;
375382

376383
struct Indexer<'s, 'a> {
377384
node_id_to_def_id: &'s NodeMap<LocalDefId>,
385+
owners: &'s NodeMap<PerOwnerResolverData>,
378386
index: IndexVec<LocalDefId, AstOwner<'a>>,
379387
}
380388

@@ -385,23 +393,38 @@ fn index_crate<'a>(
385393
}
386394

387395
fn visit_item(&mut self, item: &'a ast::Item) {
396+
let old = std::mem::replace(
397+
&mut self.node_id_to_def_id,
398+
&self.owners[&item.id].node_id_to_def_id,
399+
);
388400
let def_id = self.node_id_to_def_id[&item.id];
389401
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item);
390-
visit::walk_item(self, item)
402+
visit::walk_item(self, item);
403+
self.node_id_to_def_id = old;
391404
}
392405

393406
fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {
407+
let old = std::mem::replace(
408+
&mut self.node_id_to_def_id,
409+
&self.owners[&item.id].node_id_to_def_id,
410+
);
394411
let def_id = self.node_id_to_def_id[&item.id];
395412
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
396413
AstOwner::AssocItem(item, ctxt);
397414
visit::walk_assoc_item(self, item, ctxt);
415+
self.node_id_to_def_id = old;
398416
}
399417

400418
fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {
419+
let old = std::mem::replace(
420+
&mut self.node_id_to_def_id,
421+
&self.owners[&item.id].node_id_to_def_id,
422+
);
401423
let def_id = self.node_id_to_def_id[&item.id];
402424
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
403425
AstOwner::ForeignItem(item);
404426
visit::walk_item(self, item);
427+
self.node_id_to_def_id = old;
405428
}
406429
}
407430
}
@@ -438,7 +461,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
438461
tcx.ensure_done().get_lang_items(());
439462
let (mut resolver, krate) = tcx.resolver_for_lowering().steal();
440463

441-
let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
464+
let ast_index = index_crate(&resolver.owners, &krate);
442465
let mut owners = IndexVec::from_fn_n(
443466
|_| hir::MaybeOwner::Phantom,
444467
tcx.definitions_untracked().def_index_count(),
@@ -494,7 +517,6 @@ enum GenericArgsMode {
494517
impl<'a, 'hir> LoweringContext<'a, 'hir> {
495518
fn create_def(
496519
&mut self,
497-
parent: LocalDefId,
498520
node_id: ast::NodeId,
499521
name: Option<Symbol>,
500522
def_kind: DefKind,
@@ -509,10 +531,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
509531
self.tcx.hir_def_key(self.local_def_id(node_id)),
510532
);
511533

512-
let def_id = self.tcx.at(span).create_def(parent, name, def_kind).def_id();
534+
let def_id =
535+
self.tcx.at(span).create_def(self.current_hir_id_owner.def_id, name, def_kind).def_id();
513536

514537
debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
515-
self.resolver.node_id_to_def_id.insert(node_id, def_id);
538+
self.resolver
539+
.owners
540+
.get_mut(&self.current_ast_id_owner)
541+
.unwrap()
542+
.node_id_to_def_id
543+
.insert(node_id, def_id);
516544

517545
def_id
518546
}
@@ -527,16 +555,31 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
527555
/// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
528556
/// resolver (if any).
529557
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
530-
self.resolver.node_id_to_def_id.get(&node).copied()
558+
self.resolver.owners[&self.current_ast_id_owner].node_id_to_def_id.get(&node).copied()
531559
}
532560

533561
fn local_def_id(&self, node: NodeId) -> LocalDefId {
534-
self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
562+
self.opt_local_def_id(node).unwrap_or_else(|| {
563+
self.resolver.owners.items().any(|(id, items)| {
564+
items.node_id_to_def_id.items().any(|(node_id, def_id)| {
565+
if *node_id == node {
566+
panic!(
567+
"{def_id:?} ({node_id}) was found in {:?} ({id}) instead of in {:?} ({})",
568+
items.node_id_to_def_id.get(id),
569+
self.resolver.owners[&self.current_ast_id_owner].node_id_to_def_id[&self.current_ast_id_owner],
570+
self.current_ast_id_owner,
571+
)
572+
}
573+
false
574+
})
575+
});
576+
panic!("no entry for node id: `{node:?}`");
577+
})
535578
}
536579

537580
/// Given the id of an owner node in the AST, returns the corresponding `OwnerId`.
538581
fn owner_id(&self, node: NodeId) -> hir::OwnerId {
539-
hir::OwnerId { def_id: self.local_def_id(node) }
582+
hir::OwnerId { def_id: self.resolver.owners[&node].node_id_to_def_id[&node] }
540583
}
541584

542585
/// Freshen the `LoweringContext` and ready it to lower a nested item.
@@ -555,6 +598,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
555598
let current_attrs = std::mem::take(&mut self.attrs);
556599
let current_bodies = std::mem::take(&mut self.bodies);
557600
let current_define_opaque = std::mem::take(&mut self.define_opaque);
601+
let current_ast_owner = std::mem::replace(&mut self.current_ast_id_owner, owner);
558602
let current_ident_and_label_to_local_id =
559603
std::mem::take(&mut self.ident_and_label_to_local_id);
560604

@@ -599,6 +643,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
599643
self.item_local_id_counter = current_local_counter;
600644
self.impl_trait_defs = current_impl_trait_defs;
601645
self.impl_trait_bounds = current_impl_trait_bounds;
646+
self.current_ast_id_owner = current_ast_owner;
602647

603648
debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id));
604649
self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info)));
@@ -781,7 +826,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
781826
LifetimeRes::Fresh { param, kind, .. } => {
782827
// Late resolution delegates to us the creation of the `LocalDefId`.
783828
let _def_id = self.create_def(
784-
self.current_hir_id_owner.def_id,
785829
param,
786830
Some(kw::UnderscoreLifetime),
787831
DefKind::LifetimeParam,
@@ -2069,15 +2113,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20692113
} else {
20702114
// Construct an AnonConst where the expr is the "ty"'s path.
20712115

2072-
let parent_def_id = self.current_hir_id_owner.def_id;
20732116
let node_id = self.next_node_id();
20742117
let span = self.lower_span(span);
20752118

20762119
// Add a definition for the in-band const def.
20772120
// We're lowering a const argument that was originally thought to be a type argument,
20782121
// so the def collector didn't create the def ahead of time. That's why we have to do
20792122
// it here.
2080-
let def_id = self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, span);
2123+
let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
20812124
let hir_id = self.lower_node_id(node_id);
20822125

20832126
let path_expr = Expr {

compiler/rustc_ast_lowering/src/pat.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -516,14 +516,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
516516
span: Span,
517517
base_type: Span,
518518
) -> &'hir hir::ConstArg<'hir> {
519-
let parent_def_id = self.current_hir_id_owner.def_id;
520519
let node_id = self.next_node_id();
521520

522521
// Add a definition for the in-band const def.
523522
// We're generating a range end that didn't exist in the AST,
524523
// so the def collector didn't create the def ahead of time. That's why we have to do
525524
// it here.
526-
let def_id = self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, span);
525+
let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
527526
let hir_id = self.lower_node_id(node_id);
528527

529528
let unstable_span = self.mark_span_with_reason(

compiler/rustc_expand/src/base.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,9 @@ pub trait ResolverExpand {
11161116
trait_def_id: DefId,
11171117
impl_def_id: LocalDefId,
11181118
) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;
1119+
1120+
/// Set a new owner and return the old one
1121+
fn set_owner(&mut self, id: NodeId) -> NodeId;
11191122
}
11201123

11211124
pub trait LintStoreExpand {

compiler/rustc_expand/src/expand.rs

+20-12
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@ use std::rc::Rc;
44
use std::sync::Arc;
55
use std::{iter, mem};
66

7-
use rustc_ast as ast;
87
use rustc_ast::mut_visit::*;
98
use rustc_ast::ptr::P;
109
use rustc_ast::token::{self, Delimiter};
1110
use rustc_ast::tokenstream::TokenStream;
1211
use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult, try_visit, walk_list};
1312
use rustc_ast::{
14-
AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, ExprKind, ForeignItemKind,
15-
HasAttrs, HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind,
16-
NodeId, PatKind, StmtKind, TyKind,
13+
self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, CRATE_NODE_ID,
14+
DUMMY_NODE_ID, ExprKind, ForeignItemKind, HasAttrs, HasNodeId, Inline, ItemKind, MacStmtStyle,
15+
MetaItemInner, MetaItemKind, ModKind, NodeId, PatKind, StmtKind, TyKind,
1716
};
1817
use rustc_ast_pretty::pprust;
1918
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
@@ -2178,34 +2177,43 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
21782177
};
21792178
}
21802179
}
2180+
2181+
fn with_owner<T>(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
2182+
let old = if id != DUMMY_NODE_ID { self.cx.resolver.set_owner(id) } else { DUMMY_NODE_ID };
2183+
let val = f(self);
2184+
if id != DUMMY_NODE_ID {
2185+
assert_eq!(self.cx.resolver.set_owner(old), id);
2186+
}
2187+
val
2188+
}
21812189
}
21822190

21832191
impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
21842192
fn flat_map_item(&mut self, node: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
2185-
self.flat_map_node(node)
2193+
self.with_owner(node.id, |this| this.flat_map_node(node))
21862194
}
21872195

21882196
fn flat_map_assoc_item(
21892197
&mut self,
21902198
node: P<ast::AssocItem>,
21912199
ctxt: AssocCtxt,
21922200
) -> SmallVec<[P<ast::AssocItem>; 1]> {
2193-
match ctxt {
2194-
AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
2201+
self.with_owner(node.id, |this| match ctxt {
2202+
AssocCtxt::Trait => this.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
21952203
AssocCtxt::Impl { of_trait: false } => {
2196-
self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag))
2204+
this.flat_map_node(AstNodeWrapper::new(node, ImplItemTag))
21972205
}
21982206
AssocCtxt::Impl { of_trait: true } => {
2199-
self.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag))
2207+
this.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag))
22002208
}
2201-
}
2209+
})
22022210
}
22032211

22042212
fn flat_map_foreign_item(
22052213
&mut self,
22062214
node: P<ast::ForeignItem>,
22072215
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
2208-
self.flat_map_node(node)
2216+
self.with_owner(node.id, |this| this.flat_map_node(node))
22092217
}
22102218

22112219
fn flat_map_variant(&mut self, node: ast::Variant) -> SmallVec<[ast::Variant; 1]> {
@@ -2276,7 +2284,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
22762284
}
22772285

22782286
fn visit_crate(&mut self, node: &mut ast::Crate) {
2279-
self.visit_node(node)
2287+
self.with_owner(CRATE_NODE_ID, |this| this.visit_node(node))
22802288
}
22812289

22822290
fn visit_ty(&mut self, node: &mut P<ast::Ty>) {

compiler/rustc_middle/src/ty/mod.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ pub struct ResolverGlobalCtxt {
187187
pub stripped_cfg_items: Steal<Vec<StrippedCfgItem>>,
188188
}
189189

190+
#[derive(Debug, Default)]
191+
pub struct PerOwnerResolverData {
192+
pub node_id_to_def_id: NodeMap<LocalDefId>,
193+
}
194+
190195
/// Resolutions that should only be used for lowering.
191196
/// This struct is meant to be consumed by lowering.
192197
#[derive(Debug)]
@@ -204,9 +209,9 @@ pub struct ResolverAstLowering {
204209
/// Lifetime parameters that lowering will have to introduce.
205210
pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, LifetimeRes)>>,
206211

207-
pub next_node_id: ast::NodeId,
212+
pub owners: NodeMap<PerOwnerResolverData>,
208213

209-
pub node_id_to_def_id: NodeMap<LocalDefId>,
214+
pub next_node_id: ast::NodeId,
210215

211216
pub trait_map: NodeMap<Vec<hir::TraitCandidate>>,
212217
/// List functions and methods for which lifetime elision was successful.

0 commit comments

Comments
 (0)