Skip to content

Commit c3d2573

Browse files
Use UnordMap instead of FxHashMap in define_id_collections!().
1 parent 8a1de57 commit c3d2573

File tree

15 files changed

+254
-103
lines changed

15 files changed

+254
-103
lines changed

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,15 @@ fn exported_symbols_provider_local(
173173
return &[];
174174
}
175175

176-
let mut symbols: Vec<_> = tcx
177-
.reachable_non_generics(LOCAL_CRATE)
178-
.iter()
179-
.map(|(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info))
180-
.collect();
176+
// FIXME: Sorting this is unnecessary since we are sorting later anyway.
177+
// Can we skip the later sorting?
178+
let mut symbols: Vec<_> = tcx.with_stable_hashing_context(|hcx| {
179+
tcx.reachable_non_generics(LOCAL_CRATE)
180+
.to_sorted(&hcx)
181+
.into_iter()
182+
.map(|(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info))
183+
.collect()
184+
});
181185

182186
if tcx.entry_fn(()).is_some() {
183187
let exported_symbol =

compiler/rustc_data_structures/src/fx.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub type IndexEntry<'a, K, V> = indexmap::map::Entry<'a, K, V>;
1111
#[macro_export]
1212
macro_rules! define_id_collections {
1313
($map_name:ident, $set_name:ident, $entry_name:ident, $key:ty) => {
14-
pub type $map_name<T> = $crate::fx::FxHashMap<$key, T>;
14+
pub type $map_name<T> = $crate::unord::UnordMap<$key, T>;
1515
pub type $set_name = $crate::unord::UnordSet<$key>;
1616
pub type $entry_name<'a, T> = $crate::fx::StdEntry<'a, $key, T>;
1717
};

compiler/rustc_data_structures/src/unord.rs

+108-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ use rustc_hash::{FxHashMap, FxHashSet};
66
use smallvec::SmallVec;
77
use std::{
88
borrow::Borrow,
9+
collections::hash_map::Entry,
910
hash::Hash,
1011
iter::{Product, Sum},
12+
ops::Index,
1113
};
1214

1315
use crate::{
@@ -187,7 +189,16 @@ impl<V: Eq + Hash> UnordSet<V> {
187189
}
188190

189191
#[inline]
190-
pub fn items(&self) -> UnordItems<&V, impl Iterator<Item = &V>> {
192+
pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> bool
193+
where
194+
V: Borrow<Q>,
195+
Q: Hash + Eq,
196+
{
197+
self.inner.remove(k)
198+
}
199+
200+
#[inline]
201+
pub fn items<'a>(&'a self) -> UnordItems<&'a V, impl Iterator<Item = &'a V>> {
191202
UnordItems(self.inner.iter())
192203
}
193204

@@ -254,6 +265,18 @@ impl<K: Hash + Eq, V> Extend<(K, V)> for UnordMap<K, V> {
254265
}
255266
}
256267

268+
impl<K: Hash + Eq, V> FromIterator<(K, V)> for UnordMap<K, V> {
269+
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
270+
UnordMap { inner: FxHashMap::from_iter(iter) }
271+
}
272+
}
273+
274+
impl<K: Hash + Eq, V, I: Iterator<Item = (K, V)>> From<UnordItems<(K, V), I>> for UnordMap<K, V> {
275+
fn from(items: UnordItems<(K, V), I>) -> Self {
276+
UnordMap { inner: FxHashMap::from_iter(items.0) }
277+
}
278+
}
279+
257280
impl<K: Eq + Hash, V> UnordMap<K, V> {
258281
#[inline]
259282
pub fn len(&self) -> usize {
@@ -275,7 +298,44 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
275298
}
276299

277300
#[inline]
278-
pub fn items(&self) -> UnordItems<(&K, &V), impl Iterator<Item = (&K, &V)>> {
301+
pub fn is_empty(&self) -> bool {
302+
self.inner.is_empty()
303+
}
304+
305+
#[inline]
306+
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
307+
self.inner.entry(key)
308+
}
309+
310+
#[inline]
311+
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
312+
where
313+
K: Borrow<Q>,
314+
Q: Hash + Eq,
315+
{
316+
self.inner.get(k)
317+
}
318+
319+
#[inline]
320+
pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
321+
where
322+
K: Borrow<Q>,
323+
Q: Hash + Eq,
324+
{
325+
self.inner.get_mut(k)
326+
}
327+
328+
#[inline]
329+
pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
330+
where
331+
K: Borrow<Q>,
332+
Q: Hash + Eq,
333+
{
334+
self.inner.remove(k)
335+
}
336+
337+
#[inline]
338+
pub fn items<'a>(&'a self) -> UnordItems<(&'a K, &'a V), impl Iterator<Item = (&'a K, &'a V)>> {
279339
UnordItems(self.inner.iter())
280340
}
281341

@@ -290,6 +350,46 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
290350
pub fn extend<I: Iterator<Item = (K, V)>>(&mut self, items: UnordItems<(K, V), I>) {
291351
self.inner.extend(items.0)
292352
}
353+
354+
pub fn to_sorted<HCX>(&self, hcx: &HCX) -> Vec<(&K, &V)>
355+
where
356+
K: ToStableHashKey<HCX>,
357+
{
358+
let mut items: Vec<(&K, &V)> = self.inner.iter().collect();
359+
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
360+
items
361+
}
362+
363+
pub fn into_sorted<HCX>(self, hcx: &HCX) -> Vec<(K, V)>
364+
where
365+
K: ToStableHashKey<HCX>,
366+
{
367+
let mut items: Vec<(K, V)> = self.inner.into_iter().collect();
368+
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
369+
items
370+
}
371+
372+
pub fn values_sorted<HCX>(&self, hcx: &HCX) -> impl Iterator<Item = &V>
373+
where
374+
K: ToStableHashKey<HCX>,
375+
{
376+
let mut items: Vec<(&K, &V)> = self.inner.iter().collect();
377+
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
378+
items.into_iter().map(|(_, v)| v)
379+
}
380+
}
381+
382+
impl<K, Q: ?Sized, V> Index<&Q> for UnordMap<K, V>
383+
where
384+
K: Eq + Hash + Borrow<Q>,
385+
Q: Eq + Hash,
386+
{
387+
type Output = V;
388+
389+
#[inline]
390+
fn index(&self, key: &Q) -> &V {
391+
&self.inner[key]
392+
}
293393
}
294394

