Skip to content

Commit c4ff03f

Browse files
committed
Auto merge of #90145 - cjgillot:sorted-map, r=michaelwoerister
Use SortedMap in HIR. Closes #89788 r? `@ghost`
2 parents f2707fe + 6f6fa8b commit c4ff03f

File tree

8 files changed

+55
-57
lines changed

8 files changed

+55
-57
lines changed

compiler/rustc_ast_lowering/src/index.rs

+5-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use rustc_data_structures::fx::FxHashMap;
2+
use rustc_data_structures::sorted_map::SortedMap;
23
use rustc_hir as hir;
34
use rustc_hir::def_id::LocalDefId;
45
use rustc_hir::definitions;
@@ -9,14 +10,13 @@ use rustc_session::Session;
910
use rustc_span::source_map::SourceMap;
1011
use rustc_span::{Span, DUMMY_SP};
1112

12-
use std::iter::repeat;
1313
use tracing::debug;
1414

1515
/// A visitor that walks over the HIR and collects `Node`s into a HIR map.
1616
pub(super) struct NodeCollector<'a, 'hir> {
1717
/// Source map
1818
source_map: &'a SourceMap,
19-
bodies: &'a IndexVec<ItemLocalId, Option<&'hir Body<'hir>>>,
19+
bodies: &'a SortedMap<ItemLocalId, &'hir Body<'hir>>,
2020

2121
/// Outputs
2222
nodes: IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>,
@@ -30,21 +30,11 @@ pub(super) struct NodeCollector<'a, 'hir> {
3030
definitions: &'a definitions::Definitions,
3131
}
3232

33-
fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V) {
34-
let i = k.index();
35-
let len = map.len();
36-
if i >= len {
37-
map.extend(repeat(None).take(i - len + 1));
38-
}
39-
debug_assert!(map[k].is_none());
40-
map[k] = Some(v);
41-
}
42-
4333
pub(super) fn index_hir<'hir>(
4434
sess: &Session,
4535
definitions: &definitions::Definitions,
4636
item: hir::OwnerNode<'hir>,
47-
bodies: &IndexVec<ItemLocalId, Option<&'hir Body<'hir>>>,
37+
bodies: &SortedMap<ItemLocalId, &'hir Body<'hir>>,
4838
) -> (IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>, FxHashMap<LocalDefId, ItemLocalId>) {
4939
let mut nodes = IndexVec::new();
5040
// This node's parent should never be accessed: the owner's parent is computed by the
@@ -94,11 +84,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
9484
}
9585
}
9686

97-
insert_vec_map(
98-
&mut self.nodes,
99-
hir_id.local_id,
100-
ParentedNode { parent: self.parent_node, node: node },
101-
);
87+
self.nodes.insert(hir_id.local_id, ParentedNode { parent: self.parent_node, node: node });
10288
}
10389

10490
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
@@ -144,7 +130,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
144130

145131
fn visit_nested_body(&mut self, id: BodyId) {
146132
debug_assert_eq!(id.hir_id.owner, self.owner);
147-
let body = self.bodies[id.hir_id.local_id].unwrap();
133+
let body = self.bodies[&id.hir_id.local_id];
148134
self.visit_body(body);
149135
}
150136

compiler/rustc_ast_lowering/src/item.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -974,8 +974,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
974974
let body = hir::Body { generator_kind: self.generator_kind, params, value };
975975
let id = body.id();
976976
debug_assert_eq!(id.hir_id.owner, self.current_hir_id_owner);
977-
self.bodies.ensure_contains_elem(id.hir_id.local_id, || None);
978-
self.bodies[id.hir_id.local_id] = Some(self.arena.alloc(body));
977+
self.bodies.push((id.hir_id.local_id, self.arena.alloc(body)));
979978
id
980979
}
981980

