Skip to content

Commit 77a4fb6

Browse files
committed
Auto merge of rust-lang#155678 - aerooneqq:single-owners-query-exp, r=oli-obk
Merge several HIR-level queries into one Now four queries (`local_def_id_to_hir_id`, `opt_hir_owner_nodes`, `opt_ast_lowering_delayed_lints`, `in_scope_traits_map`) were replaced with regular methods which acts like getters. An `hir_owner` query was added that returns a `ProjectedMaybeOwner` that contains all those fields. `hir_attr_map` remains a separate query as adding attributes to `ProjectedMaybeOwner` led to [perf regressions](rust-lang#155678 (comment)). There is a similar issue with `in_scopes_trait_map`, but according to the comments from rust-lang/rustc-perf#2436 it is a rare case. Most of the changes in incremental tests are renames from `opt_hir_owner_nodes` -> `hir_owner`, but there are few cases when new dirty queries were added. r? @petrochenkov r? @oli-obk
2 parents ddc1a64 + fc6b395 commit 77a4fb6

47 files changed

Lines changed: 943 additions & 869 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_incremental/src/assert_dep_graph.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,9 @@ impl<'tcx> IfThisChanged<'tcx> {
113113
for attr in attrs {
114114
if let Attribute::Parsed(AttributeKind::RustcIfThisChanged(span, dep_node)) = *attr {
115115
let dep_node = match dep_node {
116-
None => DepNode::from_def_path_hash(
117-
self.tcx,
118-
def_path_hash,
119-
DepKind::opt_hir_owner_nodes,
120-
),
116+
None => {
117+
DepNode::from_def_path_hash(self.tcx, def_path_hash, DepKind::hir_owner)
118+
}
121119
Some(n) => {
122120
match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) {
123121
Ok(n) => n,

compiler/rustc_incremental/src/persist/clean.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ const BASE_FN: &[&str] = &[
5454

5555
/// DepNodes for Hir, which is pretty much everything
5656
const BASE_HIR: &[&str] = &[
57-
// opt_hir_owner_nodes should be computed for all nodes
58-
label_strs::opt_hir_owner_nodes,
57+
// hir_owner should be computed for all nodes
58+
label_strs::hir_owner,
5959
];
6060

6161
/// `impl` implementation of struct/trait

compiler/rustc_interface/src/passes.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -879,9 +879,9 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
879879
providers.queries.analysis = analysis;
880880
providers.queries.hir_crate = rustc_ast_lowering::lower_to_hir;
881881
providers.queries.lower_delayed_owner = rustc_ast_lowering::lower_delayed_owner;
882-
// `delayed_owner` is fed during `lower_delayed_owner`, by default it returns phantom,
882+
// `hir_delayed_owner` is fed during `lower_delayed_owner`, by default it returns phantom,
883883
// as if this query was not fed it means that `MaybeOwner` does not exist for provided LocalDefId.
884-
providers.queries.delayed_owner = |_, _| MaybeOwner::Phantom;
884+
providers.queries.hir_delayed_owner = |_, _| MaybeOwner::Phantom;
885885
providers.queries.resolver_for_lowering_raw = resolver_for_lowering_raw;
886886
providers.queries.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..];
887887
providers.queries.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1;

compiler/rustc_middle/src/arena.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ macro_rules! arena_types {
118118
[] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls,
119119
[] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>,
120120
[decode] token_stream: rustc_ast::tokenstream::TokenStream,
121+
[] maybe_owner: rustc_middle::hir::ProjectedMaybeOwner<'tcx>,
122+
[] owner_info: rustc_middle::hir::ProjectedOwnerInfo<'tcx>,
123+
[] parenting: rustc_hir::def_id::LocalDefIdMap<rustc_hir::ItemLocalId>,
124+
[] trait_candidates: rustc_hir::ItemLocalMap<&'tcx [rustc_hir::TraitCandidate<'tcx>]>,
125+
[] delayed_lints: rustc_data_structures::steal::Steal<rustc_hir::lints::DelayedLints>,
121126
]);
122127
)
123128
}

compiler/rustc_middle/src/dep_graph/graph.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,14 @@ impl DepGraph {
213213
}
214214
}
215215

216+
pub fn assert_eval_always(&self) {
217+
if self.data.is_some() {
218+
read_deps(|deps| {
219+
assert_matches!(deps, TaskDepsRef::EvalAlways, "expected eval always context")
220+
});
221+
}
222+
}
223+
216224
pub fn with_ignore<OP, R>(&self, op: OP) -> R
217225
where
218226
OP: FnOnce() -> R,

compiler/rustc_middle/src/hir/map.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,22 @@ use rustc_abi::ExternAbi;
66
use rustc_ast::visit::{VisitorResult, walk_list};
77
use rustc_data_structures::fingerprint::Fingerprint;
88
use rustc_data_structures::stable_hash::{StableHash, StableHasher};
9+
use rustc_data_structures::steal::Steal;
910
use rustc_data_structures::svh::Svh;
1011
use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, spawn, try_par_for_each_in};
1112
use rustc_hir::def::{DefKind, Res};
1213
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
1314
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
1415
use rustc_hir::intravisit::Visitor;
16+
use rustc_hir::lints::DelayedLints;
1517
use rustc_hir::*;
1618
use rustc_hir_pretty as pprust_hir;
1719
use rustc_span::def_id::StableCrateId;
1820
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, with_metavar_spans};
1921

