Skip to content

Commit 18f3be7

Browse files
committed
Auto merge of #75278 - cuviper:indexmap, r=Mark-Simulacrum
Upgrade indexmap and use it more First this upgrades `indexmap` to 1.5.1, which is now based on `hashbrown::raw::RawTable`. This means it shares a lot of the same performance characteristics for insert, lookup, etc., while keeping items in insertion order. Then across various rustc crates, this replaces a lot of `Vec`+`HashMap` pairs with a single `IndexMap` or `IndexSet`. Closes #60608. r? @eddyb
2 parents 39e593a + ca0b89a commit 18f3be7

File tree

21 files changed

+144
-193
lines changed

21 files changed

+144
-193
lines changed

Cargo.lock

+6-2
Original file line numberDiff line numberDiff line change
@@ -1382,9 +1382,13 @@ dependencies = [
13821382

13831383
[[package]]
13841384
name = "indexmap"
1385-
version = "1.0.2"
1385+
version = "1.5.1"
13861386
source = "registry+https://github.com/rust-lang/crates.io-index"
1387-
checksum = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
1387+
checksum = "86b45e59b16c76b11bf9738fd5d38879d3bd28ad292d7b313608becb17ae2df9"
1388+
dependencies = [
1389+
"autocfg",
1390+
"hashbrown",
1391+
]
13881392

13891393
[[package]]
13901394
name = "installer"

src/librustc_codegen_llvm/coverageinfo/mapgen.rs

+5-14
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use llvm::coverageinfo::CounterMappingRegion;
66
use log::debug;
77
use rustc_codegen_ssa::coverageinfo::map::{Counter, CounterExpression, Region};
88
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods};
9-
use rustc_data_structures::fx::FxHashMap;
9+
use rustc_data_structures::fx::FxIndexSet;
1010
use rustc_llvm::RustString;
1111

1212
use std::ffi::CString;
@@ -76,13 +76,12 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
7676
}
7777

7878
struct CoverageMapGenerator {
79-
filenames: Vec<CString>,
80-
filename_to_index: FxHashMap<CString, u32>,
79+
filenames: FxIndexSet<CString>,
8180
}
8281