compiler/rustc_ast_lowering/src/lib.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use rustc_ast_pretty::pprust;
4545
use rustc_data_structures::captures::Captures;
4646
use rustc_data_structures::fingerprint::Fingerprint;
4747
use rustc_data_structures::fx::FxHashSet;
48+
use rustc_data_structures::sorted_map::SortedMap;
4849
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
4950
use rustc_data_structures::sync::Lrc;
5051
use rustc_errors::{struct_span_err, Applicability};
@@ -67,7 +68,6 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
6768
use rustc_span::{Span, DUMMY_SP};
6869

6970
use smallvec::SmallVec;
70-
use std::collections::BTreeMap;
7171
use tracing::{debug, trace};
7272

7373
macro_rules! arena_vec {
@@ -104,9 +104,9 @@ struct LoweringContext<'a, 'hir: 'a> {
104104
/// The items being lowered are collected here.
105105
owners: IndexVec<LocalDefId, Option<hir::OwnerInfo<'hir>>>,
106106
/// Bodies inside the owner being lowered.
107-
bodies: IndexVec<hir::ItemLocalId, Option<&'hir hir::Body<'hir>>>,
107+
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
108108
/// Attributes inside the owner being lowered.
109-
attrs: BTreeMap<hir::ItemLocalId, &'hir [Attribute]>,
109+
attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>,
110110

111111
generator_kind: Option<hir::GeneratorKind>,
112112

@@ -301,8 +301,8 @@ pub fn lower_crate<'a, 'hir>(
301301
nt_to_tokenstream,
302302
arena,
303303
owners,
304-
bodies: IndexVec::new(),
305-
attrs: BTreeMap::default(),
304+
bodies: Vec::new(),
305+
attrs: SortedMap::new(),
306306
catch_scope: None,
307307
loop_scope: None,
308308
is_in_loop_condition: false,
@@ -479,7 +479,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
479479

480480
fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> hir::OwnerInfo<'hir> {
481481
let attrs = std::mem::take(&mut self.attrs);
482-
let bodies = std::mem::take(&mut self.bodies);
482+
let mut bodies = std::mem::take(&mut self.bodies);
483483
let local_node_ids = std::mem::take(&mut self.local_node_ids);
484484
let trait_map = local_node_ids
485485
.into_iter()
@@ -491,13 +491,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
491491
.collect();
492492

493493
#[cfg(debug_assertions)]
494-
for (&id, attrs) in attrs.iter() {
494+
for (id, attrs) in attrs.iter() {
495495
// Verify that we do not store empty slices in the map.
496496
if attrs.is_empty() {
497497
panic!("Stored empty attributes for {:?}", id);
498498
}
499499
}
500500

501+
bodies.sort_by_key(|(k, _)| *k);
502+
let bodies = SortedMap::from_presorted_elements(bodies);
501503
let (hash_including_bodies, hash_without_bodies) = self.hash_owner(node, &bodies);
502504
let (nodes, parenting) =
503505
index::index_hir(self.sess, self.resolver.definitions(), node, &bodies);
@@ -518,7 +520,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
518520
fn hash_owner(
519521
&mut self,
520522
node: hir::OwnerNode<'hir>,
521-
bodies: &IndexVec<hir::ItemLocalId, Option<&'hir hir::Body<'hir>>>,
523+
bodies: &SortedMap<hir::ItemLocalId, &'hir hir::Body<'hir>>,
522524
) -> (Fingerprint, Fingerprint) {
523525
let mut hcx = self.resolver.create_stable_hashing_context();
524526
let mut stable_hasher = StableHasher::new();

compiler/rustc_data_structures/src/sorted_map.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::stable_hasher::{HashStable, StableHasher};
12
use std::borrow::Borrow;
23
use std::cmp::Ordering;
34
use std::iter::FromIterator;
@@ -16,17 +17,26 @@ pub use index_map::SortedIndexMultiMap;
1617
/// stores data in a more compact way. It also supports accessing contiguous
1718
/// ranges of elements as a slice, and slices of already sorted elements can be
1819
/// inserted efficiently.
19-
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug, Encodable, Decodable)]
20-
pub struct SortedMap<K: Ord, V> {
20+
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
21+
pub struct SortedMap<K, V> {
2122
data: Vec<(K, V)>,
2223
}
2324

24-
impl<K: Ord, V> SortedMap<K, V> {
25+
impl<K, V> Default for SortedMap<K, V> {
26+
#[inline]
27+
fn default() -> SortedMap<K, V> {
28+
SortedMap { data: Vec::new() }
29+
}
30+
}
31+
32+
impl<K, V> SortedMap<K, V> {
2533
#[inline]
26-
pub fn new() -> SortedMap<K, V> {
27-
SortedMap { data: vec![] }
34+
pub const fn new() -> SortedMap<K, V> {
35+
SortedMap { data: Vec::new() }
2836
}
37+
}
2938

39+
impl<K: Ord, V> SortedMap<K, V> {
3040
/// Construct a `SortedMap` from a presorted set of elements. This is faster
3141
/// than creating an empty map and then inserting the elements individually.
3242
///
@@ -281,5 +291,12 @@ impl<K: Ord, V> FromIterator<(K, V)> for SortedMap<K, V> {
281291
}
282292
}
283293

294+
impl<K: HashStable<CTX>, V: HashStable<CTX>, CTX> HashStable<CTX> for SortedMap<K, V> {
295+
#[inline]
296+
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
297+
self.data.hash_stable(ctx, hasher);
298+
}
299+
}
300+
284301
#[cfg(test)]
285302
mod tests;

compiler/rustc_hir/src/hir.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub use rustc_ast::{CaptureBy, Movability, Mutability};
1212
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
1313
use rustc_data_structures::fingerprint::Fingerprint;
1414
use rustc_data_structures::fx::FxHashMap;
15+
use rustc_data_structures::sorted_map::SortedMap;
1516
use rustc_index::vec::IndexVec;
1617
use rustc_macros::HashStable_Generic;
1718
use rustc_span::source_map::Spanned;
@@ -22,7 +23,6 @@ use rustc_target::asm::InlineAsmRegOrRegClass;
2223
use rustc_target::spec::abi::Abi;
2324

2425
use smallvec::SmallVec;
25-
use std::collections::BTreeMap;
2626
use std::fmt;
2727

2828
#[derive(Copy, Clone, Encodable, HashStable_Generic)]
@@ -676,13 +676,13 @@ pub struct ParentedNode<'tcx> {
676676
/// Attributes owned by a HIR owner.
677677
#[derive(Debug)]
678678
pub struct AttributeMap<'tcx> {
679-
pub map: BTreeMap<ItemLocalId, &'tcx [Attribute]>,
679+
pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
680680
pub hash: Fingerprint,
681681
}
682682

683683
impl<'tcx> AttributeMap<'tcx> {
684684
pub const EMPTY: &'static AttributeMap<'static> =
685-
&AttributeMap { map: BTreeMap::new(), hash: Fingerprint::ZERO };
685+
&AttributeMap { map: SortedMap::new(), hash: Fingerprint::ZERO };
686686

687687
#[inline]
688688
pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
@@ -705,7 +705,7 @@ pub struct OwnerNodes<'tcx> {
705705
// used.
706706
pub nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
707707
/// Content of local bodies.
708-
pub bodies: IndexVec<ItemLocalId, Option<&'tcx Body<'tcx>>>,
708+
pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
709709
}
710710

711711
/// Full information resulting from lowering an AST node.

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

+9-15
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ impl<'hir> Map<'hir> {
376376
}
377377

378378
pub fn body(&self, id: BodyId) -> &'hir Body<'hir> {
379-
self.tcx.hir_owner_nodes(id.hir_id.owner).unwrap().bodies[id.hir_id.local_id].unwrap()
379+
self.tcx.hir_owner_nodes(id.hir_id.owner).unwrap().bodies[&id.hir_id.local_id]
380380
}
381381

382382
pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
@@ -495,13 +495,10 @@ impl<'hir> Map<'hir> {
495495
.iter_enumerated()
496496
.flat_map(move |(owner, owner_info)| {
497497
let bodies = &owner_info.as_ref()?.nodes.bodies;
498-
Some(bodies.iter_enumerated().filter_map(move |(local_id, body)| {
499-
if body.is_none() {
500-
return None;
501-
}
498+
Some(bodies.iter().map(move |&(local_id, _)| {
502499
let hir_id = HirId { owner, local_id };
503500
let body_id = BodyId { hir_id };
504-
Some(self.body_owner_def_id(body_id))
501+
self.body_owner_def_id(body_id)
505502
}))
506503
})
507504
.flatten()
@@ -515,13 +512,10 @@ impl<'hir> Map<'hir> {
515512
par_iter(&self.krate().owners.raw).enumerate().for_each(|(owner, owner_info)| {
516513
let owner = LocalDefId::new(owner);
517514
if let Some(owner_info) = owner_info {
518-
par_iter(&owner_info.nodes.bodies.raw).enumerate().for_each(|(local_id, body)| {
519-
if body.is_some() {
520-
let local_id = ItemLocalId::new(local_id);
521-
let hir_id = HirId { owner, local_id };
522-
let body_id = BodyId { hir_id };
523-
f(self.body_owner_def_id(body_id))
524-
}
515+
par_iter(owner_info.nodes.bodies.range(..)).for_each(|(local_id, _)| {
516+
let hir_id = HirId { owner, local_id: *local_id };
517+
let body_id = BodyId { hir_id };
518+
f(self.body_owner_def_id(body_id))
525519
})
526520
}
527521
});
@@ -578,8 +572,8 @@ impl<'hir> Map<'hir> {
578572
let krate = self.krate();
579573
for (owner, info) in krate.owners.iter_enumerated() {
580574
if let Some(info) = info {
581-
for (&local_id, attrs) in info.attrs.map.iter() {
582-
let id = HirId { owner, local_id };
575+
for (local_id, attrs) in info.attrs.map.iter() {
576+
let id = HirId { owner, local_id: *local_id };
583577
for a in *attrs {
584578
visitor.visit_attribute(id, a)
585579
}

compiler/rustc_query_system/src/ich/hcx.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use crate::ich;
22
use rustc_ast as ast;
33
use rustc_data_structures::fx::FxHashSet;
4+
use rustc_data_structures::sorted_map::SortedMap;
45
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
56
use rustc_data_structures::sync::Lrc;
67
use rustc_hir as hir;
78
use rustc_hir::def_id::{DefId, LocalDefId};
89
use rustc_hir::definitions::{DefPathHash, Definitions};
9-
use rustc_index::vec::IndexVec;
1010
use rustc_session::cstore::CrateStore;
1111
use rustc_session::Session;
1212
use rustc_span::source_map::SourceMap;
@@ -51,7 +51,7 @@ pub(super) enum BodyResolver<'tcx> {
5151
Traverse {
5252
hash_bodies: bool,
5353
owner: LocalDefId,
54-
bodies: &'tcx IndexVec<hir::ItemLocalId, Option<&'tcx hir::Body<'tcx>>>,
54+
bodies: &'tcx SortedMap<hir::ItemLocalId, &'tcx hir::Body<'tcx>>,
5555
},
5656
}
5757

@@ -122,7 +122,7 @@ impl<'a> StableHashingContext<'a> {
122122
&mut self,
123123
hash_bodies: bool,
124124
owner: LocalDefId,
125-
bodies: &'a IndexVec<hir::ItemLocalId, Option<&'a hir::Body<'a>>>,
125+
bodies: &'a SortedMap<hir::ItemLocalId, &'a hir::Body<'a>>,
126126
f: impl FnOnce(&mut Self),
127127
) {
128128
let prev = self.body_resolver;

compiler/rustc_query_system/src/ich/impls_hir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
3333
BodyResolver::Traverse { hash_bodies: false, .. } => {}
3434
BodyResolver::Traverse { hash_bodies: true, owner, bodies } => {
3535
assert_eq!(id.hir_id.owner, owner);
36-
bodies[id.hir_id.local_id].unwrap().hash_stable(hcx, hasher);
36+
bodies[&id.hir_id.local_id].hash_stable(hcx, hasher);
3737
}
3838
}
3939
}

0 commit comments

Comments
 (0)