20-
use crate::hir::{ModuleItems, nested_filter};
22+
use crate::hir::{ModuleItems, ProjectedMaybeOwner, nested_filter};
2123
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
22-
use crate::query::LocalCrate;
24+
use crate::query::{IntoQueryKey, LocalCrate};
2325
use crate::ty::TyCtxt;
2426

2527
/// An iterator that walks up the ancestor tree of a given `HirId`.
@@ -101,6 +103,37 @@ impl<'tcx> Iterator for ParentOwnerIterator<'tcx> {
101103
}
102104

103105
impl<'tcx> TyCtxt<'tcx> {
106+
#[inline]
107+
pub fn local_def_id_to_hir_id(self, def_id: impl IntoQueryKey<LocalDefId>) -> HirId {
108+
let def_id = def_id.into_query_key();
109+
match self.hir_owner(def_id) {
110+
ProjectedMaybeOwner::Owner(_) => HirId::make_owner(def_id),
111+
ProjectedMaybeOwner::NonOwner(hir_id) => hir_id,
112+
}
113+
}
114+
115+
/// This function is used only inside eval-always query `analysis`
116+
/// (`analysis -> run_required_analysis` -> `emit_delayed_lints`), so it is safe
117+
/// to obtain delayed lints from non-eval-always `owner` query.
118+
#[inline]
119+
pub fn opt_ast_lowering_delayed_lints(self, id: OwnerId) -> Option<&'tcx Steal<DelayedLints>> {
120+
self.dep_graph.assert_eval_always();
121+
self.hir_owner(id.def_id).as_owner().map(|o| o.delayed_lints)
122+
}
123+
124+
#[inline]
125+
pub fn in_scope_traits_map(
126+
self,
127+
id: OwnerId,
128+
) -> Option<&'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>> {
129+
self.hir_owner(id.def_id).as_owner().map(|o| o.trait_map)
130+
}
131+
132+
#[inline]
133+
pub fn opt_hir_owner_nodes(self, def_id: LocalDefId) -> Option<&'tcx OwnerNodes<'tcx>> {
134+
self.hir_owner(def_id).as_owner().map(|o| o.nodes)
135+
}
136+
104137
#[inline]
105138
fn expect_hir_owner_nodes(self, def_id: LocalDefId) -> &'tcx OwnerNodes<'tcx> {
106139
self.opt_hir_owner_nodes(def_id)

compiler/rustc_middle/src/hir/mod.rs

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHashe
1616
use rustc_data_structures::steal::Steal;
1717
use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in};
1818
use rustc_hir::def::{DefKind, Res};
19-
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
19+
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap, LocalModDefId};
20+
use rustc_hir::lints::DelayedLints;
2021
use rustc_hir::*;
2122
use rustc_index::IndexVec;
2223
use rustc_macros::{Decodable, Encodable, StableHash};
@@ -72,7 +73,7 @@ impl<'hir> Crate<'hir> {
7273
tcx.ensure_done().lower_delayed_owner(def_id);
7374
}
7475