295395
impl<HCX, K: Hash + Eq + HashStable<HCX>, V: HashStable<HCX>> HashStable<HCX> for UnordMap<K, V> {
@@ -354,6 +454,12 @@ impl<T> Extend<T> for UnordBag<T> {
354454
}
355455
}
356456

457+
impl<T, I: Iterator<Item = T>> From<UnordItems<T, I>> for UnordBag<T> {
458+
fn from(value: UnordItems<T, I>) -> Self {
459+
UnordBag { inner: Vec::from_iter(value.0) }
460+
}
461+
}
462+
357463
impl<HCX, V: Hash + Eq + HashStable<HCX>> HashStable<HCX> for UnordBag<V> {
358464
#[inline]
359465
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {

compiler/rustc_hir_analysis/src/variance/solve.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
//! optimal solution to the constraints. The final variance for each
66
//! inferred is then written into the `variance_map` in the tcx.
77
8-
use rustc_data_structures::fx::FxHashMap;
9-
use rustc_hir::def_id::DefId;
8+
use rustc_hir::def_id::DefIdMap;
109
use rustc_middle::ty;
1110

1211
use super::constraints::*;
@@ -89,14 +88,12 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
8988
}
9089
}
9190

92-
fn create_map(&self) -> FxHashMap<DefId, &'tcx [ty::Variance]> {
91+
fn create_map(&self) -> DefIdMap<&'tcx [ty::Variance]> {
9392
let tcx = self.terms_cx.tcx;
9493

9594
let solutions = &self.solutions;
96-
self.terms_cx
97-
.inferred_starts
98-
.iter()
99-
.map(|(&def_id, &InferredIndex(start))| {
95+
DefIdMap::from(self.terms_cx.inferred_starts.items().map(
96+
|(&def_id, &InferredIndex(start))| {
10097
let generics = tcx.generics_of(def_id);
10198
let count = generics.count();
10299

@@ -115,8 +112,8 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
115112
}
116113

117114
(def_id.to_def_id(), &*variances)
118-
})
119-
.collect()
115+
},
116+
))
120117
}
121118

