Skip to content

Commit 72ee14c

Browse files
Allow for more efficient sorting when exporting Unord collections.
1 parent c3d2573 commit 72ee14c

File tree

7 files changed

+99
-34
lines changed

7 files changed

+99
-34
lines changed

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ fn exported_symbols_provider_local(
177177
// Can we skip the later sorting?
178178
let mut symbols: Vec<_> = tcx.with_stable_hashing_context(|hcx| {
179179
tcx.reachable_non_generics(LOCAL_CRATE)
180-
.to_sorted(&hcx)
180+
.to_sorted(&hcx, true)
181181
.into_iter()
182182
.map(|(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info))
183183
.collect()

compiler/rustc_data_structures/src/unord.rs

+80-7
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::{
1414

1515
use crate::{
1616
fingerprint::Fingerprint,
17-
stable_hasher::{HashStable, StableHasher, ToStableHashKey},
17+
stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey},
1818
};
1919

2020
/// `UnordItems` is the order-less version of `Iterator`. It only contains methods
@@ -158,6 +158,7 @@ pub struct UnordSet<V: Eq + Hash> {
158158
}
159159

160160
impl<V: Eq + Hash> Default for UnordSet<V> {
161+
#[inline]
161162
fn default() -> Self {
162163
Self { inner: FxHashSet::default() }
163164
}
@@ -207,6 +208,46 @@ impl<V: Eq + Hash> UnordSet<V> {
207208
UnordItems(self.inner.into_iter())
208209
}
209210

211+
#[inline]
212+
pub fn to_sorted<HCX>(&self, hcx: &HCX, cache_sort_key: bool) -> Vec<&V>
213+
where
214+
V: ToStableHashKey<HCX>,
215+
{
216+
let mut items: Vec<&V> = self.inner.iter().collect();
217+
if cache_sort_key {
218+
items.sort_by_cached_key(|k| k.to_stable_hash_key(hcx));
219+
} else {
220+
items.sort_unstable_by_key(|k| k.to_stable_hash_key(hcx));
221+
}
222+
223+
items
224+
}
225+
226+
#[inline]
227+
pub fn to_sorted_stable_ord(&self) -> Vec<V>
228+
where
229+
V: Ord + StableOrd + Copy,
230+
{
231+
let mut items: Vec<V> = self.inner.iter().copied().collect();
232+
items.sort_unstable();
233+
items
234+
}
235+
236+
#[inline]
237+
pub fn into_sorted<HCX>(self, hcx: &HCX, cache_sort_key: bool) -> Vec<V>
238+
where
239+
V: ToStableHashKey<HCX>,
240+
{
241+
let mut items: Vec<V> = self.inner.into_iter().collect();
242+
if cache_sort_key {
243+
items.sort_by_cached_key(|k| k.to_stable_hash_key(hcx));
244+
} else {
245+
items.sort_unstable_by_key(|k| k.to_stable_hash_key(hcx));
246+
}
247+
248+
items
249+
}
250+
210251
// We can safely extend this UnordSet from a set of unordered values because that
211252
// won't expose the internal ordering anywhere.
212253
#[inline]
@@ -221,12 +262,14 @@ impl<V: Eq + Hash> UnordSet<V> {
221262
}
222263

223264
impl<V: Hash + Eq> Extend<V> for UnordSet<V> {
265+
#[inline]
224266
fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
225267
self.inner.extend(iter)
226268
}
227269
}
228270

229271
impl<V: Hash + Eq> FromIterator<V> for UnordSet<V> {
272+
#[inline]
230273
fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
231274
UnordSet { inner: FxHashSet::from_iter(iter) }
232275
}
@@ -254,24 +297,28 @@ pub struct UnordMap<K: Eq + Hash, V> {
254297
}
255298

256299
impl<K: Eq + Hash, V> Default for UnordMap<K, V> {
300+
#[inline]
257301
fn default() -> Self {
258302
Self { inner: FxHashMap::default() }
259303
}
260304
}
261305

262306
impl<K: Hash + Eq, V> Extend<(K, V)> for UnordMap<K, V> {
307+
#[inline]
263308
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
264309
self.inner.extend(iter)
265310
}
266311
}
267312

268313
impl<K: Hash + Eq, V> FromIterator<(K, V)> for UnordMap<K, V> {
314+
#[inline]
269315
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
270316
UnordMap { inner: FxHashMap::from_iter(iter) }
271317
}
272318
}
273319

274320
impl<K: Hash + Eq, V, I: Iterator<Item = (K, V)>> From<UnordItems<(K, V), I>> for UnordMap<K, V> {
321+
#[inline]
275322
fn from(items: UnordItems<(K, V), I>) -> Self {
276323
UnordMap { inner: FxHashMap::from_iter(items.0) }
277324
}
@@ -351,30 +398,56 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
351398
self.inner.extend(items.0)
352399
}
353400

354-
pub fn to_sorted<HCX>(&self, hcx: &HCX) -> Vec<(&K, &V)>
401+
#[inline]
402+
pub fn to_sorted<HCX>(&self, hcx: &HCX, cache_sort_key: bool) -> Vec<(&K, &V)>
355403
where
356404
K: ToStableHashKey<HCX>,
357405
{
358406
let mut items: Vec<(&K, &V)> = self.inner.iter().collect();
359-
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
407+
if cache_sort_key {
408+
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
409+
} else {
410+
items.sort_unstable_by_key(|(k, _)| k.to_stable_hash_key(hcx));
411+
}
412+
360413
items
361414
}
362415

363-
pub fn into_sorted<HCX>(self, hcx: &HCX) -> Vec<(K, V)>
416+
#[inline]
417+
pub fn to_sorted_stable_ord(&self) -> Vec<(K, &V)>
418+
where
419+
K: Ord + StableOrd + Copy,
420+
{
421+
let mut items: Vec<(K, &V)> = self.inner.iter().map(|(&k, v)| (k, v)).collect();
422+
items.sort_unstable_by_key(|&(k, _)| k);
423+
items
424+
}
425+
426+
#[inline]
427+
pub fn into_sorted<HCX>(self, hcx: &HCX, cache_sort_key: bool) -> Vec<(K, V)>
364428
where
365429
K: ToStableHashKey<HCX>,
366430
{
367431
let mut items: Vec<(K, V)> = self.inner.into_iter().collect();
368-
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
432+
if cache_sort_key {
433+
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
434+
} else {
435+
items.sort_unstable_by_key(|(k, _)| k.to_stable_hash_key(hcx));
436+
}
369437
items
370438
}
371439

372-
pub fn values_sorted<HCX>(&self, hcx: &HCX) -> impl Iterator<Item = &V>
440+
#[inline]
441+
pub fn values_sorted<HCX>(&self, hcx: &HCX, cache_sort_key: bool) -> impl Iterator<Item = &V>
373442
where
374443
K: ToStableHashKey<HCX>,
375444
{
376445
let mut items: Vec<(&K, &V)> = self.inner.iter().collect();
377-
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
446+
if cache_sort_key {
447+
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
448+
} else {
449+
items.sort_unstable_by_key(|(k, _)| k.to_stable_hash_key(hcx));
450+
}
378451
items.into_iter().map(|(_, v)| v)
379452
}
380453
}