75-
tcx.delayed_owner(def_id)
76+
tcx.hir_delayed_owner(def_id)
7677
}
7778
}
7879

@@ -422,8 +423,7 @@ impl<'tcx> TyCtxt<'tcx> {
422423
HirId {
423424
owner: parent_owner_id,
424425
local_id: self
425-
.hir_crate(())
426-
.owner(self, parent_owner_id.def_id)
426+
.hir_owner(parent_owner_id.def_id)
427427
.unwrap()
428428
.parenting
429429
.get(&owner_id.def_id)
@@ -452,23 +452,75 @@ pub struct Hashes {
452452
pub attrs_hash: Option<Fingerprint>,
453453
}
454454

455+
/// Unites some of `OwnerInfo`'s fields into same struct that is used by `hir_owner` query.
456+
/// `AttributeMap` is handled separately as placing it in this struct led to perf regressions:
457+
/// <https://github.com/rust-lang/rust/pull/155678#issuecomment-4304597871>.
458+
/// This struct is created mainly for uniting/splitting fields of `OwnerInfo` so they are
459+
/// stored/invalidated together in incremental compilation.
460+
/// For comments about each field see `OwnerInfo` struct.
461+
#[derive(Clone, Copy, Debug, StableHash)]
462+
pub struct ProjectedOwnerInfo<'tcx> {
463+
nodes: &'tcx OwnerNodes<'tcx>,
464+
parenting: &'tcx LocalDefIdMap<ItemLocalId>,
465+
trait_map: &'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>,
466+
467+
#[stable_hash(ignore)]
468+
delayed_lints: &'tcx Steal<DelayedLints>,
469+
}
470+
471+
impl<'tcx> ProjectedOwnerInfo<'tcx> {
472+
pub fn new(
473+
nodes: &'tcx OwnerNodes<'tcx>,
474+
parenting: &'tcx LocalDefIdMap<ItemLocalId>,
475+
trait_map: &'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>,
476+
delayed_lints: &'tcx Steal<DelayedLints>,
477+
) -> ProjectedOwnerInfo<'tcx> {
478+
ProjectedOwnerInfo { nodes, parenting, trait_map, delayed_lints }
479+
}
480+
}
481+
482+
#[derive(Clone, Copy, Debug, StableHash)]
483+
pub enum ProjectedMaybeOwner<'tcx> {
484+
Owner(ProjectedOwnerInfo<'tcx>),
485+
NonOwner(HirId),
486+
}
487+
488+
impl<'tcx> ProjectedMaybeOwner<'tcx> {
489+
pub fn new(value: MaybeOwner<'tcx>, def_id: LocalDefId) -> Self {
490+
match value {
491+
MaybeOwner::Owner(o) => ProjectedMaybeOwner::Owner(ProjectedOwnerInfo {
492+
nodes: &o.nodes,
493+
parenting: &o.parenting,
494+
trait_map: &o.trait_map,
495+
delayed_lints: &o.delayed_lints,
496+
}),
497+
MaybeOwner::NonOwner(hir_id) => ProjectedMaybeOwner::NonOwner(hir_id),
498+
MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id),
499+
}
500+
}
501+
502+
pub fn as_owner(&self) -> Option<&ProjectedOwnerInfo<'tcx>> {
503+
match self {
504+
ProjectedMaybeOwner::Owner(i) => Some(i),
505+
ProjectedMaybeOwner::NonOwner(_) => None,
506+
}
507+
}
508+
509+
pub fn unwrap(&'tcx self) -> &'tcx ProjectedOwnerInfo<'tcx> {
510+
self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner"))
511+
}
512+
}
513+
455514
pub fn provide(providers: &mut Providers) {
456515
providers.hir_crate_items = map::hir_crate_items;
457516
providers.crate_hash = map::crate_hash;
458517
providers.hir_module_items = map::hir_module_items;
459-
providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owner(tcx, def_id) {
460-
MaybeOwner::Owner(_) => HirId::make_owner(def_id),
461-
MaybeOwner::NonOwner(hir_id) => hir_id,
462-
MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id),
463-
};
464-
providers.opt_hir_owner_nodes =
465-
|tcx, id| tcx.hir_crate(()).owner(tcx, id).as_owner().map(|i| &i.nodes);
466-
providers.hir_owner_parent_q = |tcx, owner_id| tcx.hir_owner_parent_impl(owner_id);
467518
providers.hir_attr_map = |tcx, id| {
468519
tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
469520
};
470-
providers.opt_ast_lowering_delayed_lints =
471-
|tcx, id| tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map(|o| &o.delayed_lints);
521+
providers.hir_owner =
522+
|tcx, def_id| ProjectedMaybeOwner::new(tcx.hir_crate(()).owner(tcx, def_id), def_id);
523+
providers.hir_owner_parent_q = |tcx, owner_id| tcx.hir_owner_parent_impl(owner_id);
472524
providers.def_span = |tcx, def_id| tcx.hir_span(tcx.local_def_id_to_hir_id(def_id));
473525
providers.def_ident_span = |tcx, def_id| {
474526
let hir_id = tcx.local_def_id_to_hir_id(def_id);
@@ -508,7 +560,4 @@ pub fn provide(providers: &mut Providers) {
508560
|tcx, trait_id| tcx.resolutions(()).trait_impls.get(&trait_id).map_or(&[], |xs| &xs[..]);
509561
providers.expn_that_defined =
510562
|tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
511-
providers.in_scope_traits_map = |tcx, id| {
512-
tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map(|owner_info| &owner_info.trait_map)
513-
};
514563
}

compiler/rustc_middle/src/queries.rs

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use rustc_hir::attrs::{EiiDecl, EiiImpl, StrippedCfgItem};
6666
use rustc_hir::def::{DefKind, DocLinkResMap};
6767
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdSet, LocalModDefId};
6868
use rustc_hir::lang_items::{LangItem, LanguageItems};
69-
use rustc_hir::{ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, TraitCandidate};
69+
use rustc_hir::{ItemLocalId, PreciseCapturingArgKind};
7070
use rustc_index::IndexVec;
7171
use rustc_lint_defs::LintId;
7272
use rustc_macros::rustc_queries;
@@ -215,7 +215,12 @@ rustc_queries! {
215215
desc { "lowering the delayed AST owner `{}`", tcx.def_path_str(def_id) }
216216
}
217217

