Skip to content

Commit 66f172c

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 e77a8f4 + a16a6f1 commit 66f172c

File tree

12 files changed

+378
-172
lines changed

12 files changed

+378
-172
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

+57-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)]
@@ -61,7 +62,7 @@ use rustc_hir::{
6162
use rustc_index::{Idx, IndexSlice, IndexVec};
6263
use rustc_macros::extension;
6364
use rustc_middle::span_bug;
64-
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
65+
use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt};
6566
use rustc_session::parse::{add_feature_diagnostics, feature_err};
6667
use rustc_span::symbol::{Ident, Symbol, kw, sym};
6768
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
@@ -125,6 +126,7 @@ struct LoweringContext<'a, 'hir> {
125126
is_in_dyn_type: bool,
126127

127128
current_hir_id_owner: hir::OwnerId,
129+
current_ast_id_owner: PerOwnerResolverData,
128130
item_local_id_counter: hir::ItemLocalId,
129131
trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
130132

@@ -163,6 +165,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
163165
children: Vec::default(),
164166
contract_ensures: None,
165167
current_hir_id_owner: hir::CRATE_OWNER_ID,
168+
current_ast_id_owner: PerOwnerResolverData {
169+
node_id_to_def_id: Default::default(),
170+
id: DUMMY_NODE_ID,
171+
},
166172
item_local_id_counter: hir::ItemLocalId::ZERO,
167173
ident_and_label_to_local_id: Default::default(),
168174
#[cfg(debug_assertions)]
@@ -254,7 +260,7 @@ impl ResolverAstLowering {
254260
///
255261
/// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring
256262
/// should appear at the enclosing `PolyTraitRef`.
257-
fn extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
263+
fn extra_lifetime_params(&self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
258264
self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default()
259265
}
260266
}
@@ -365,17 +371,22 @@ enum AstOwner<'a> {
365371
}
366372

367373
fn index_crate<'a>(
368-
node_id_to_def_id: &NodeMap<LocalDefId>,
374+
owners: &NodeMap<PerOwnerResolverData>,
369375
krate: &'a Crate,
370376
) -> IndexVec<LocalDefId, AstOwner<'a>> {
371-
let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() };
377+
let mut indexer = Indexer {
378+
owners,
379+
node_id_to_def_id: &owners[&CRATE_NODE_ID].node_id_to_def_id,
380+
index: IndexVec::new(),
381+
};
372382
*indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) =
373383
AstOwner::Crate(krate);
374384
visit::walk_crate(&mut indexer, krate);
375385
return indexer.index;
376386

377387
struct Indexer<'s, 'a> {
378388
node_id_to_def_id: &'s NodeMap<LocalDefId>,
389+
owners: &'s NodeMap<PerOwnerResolverData>,
379390
index: IndexVec<LocalDefId, AstOwner<'a>>,
380391
}
381392

@@ -386,23 +397,38 @@ fn index_crate<'a>(
386397
}
387398

388399
fn visit_item(&mut self, item: &'a ast::Item) {
400+
let old = std::mem::replace(
401+
&mut self.node_id_to_def_id,
402+
&self.owners[&item.id].node_id_to_def_id,
403+
);
389404
let def_id = self.node_id_to_def_id[&item.id];
390405
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item);
391-
visit::walk_item(self, item)
406+
visit::walk_item(self, item);
407+
self.node_id_to_def_id = old;
392408
}
393409

394410
fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {
411+
let old = std::mem::replace(
412+
&mut self.node_id_to_def_id,
413+
&self.owners[&item.id].node_id_to_def_id,
414+
);
395415
let def_id = self.node_id_to_def_id[&item.id];
396416
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
397417
AstOwner::AssocItem(item, ctxt);
398418
visit::walk_assoc_item(self, item, ctxt);
419+
self.node_id_to_def_id = old;
399420
}
400421

401422
fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {
423+
let old = std::mem::replace(
424+
&mut self.node_id_to_def_id,
425+
&self.owners[&item.id].node_id_to_def_id,
426+
);
402427
let def_id = self.node_id_to_def_id[&item.id];
403428
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
404429
AstOwner::ForeignItem(item);
405430
visit::walk_item(self, item);
431+
self.node_id_to_def_id = old;
406432
}
407433
}
408434
}
@@ -439,7 +465,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
439465
tcx.ensure_done().get_lang_items(());
440466
let (mut resolver, krate) = tcx.resolver_for_lowering().steal();
441467