8382
impl CoverageMapGenerator {
8483
fn new() -> Self {
85-
Self { filenames: Vec::new(), filename_to_index: FxHashMap::default() }
84+
Self { filenames: FxIndexSet::default() }
8685
}
8786

8887
/// Using the `expressions` and `counter_regions` collected for the current function, generate
@@ -122,16 +121,8 @@ impl CoverageMapGenerator {
122121
let c_filename =
123122
CString::new(file_name).expect("null error converting filename to C string");
124123
debug!(" file_id: {} = '{:?}'", current_file_id, c_filename);
125-
let filenames_index = match self.filename_to_index.get(&c_filename) {
126-
Some(index) => *index,
127-
None => {
128-
let index = self.filenames.len() as u32;
129-
self.filenames.push(c_filename.clone());
130-
self.filename_to_index.insert(c_filename.clone(), index);
131-
index
132-
}
133-
};
134-
virtual_file_mapping.push(filenames_index);
124+
let (filenames_index, _) = self.filenames.insert_full(c_filename);
125+
virtual_file_mapping.push(filenames_index as u32);
135126
}
136127
mapping_regions.push(CounterMappingRegion::code_region(
137128
counter,

src/librustc_codegen_llvm/coverageinfo/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,11 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
9797
}
9898
}
9999

100-
pub(crate) fn write_filenames_section_to_buffer(filenames: &Vec<CString>, buffer: &RustString) {
101-
let c_str_vec = filenames.iter().map(|cstring| cstring.as_ptr()).collect::<Vec<_>>();
100+
pub(crate) fn write_filenames_section_to_buffer<'a>(
101+
filenames: impl IntoIterator<Item = &'a CString>,
102+
buffer: &RustString,
103+
) {
104+
let c_str_vec = filenames.into_iter().map(|cstring| cstring.as_ptr()).collect::<Vec<_>>();
102105
unsafe {
103106
llvm::LLVMRustCoverageWriteFilenamesSectionToBuffer(
104107
c_str_vec.as_ptr(),

src/librustc_data_structures/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ doctest = false
1111

1212
[dependencies]
1313
ena = "0.14"
14-
indexmap = "1"
14+
indexmap = "1.5.1"
1515
log = { package = "tracing", version = "0.1" }
1616
jobserver_crate = { version = "0.1.13", package = "jobserver" }
1717
lazy_static = "1"

src/librustc_data_structures/transitive_relation.rs

+13-26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::fx::FxHashMap;
1+
use crate::fx::FxIndexSet;
22
use crate::stable_hasher::{HashStable, StableHasher};
33
use crate::sync::Lock;
44
use rustc_index::bit_set::BitMatrix;
@@ -13,10 +13,7 @@ mod tests;
1313
#[derive(Clone, Debug)]
1414
pub struct TransitiveRelation<T: Eq + Hash> {
1515
// List of elements. This is used to map from a T to a usize.
16-
elements: Vec<T>,
17-
18-
// Maps each element to an index.
19-
map: FxHashMap<T, Index>,
16+
elements: FxIndexSet<T>,
2017

2118
// List of base edges in the graph. Require to compute transitive
2219
// closure.
@@ -39,7 +36,6 @@ impl<T: Eq + Hash> Default for TransitiveRelation<T> {
3936
fn default() -> Self {
4037
TransitiveRelation {
4138
elements: Default::default(),
42-
map: Default::default(),
4339
edges: Default::default(),
4440
closure: Default::default(),
4541
}
@@ -65,20 +61,16 @@ impl<T: Clone + Debug + Eq + Hash> TransitiveRelation<T> {
6561
}
6662

6763
fn index(&self, a: &T) -> Option<Index> {
68-
self.map.get(a).cloned()
64+
self.elements.get_index_of(a).map(Index)
6965
}
7066

7167
fn add_index(&mut self, a: T) -> Index {
72-
let &mut TransitiveRelation { ref mut elements, ref mut closure, ref mut map, .. } = self;
73-
74-
*map.entry(a.clone()).or_insert_with(|| {
75-
elements.push(a);
76-
68+
let (index, added) = self.elements.insert_full(a);
69+
if added {
7770
// if we changed the dimensions, clear the cache
78-
*closure.get_mut() = None;
79-
80-
Index(elements.len() - 1)
81-
})
71+
*self.closure.get_mut() = None;
72+
}
73+
Index(index)
8274
}
8375

8476
/// Applies the (partial) function to each edge and returns a new
@@ -430,14 +422,11 @@ where
430422
{
431423
fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
432424
d.read_struct("TransitiveRelation", 2, |d| {
433-
let elements: Vec<T> = d.read_struct_field("elements", 0, |d| Decodable::decode(d))?;
434-
let edges = d.read_struct_field("edges", 1, |d| Decodable::decode(d))?;
435-
let map = elements
436-
.iter()
437-
.enumerate()
438-
.map(|(index, elem)| (elem.clone(), Index(index)))
439-
.collect();
440-
Ok(TransitiveRelation { elements, edges, map, closure: Lock::new(None) })
425+
Ok(TransitiveRelation {
426+
elements: d.read_struct_field("elements", 0, |d| Decodable::decode(d))?,
427+
edges: d.read_struct_field("edges", 1, |d| Decodable::decode(d))?,
428+
closure: Lock::new(None),
429+
})
441430
})
442431
}
443432
}
@@ -452,8 +441,6 @@ where
452441
let TransitiveRelation {
453442
ref elements,
454443
ref edges,
455-
// "map" is just a copy of elements vec
456-
map: _,
457444
// "closure" is just a copy of the data above
458445
closure: _,
459446
} = *self;

src/librustc_metadata/rmeta/encoder.rs

+5-17
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::rmeta::*;
44
use log::{debug, trace};
55
use rustc_ast::ast;
66
use rustc_data_structures::fingerprint::Fingerprint;
7-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
7+
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
88
use rustc_data_structures::stable_hasher::StableHasher;
99
use rustc_data_structures::sync::{join, Lrc};
1010
use rustc_hir as hir;
@@ -48,8 +48,7 @@ struct EncodeContext<'a, 'tcx> {
4848
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
4949
predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
5050

51-
interpret_allocs: FxHashMap<interpret::AllocId, usize>,
52-
interpret_allocs_inverse: Vec<interpret::AllocId>,
51+
interpret_allocs: FxIndexSet<interpret::AllocId>,
5352

5453
// This is used to speed up Span encoding.
5554
// The `usize` is an index into the `MonotonicVec`
@@ -331,17 +330,7 @@ impl<'a, 'b, 'tcx> SpecializedEncoder<ty::Predicate<'b>> for EncodeContext<'a, '
331330

332331
impl<'a, 'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'a, 'tcx> {
333332
fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
334-
use std::collections::hash_map::Entry;
335-
let index = match self.interpret_allocs.entry(*alloc_id) {
336-
Entry::Occupied(e) => *e.get(),
337-
Entry::Vacant(e) => {
338-
let idx = self.interpret_allocs_inverse.len();
339-
self.interpret_allocs_inverse.push(*alloc_id);
340-
e.insert(idx);
341-
idx
342-
}
343-
};
344-
333+
let (index, _) = self.interpret_allocs.insert_full(*alloc_id);
345334
index.encode(self)
346335
}
347336
}
@@ -583,15 +572,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
583572
let mut n = 0;
584573
trace!("beginning to encode alloc ids");
585574
loop {
586-
let new_n = self.interpret_allocs_inverse.len();
575+
let new_n = self.interpret_allocs.len();
587576
// if we have found new ids, serialize those, too
588577
if n == new_n {
589578
// otherwise, abort
590579
break;
591580
}
592581
trace!("encoding {} further alloc ids", new_n - n);
593582
for idx in n..new_n {
594-
let id = self.interpret_allocs_inverse[idx];
583+
let id = self.interpret_allocs[idx];
595584
let pos = self.position() as u32;
596585
interpret_alloc_index.push(pos);
597586
interpret::specialized_encode_alloc_id(self, tcx, id).unwrap();
@@ -2019,7 +2008,6 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
20192008
predicate_shorthands: Default::default(),
20202009
source_file_cache: (source_map_files[0].clone(), 0),
20212010
interpret_allocs: Default::default(),
2022-
interpret_allocs_inverse: Default::default(),
20232011
required_source_files: Some(GrowableBitSet::with_capacity(source_map_files.len())),
20242012
is_proc_macro: tcx.sess.crate_types().contains(&CrateType::ProcMacro),
20252013
hygiene_ctxt: &hygiene_ctxt,

src/librustc_middle/ty/query/on_disk_cache.rs

+5-17
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder};
55
use crate::ty::context::TyCtxt;
66
use crate::ty::{self, Ty};
77
use rustc_data_structures::fingerprint::Fingerprint;
8-
use rustc_data_structures::fx::FxHashMap;
8+
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
99
use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, OnceCell};
1010
use rustc_data_structures::thin_vec::ThinVec;
1111
use rustc_errors::Diagnostic;
@@ -212,7 +212,6 @@ impl<'sess> OnDiskCache<'sess> {
212212
type_shorthands: Default::default(),
213213
predicate_shorthands: Default::default(),
214214
interpret_allocs: Default::default(),
215-
interpret_allocs_inverse: Vec::new(),
216215
source_map: CachingSourceMapView::new(tcx.sess.source_map()),
217216
file_to_file_index,
218217
hygiene_context: &hygiene_encode_context,
@@ -267,15 +266,15 @@ impl<'sess> OnDiskCache<'sess> {
267266
let mut interpret_alloc_index = Vec::new();
268267
let mut n = 0;
269268
loop {
270-
let new_n = encoder.interpret_allocs_inverse.len();
269+
let new_n = encoder.interpret_allocs.len();
271270
// If we have found new IDs, serialize those too.
272271
if n == new_n {
273272
// Otherwise, abort.
274273
break;
275274
}
276275
interpret_alloc_index.reserve(new_n - n);
277276
for idx in n..new_n {
278-
let id = encoder.interpret_allocs_inverse[idx];
277+
let id = encoder.interpret_allocs[idx];
279278
let pos = encoder.position() as u32;
280279
interpret_alloc_index.push(pos);
281280
interpret::specialized_encode_alloc_id(&mut encoder, tcx, id)?;
@@ -767,8 +766,7 @@ struct CacheEncoder<'a, 'tcx, E: ty_codec::TyEncoder> {
767766
encoder: &'a mut E,
768767
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
769768
predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
770-
interpret_allocs: FxHashMap<interpret::AllocId, usize>,
771-
interpret_allocs_inverse: Vec<interpret::AllocId>,
769+
interpret_allocs: FxIndexSet<interpret::AllocId>,
772770
source_map: CachingSourceMapView<'tcx>,
773771
file_to_file_index: FxHashMap<*const SourceFile, SourceFileIndex>,
774772
hygiene_context: &'a HygieneEncodeContext,
@@ -807,17 +805,7 @@ where
807805
E: 'a + TyEncoder,
808806
{
809807
fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
810-
use std::collections::hash_map::Entry;
811-
let index = match self.interpret_allocs.entry(*alloc_id) {
812-
Entry::Occupied(e) => *e.get(),
813-
Entry::Vacant(e) => {
814-
let idx = self.interpret_allocs_inverse.len();
815-
self.interpret_allocs_inverse.push(*alloc_id);
816-
e.insert(idx);
817-
idx
818-
}
819-
};
820-
808+
let (index, _) = self.interpret_allocs.insert_full(*alloc_id);
821809
index.encode(self)
822810
}
823811
}

0 commit comments

Comments
 (0)