218-
query delayed_owner(def_id: LocalDefId) -> hir::MaybeOwner<'tcx> {
218+
query hir_owner(def_id: LocalDefId) -> rustc_middle::hir::ProjectedMaybeOwner<'tcx> {
219+
desc { "getting owner for `{}`", tcx.def_path_str(def_id) }
220+
feedable
221+
}
222+
223+
query hir_delayed_owner(def_id: LocalDefId) -> hir::MaybeOwner<'tcx> {
219224
feedable
220225
desc { "getting child of lowered delayed AST owner `{}`", tcx.def_path_str(def_id) }
221226
}
@@ -237,12 +242,6 @@ rustc_queries! {
237242
cache_on_disk
238243
}
239244

240-
/// Returns HIR ID for the given `LocalDefId`.
241-
query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId {
242-
desc { "getting HIR ID of `{}`", tcx.def_path_str(key) }
243-
feedable
244-
}
245-
246245
/// Gives access to the HIR node's parent for the HIR owner `key`.
247246
///
248247
/// This can be conveniently accessed by `tcx.hir_*` methods.
@@ -251,15 +250,6 @@ rustc_queries! {
251250
desc { "getting HIR parent of `{}`", tcx.def_path_str(key) }
252251
}
253252

254-
/// Gives access to the HIR nodes and bodies inside `key` if it's a HIR owner.
255-
///
256-
/// This can be conveniently accessed by `tcx.hir_*` methods.
257-
/// Avoid calling this query directly.
258-
query opt_hir_owner_nodes(key: LocalDefId) -> Option<&'tcx hir::OwnerNodes<'tcx>> {
259-
desc { "getting HIR owner items in `{}`", tcx.def_path_str(key) }
260-
feedable
261-
}
262-
263253
/// Gives access to the HIR attributes inside the HIR owner `key`.
264254
///
265255
/// This can be conveniently accessed by `tcx.hir_*` methods.
@@ -269,18 +259,6 @@ rustc_queries! {
269259
feedable
270260
}
271261