442-
let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
468+
let ast_index = index_crate(&resolver.owners, &krate);
443469
let mut owners = IndexVec::from_fn_n(
444470
|_| hir::MaybeOwner::Phantom,
445471
tcx.definitions_untracked().def_index_count(),
@@ -495,7 +521,6 @@ enum GenericArgsMode {
495521
impl<'a, 'hir> LoweringContext<'a, 'hir> {
496522
fn create_def(
497523
&mut self,
498-
parent: LocalDefId,
499524
node_id: ast::NodeId,
500525
name: Option<Symbol>,
501526
def_kind: DefKind,
@@ -510,10 +535,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
510535
self.tcx.hir_def_key(self.local_def_id(node_id)),
511536
);
512537

513-
let def_id = self.tcx.at(span).create_def(parent, name, def_kind).def_id();
538+
let def_id =
539+
self.tcx.at(span).create_def(self.current_hir_id_owner.def_id, name, def_kind).def_id();
514540

515541
debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
516-
self.resolver.node_id_to_def_id.insert(node_id, def_id);
542+
self.current_ast_id_owner.node_id_to_def_id.insert(node_id, def_id);
517543

518544
def_id
519545
}
@@ -528,16 +554,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
528554
/// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
529555
/// resolver (if any).
530556
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
531-
self.resolver.node_id_to_def_id.get(&node).copied()
557+
self.current_ast_id_owner.node_id_to_def_id.get(&node).copied()
532558
}
533559

534560
fn local_def_id(&self, node: NodeId) -> LocalDefId {
535-
self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
561+
self.opt_local_def_id(node).unwrap_or_else(|| {
562+
self.resolver.owners.items().any(|(id, items)| {
563+
items.node_id_to_def_id.items().any(|(node_id, def_id)| {
564+
if *node_id == node {
565+
panic!(
566+
"{def_id:?} ({node_id}) was found in {:?} ({id})",
567+
items.node_id_to_def_id.get(id),
568+
)
569+
}
570+
false
571+
})
572+
});
573+
panic!("no entry for node id: `{node:?}`");
574+
})
536575
}
537576

538577
/// Given the id of an owner node in the AST, returns the corresponding `OwnerId`.
539578
fn owner_id(&self, node: NodeId) -> hir::OwnerId {
540-
hir::OwnerId { def_id: self.local_def_id(node) }
579+
hir::OwnerId { def_id: self.resolver.owners[&node].node_id_to_def_id[&node] }
541580
}
542581

543582
/// Freshen the `LoweringContext` and ready it to lower a nested item.
@@ -556,6 +595,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
556595
let current_attrs = std::mem::take(&mut self.attrs);
557596
let current_bodies = std::mem::take(&mut self.bodies);
558597
let current_define_opaque = std::mem::take(&mut self.define_opaque);
598+
let current_ast_owner = std::mem::replace(
599+
&mut self.current_ast_id_owner,
600+
self.resolver.owners.remove(&owner).unwrap(),
601+
);
559602
let current_ident_and_label_to_local_id =
560603
std::mem::take(&mut self.ident_and_label_to_local_id);
561604

@@ -600,6 +643,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
600643
self.item_local_id_counter = current_local_counter;
601644
self.impl_trait_defs = current_impl_trait_defs;
602645
self.impl_trait_bounds = current_impl_trait_bounds;
646+
self.current_ast_id_owner = current_ast_owner;
603647

604648
debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id));
605649
self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info)));
@@ -782,7 +826,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
782826
LifetimeRes::Fresh { param, kind, .. } => {
783827
// Late resolution delegates to us the creation of the `LocalDefId`.
784828
let _def_id = self.create_def(
785-
self.current_hir_id_owner.def_id,
786829
param,
787830
Some(kw::UnderscoreLifetime),
788831
DefKind::LifetimeParam,
@@ -2089,15 +2132,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20892132
} else {
20902133
// Construct an AnonConst where the expr is the "ty"'s path.
20912134

2092-
let parent_def_id = self.current_hir_id_owner.def_id;
20932135
let node_id = self.next_node_id();
20942136
let span = self.lower_span(span);
20952137

20962138
// Add a definition for the in-band const def.
20972139
// We're lowering a const argument that was originally thought to be a type argument,
20982140
// so the def collector didn't create the def ahead of time. That's why we have to do
20992141
// it here.
2100-
let def_id = self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, span);
2142+
let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
21012143
let hir_id = self.lower_node_id(node_id);
21022144

21032145
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

+7
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,13 @@ 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. Use only in the implementation
1121+
/// of `with_owner` and always call [Self::reset_owner] afterwards
1122+
fn set_owner(&mut self, id: NodeId) -> NodeId;
1123+
1124+
/// Switch back to the original owner.
1125+
fn reset_owner(&mut self, id: NodeId);
11191126
}
11201127