compiler/rustc_hir_typeck/src/writeback.rs

+12-19
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use rustc_middle::ty::TypeckResults;
1919
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
2020
use rustc_span::symbol::sym;
2121
use rustc_span::Span;
22-
use smallvec::SmallVec;
2322

2423
use std::mem;
2524
use std::ops::ControlFlow;
@@ -450,9 +449,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
450449
let common_hir_owner = fcx_typeck_results.hir_owner;
451450

452451
let fcx_closure_kind_origins =
453-
fcx_typeck_results.closure_kind_origins().items_in_stable_order(self.tcx());
452+
fcx_typeck_results.closure_kind_origins().items_in_stable_order();
454453

455-
for (&local_id, origin) in fcx_closure_kind_origins {
454+
for (local_id, origin) in fcx_closure_kind_origins {
456455
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
457456
let place_span = origin.0;
458457
let place = self.resolve(origin.1.clone(), &place_span);
@@ -465,14 +464,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
465464

466465
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
467466

468-
self.tcx().with_stable_hashing_context(|hcx| {
469-
let fcx_coercion_casts: SmallVec<[_; 32]> =
470-
fcx_typeck_results.coercion_casts().items().cloned().into_sorted_small_vec(&hcx);
471-
472-
for local_id in fcx_coercion_casts {
473-
self.typeck_results.set_coercion_cast(local_id);
474-
}
475-
});
467+
let fcx_coercion_casts = fcx_typeck_results.coercion_casts().to_sorted_stable_ord();
468+
for local_id in fcx_coercion_casts {
469+
self.typeck_results.set_coercion_cast(local_id);
470+
}
476471
}
477472

478473
fn visit_user_provided_tys(&mut self) {
@@ -482,10 +477,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
482477

483478
if self.rustc_dump_user_substs {
484479
let sorted_user_provided_types =
485-
fcx_typeck_results.user_provided_types().items_in_stable_order(self.tcx());
480+
fcx_typeck_results.user_provided_types().items_in_stable_order();
486481

487482
let mut errors_buffer = Vec::new();
488-
for (&local_id, c_ty) in sorted_user_provided_types {
483+
for (local_id, c_ty) in sorted_user_provided_types {
489484
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
490485

491486
if let ty::UserType::TypeOf(_, user_substs) = c_ty.value {
@@ -661,10 +656,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
661656
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
662657
let common_hir_owner = fcx_typeck_results.hir_owner;
663658

664-
let fcx_liberated_fn_sigs =
665-
fcx_typeck_results.liberated_fn_sigs().items_in_stable_order(self.tcx());
659+
let fcx_liberated_fn_sigs = fcx_typeck_results.liberated_fn_sigs().items_in_stable_order();
666660

667-
for (&local_id, &fn_sig) in fcx_liberated_fn_sigs {
661+
for (local_id, &fn_sig) in fcx_liberated_fn_sigs {
668662
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
669663
let fn_sig = self.resolve(fn_sig, &hir_id);
670664
self.typeck_results.liberated_fn_sigs_mut().insert(hir_id, fn_sig);
@@ -676,10 +670,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
676670
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
677671
let common_hir_owner = fcx_typeck_results.hir_owner;
678672

679-
let fcx_fru_field_types =
680-
fcx_typeck_results.fru_field_types().items_in_stable_order(self.tcx());
673+
let fcx_fru_field_types = fcx_typeck_results.fru_field_types().items_in_stable_order();
681674

682-
for (&local_id, ftys) in fcx_fru_field_types {
675+
for (local_id, ftys) in fcx_fru_field_types {
683676
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
684677
let ftys = self.resolve(ftys.clone(), &hir_id);
685678
self.typeck_results.fru_field_types_mut().insert(hir_id, ftys);

compiler/rustc_metadata/src/rmeta/encoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
11881188
}
11891189
}
11901190
let inherent_impls = tcx.with_stable_hashing_context(|hcx| {
1191-
tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx)
1191+
tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx, true)
11921192
});
11931193

11941194
for (def_id, implementations) in inherent_impls {

compiler/rustc_middle/src/ty/typeck_results.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use rustc_session::Session;
2727
use rustc_span::Span;
2828
use std::{collections::hash_map::Entry, hash::Hash, iter};
2929

30-
use super::{RvalueScopes, TyCtxt};
30+
use super::RvalueScopes;
3131

3232
#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
3333
pub struct TypeckResults<'tcx> {
@@ -575,9 +575,8 @@ impl<'a, V> LocalTableInContext<'a, V> {
575575
self.data.items().map(|(id, value)| (*id, value))
576576
}
577577

578-
#[allow(rustc::pass_by_value)]
579-
pub fn items_in_stable_order(&self, tcx: TyCtxt<'_>) -> Vec<(&'a ItemLocalId, &'a V)> {
580-
tcx.with_stable_hashing_context(|hcx| self.data.to_sorted(&hcx))
578+
pub fn items_in_stable_order(&self) -> Vec<(ItemLocalId, &'a V)> {
579+
self.data.to_sorted_stable_ord()
581580
}
582581
}
583582

src/tools/clippy/clippy_lints/src/inherent_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
5454

5555
let inherent_impls = cx
5656
.tcx
57-
.with_stable_hashing_context(|hcx| cx.tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx));
57+
.with_stable_hashing_context(|hcx| cx.tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx, true));
5858

5959
for (_, impl_ids) in inherent_impls.into_iter().filter(|(&id, impls)| {
6060
impls.len() > 1

src/tools/clippy/clippy_lints/src/missing_trait_methods.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods {
8181
}
8282

8383
cx.tcx.with_stable_hashing_context(|hcx| {
84-
for assoc in provided.values_sorted(&hcx) {
84+
for assoc in provided.values_sorted(&hcx, true) {
8585
let source_map = cx.tcx.sess.source_map();
8686
let definition_span = source_map.guess_head_span(cx.tcx.def_span(assoc.def_id));
8787

0 commit comments

Comments
 (0)