122119
fn evaluate(&self, term: VarianceTermPtr<'a>) -> ty::Variance {

compiler/rustc_hir_typeck/src/writeback.rs

+54-34
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,11 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
449449
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
450450
let common_hir_owner = fcx_typeck_results.hir_owner;
451451

452-
for (id, origin) in fcx_typeck_results.closure_kind_origins().iter() {
453-
let hir_id = hir::HirId { owner: common_hir_owner, local_id: *id };
452+
let fcx_closure_kind_origins =
453+
fcx_typeck_results.closure_kind_origins().items_in_stable_order(self.tcx());
454+
455+
for (&local_id, origin) in fcx_closure_kind_origins {
456+
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
454457
let place_span = origin.0;
455458
let place = self.resolve(origin.1.clone(), &place_span);
456459
self.typeck_results.closure_kind_origins_mut().insert(hir_id, (place_span, place));
@@ -477,22 +480,15 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
477480
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
478481
let common_hir_owner = fcx_typeck_results.hir_owner;
479482

480-
let mut errors_buffer = Vec::new();
481-
for (&local_id, c_ty) in fcx_typeck_results.user_provided_types().iter() {
482-
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
483-
484-
if cfg!(debug_assertions) && c_ty.needs_infer() {
485-
span_bug!(
486-
hir_id.to_span(self.fcx.tcx),
487-
"writeback: `{:?}` has inference variables",
488-
c_ty
489-
);
490-
};
483+
if self.rustc_dump_user_substs {
484+
let sorted_user_provided_types =
485+
fcx_typeck_results.user_provided_types().items_in_stable_order(self.tcx());
491486

492-
self.typeck_results.user_provided_types_mut().insert(hir_id, *c_ty);
487+
let mut errors_buffer = Vec::new();
488+
for (&local_id, c_ty) in sorted_user_provided_types {
489+
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
493490

494-
if let ty::UserType::TypeOf(_, user_substs) = c_ty.value {
495-
if self.rustc_dump_user_substs {
491+
if let ty::UserType::TypeOf(_, user_substs) = c_ty.value {
496492
// This is a unit-testing mechanism.
497493
let span = self.tcx().hir().span(hir_id);
498494
// We need to buffer the errors in order to guarantee a consistent
@@ -504,31 +500,49 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
504500
err.buffer(&mut errors_buffer);
505501
}
506502
}
507-
}
508503

509-
if !errors_buffer.is_empty() {
510-
errors_buffer.sort_by_key(|diag| diag.span.primary_span());
511-
for mut diag in errors_buffer {
512-
self.tcx().sess.diagnostic().emit_diagnostic(&mut diag);
504+
if !errors_buffer.is_empty() {
505+
errors_buffer.sort_by_key(|diag| diag.span.primary_span());
506+
for mut diag in errors_buffer {
507+
self.tcx().sess.diagnostic().emit_diagnostic(&mut diag);
508+
}
513509
}
514510
}
511+
512+
self.typeck_results.user_provided_types_mut().extend(
513+
fcx_typeck_results.user_provided_types().items().map(|(local_id, c_ty)| {
514+
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
515+
516+
if cfg!(debug_assertions) && c_ty.needs_infer() {
517+
span_bug!(
518+
hir_id.to_span(self.fcx.tcx),
519+
"writeback: `{:?}` has inference variables",
520+
c_ty
521+
);
522+
};
523+
524+
(hir_id, *c_ty)
525+
}),
526+
);
515527
}
516528

517529
fn visit_user_provided_sigs(&mut self) {
518530
let fcx_typeck_results = self.fcx.typeck_results.borrow();
519531
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
520532

521-
for (&def_id, c_sig) in fcx_typeck_results.user_provided_sigs.iter() {
522-
if cfg!(debug_assertions) && c_sig.needs_infer() {
523-
span_bug!(
524-
self.fcx.tcx.def_span(def_id),
525-
"writeback: `{:?}` has inference variables",
526-
c_sig
527-
);
528-
};
529-
530-
self.typeck_results.user_provided_sigs.insert(def_id, *c_sig);
531-
}
533+
self.typeck_results.user_provided_sigs.extend(
534+
fcx_typeck_results.user_provided_sigs.items().map(|(&def_id, c_sig)| {
535+
if cfg!(debug_assertions) && c_sig.needs_infer() {
536+
span_bug!(
537+
self.fcx.tcx.def_span(def_id),
538+
"writeback: `{:?}` has inference variables",
539+
c_sig
540+
);
541+
};
542+
543+
(def_id, *c_sig)
544+
}),
545+
);
532546
}
533547

534548
fn visit_generator_interior_types(&mut self) {
@@ -647,7 +661,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
647661
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
648662
let common_hir_owner = fcx_typeck_results.hir_owner;
649663

650-
for (&local_id, &fn_sig) in fcx_typeck_results.liberated_fn_sigs().iter() {
664+
let fcx_liberated_fn_sigs =
665+
fcx_typeck_results.liberated_fn_sigs().items_in_stable_order(self.tcx());
666+
667+
for (&local_id, &fn_sig) in fcx_liberated_fn_sigs {
651668
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
652669
let fn_sig = self.resolve(fn_sig, &hir_id);
653670
self.typeck_results.liberated_fn_sigs_mut().insert(hir_id, fn_sig);
@@ -659,7 +676,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
659676
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
660677
let common_hir_owner = fcx_typeck_results.hir_owner;
661678

662-
for (&local_id, ftys) in fcx_typeck_results.fru_field_types().iter() {
679+
let fcx_fru_field_types =
680+
fcx_typeck_results.fru_field_types().items_in_stable_order(self.tcx());
681+
682+
for (&local_id, ftys) in fcx_fru_field_types {
663683
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
664684
let ftys = self.resolve(ftys.clone(), &hir_id);
665685
self.typeck_results.fru_field_types_mut().insert(hir_id, ftys);

compiler/rustc_lint_defs/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
extern crate rustc_macros;
77

88
pub use self::Level::*;
9-
use rustc_ast::node_id::{NodeId, NodeMap};
9+
use rustc_ast::node_id::NodeId;
1010
use rustc_ast::{AttrId, Attribute};
11+
use rustc_data_structures::fx::FxIndexMap;
1112
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
1213
use rustc_error_messages::{DiagnosticMessage, MultiSpan};
1314
use rustc_hir::HashStableContext;
@@ -544,7 +545,7 @@ pub struct BufferedEarlyLint {
544545

545546
#[derive(Default)]
546547
pub struct LintBuffer {
547-
pub map: NodeMap<Vec<BufferedEarlyLint>>,
548+
pub map: FxIndexMap<NodeId, Vec<BufferedEarlyLint>>,
548549
}
549550

550551
impl LintBuffer {

0 commit comments

Comments
 (0)