11211128
pub trait LintStoreExpand {

compiler/rustc_expand/src/expand.rs

+22-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;
@@ -2177,34 +2176,45 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
21772176
};
21782177
}
21792178
}
2179+
2180+
fn with_owner<T>(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
2181+
if id == DUMMY_NODE_ID {
2182+
f(self)
2183+
} else {
2184+
let old = self.cx.resolver.set_owner(id);
2185+
let val = f(self);
2186+
self.cx.resolver.reset_owner(old);
2187+
val
2188+
}
2189+
}
21802190
}
21812191

21822192
impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
21832193
fn flat_map_item(&mut self, node: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
2184-
self.flat_map_node(node)
2194+
self.with_owner(node.id, |this| this.flat_map_node(node))
21852195
}
21862196

21872197
fn flat_map_assoc_item(
21882198
&mut self,
21892199
node: P<ast::AssocItem>,
21902200
ctxt: AssocCtxt,
21912201
) -> SmallVec<[P<ast::AssocItem>; 1]> {
2192-
match ctxt {
2193-
AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
2202+
self.with_owner(node.id, |this| match ctxt {
2203+
AssocCtxt::Trait => this.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
21942204
AssocCtxt::Impl { of_trait: false } => {
2195-
self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag))
2205+
this.flat_map_node(AstNodeWrapper::new(node, ImplItemTag))
21962206
}
21972207
AssocCtxt::Impl { of_trait: true } => {
2198-
self.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag))
2208+
this.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag))
21992209
}
2200-
}
2210+
})
22012211
}
22022212

22032213
fn flat_map_foreign_item(
22042214
&mut self,
22052215
node: P<ast::ForeignItem>,
22062216
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
2207-
self.flat_map_node(node)
2217+
self.with_owner(node.id, |this| this.flat_map_node(node))
22082218
}
22092219

22102220
fn flat_map_variant(&mut self, node: ast::Variant) -> SmallVec<[ast::Variant; 1]> {
@@ -2275,7 +2285,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
22752285
}
22762286

22772287
fn visit_crate(&mut self, node: &mut ast::Crate) {
2278-
self.visit_node(node)
2288+
self.with_owner(CRATE_NODE_ID, |this| this.visit_node(node))
22792289
}
22802290

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

compiler/rustc_middle/src/ty/mod.rs

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

190+
#[derive(Debug)]
191+
pub struct PerOwnerResolverData {
192+
pub node_id_to_def_id: NodeMap<LocalDefId>,
193+
/// The id of the owner
194+
pub id: ast::NodeId,
195+
}
196+
197+
impl PerOwnerResolverData {
198+
pub fn new(id: ast::NodeId) -> Self {
199+
Self { node_id_to_def_id: Default::default(), id }
200+
}
201+
}
202+
190203
/// Resolutions that should only be used for lowering.
191204
/// This struct is meant to be consumed by lowering.
192205
#[derive(Debug)]
@@ -204,9 +217,9 @@ pub struct ResolverAstLowering {
204217
/// Lifetime parameters that lowering will have to introduce.
205218
pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, LifetimeRes)>>,
206219

207-
pub next_node_id: ast::NodeId,
220+
pub owners: NodeMap<PerOwnerResolverData>,
208221

209-
pub node_id_to_def_id: NodeMap<LocalDefId>,
222+
pub next_node_id: ast::NodeId,
210223

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

0 commit comments

Comments
 (0)