272-
/// Gives access to lints emitted during ast lowering.
273-
///
274-
/// This can be conveniently accessed by `tcx.hir_*` methods.
275-
/// Avoid calling this query directly.
276-
query opt_ast_lowering_delayed_lints(key: hir::OwnerId) -> Option<&'tcx Steal<hir::lints::DelayedLints>> {
277-
desc { "getting AST lowering delayed lints in `{}`", tcx.def_path_str(key) }
278-
// This query has to be `no_hash` and `eval_always`,
279-
// because it accesses `delayed_lints` which is not hashed as part of the HIR
280-
no_hash
281-
eval_always
282-
}
283-
284262
/// Returns the *default* of the const pararameter given by `DefId`.
285263
///
286264
/// E.g., given `struct Ty<const N: usize = 3>;` this returns `3` for `N`.
@@ -1881,10 +1859,6 @@ rustc_queries! {
18811859
query specializes(_: (DefId, DefId)) -> bool {
18821860
desc { "computing whether impls specialize one another" }
18831861
}
1884-
query in_scope_traits_map(_: hir::OwnerId)
1885-
-> Option<&'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>> {
1886-
desc { "getting traits in scope at a block" }
1887-
}
18881862

18891863
/// Returns whether the impl or associated function has the `default` keyword.
18901864
/// Note: This will ICE on inherent impl items. Consider using `AssocItem::defaultness`.

compiler/rustc_middle/src/query/erase.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ impl_erasable_for_types_with_no_type_params! {
214214
rustc_hir::OpaqueTyOrigin<rustc_hir::def_id::DefId>,
215215
rustc_hir::def::DefKind,
216216
rustc_hir::def_id::DefId,
217+
rustc_middle::hir::ProjectedMaybeOwner<'_>,
217218
rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs,
218219
rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault,
219220
rustc_middle::mir::ConstQualifs,

compiler/rustc_middle/src/ty/context.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ use tracing::{debug, instrument};
5252
use crate::arena::Arena;
5353
use crate::dep_graph::dep_node::make_metadata;
5454
use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex};
55+
use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo};
5556
use crate::ich::StableHashState;
5657
use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
5758
use crate::lint::emit_lint_base;
@@ -585,7 +586,7 @@ impl<'tcx> TyCtxt<'tcx> {
585586
/// Feeds the HIR delayed owner during AST -> HIR delayed lowering.
586587
pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) {
587588
self.dep_graph.assert_ignored();
588-
TyCtxtFeed { tcx: self, key }.delayed_owner(owner);
589+
TyCtxtFeed { tcx: self, key }.hir_delayed_owner(owner);
589590
}
590591

591592
// Trait impl item visibility is inherited from its trait when not specified
@@ -626,8 +627,13 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
626627

627628
// Fills in all the important parts needed by HIR queries
628629
pub fn feed_hir(&self) {
629-
self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
630-
self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes::synthetic())));
630+
self.hir_owner(ProjectedMaybeOwner::Owner(ProjectedOwnerInfo::new(
631+
self.tcx.arena.alloc(hir::OwnerNodes::synthetic()),
632+
self.tcx.arena.alloc(Default::default()),
633+
self.tcx.arena.alloc(Default::default()),
634+
self.tcx.arena.alloc(Steal::new(Default::default())),
635+
)));
636+
631637
self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY);
632638
}
633639
}

0 commit comments

Comments
 (0)