Skip to content

Commit a0df04c

Browse files
committed
Auto merge of #110040 - ndrewxie:issue-84447-partial-1, r=lcnr,michaelwoerister
Removed use of iteration through a HashMap/HashSet in rustc_incremental and replaced with IndexMap/IndexSet This allows for the `#[allow(rustc::potential_query_instability)]` in rustc_incremental to be removed, moving towards fixing #84447 (although a LOT more modules have to be changed to fully resolve it). Only HashMaps/HashSets that are being iterated through have been modified (although many structs and traits outside of rustc_incremental had to be modified as well, as they had fields/methods that involved a HashMap/HashSet that would be iterated through) I'm making a PR for just 1 module changed to test for performance regressions and such, for future changes I'll either edit this PR to reflect additional modules being converted, or batch multiple modules of changes together and make a PR for each group of modules.
2 parents 8091736 + 3f324a8 commit a0df04c

File tree

25 files changed

+261
-192
lines changed

25 files changed

+261
-192
lines changed

compiler/rustc_abi/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,9 @@ pub struct Size {
414414
// Safety: Ord is implement as just comparing numerical values and numerical values
415415
// are not changed by (de-)serialization.
416416
#[cfg(feature = "nightly")]
417-
unsafe impl StableOrd for Size {}
417+
unsafe impl StableOrd for Size {
418+
const CAN_USE_UNSTABLE_SORT: bool = true;
419+
}
418420

419421
// This is debug-printed a lot in larger structs, don't waste too much space there
420422
impl fmt::Debug for Size {

compiler/rustc_codegen_cranelift/src/driver/aot.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ impl OngoingCodegen {
5454
self,
5555
sess: &Session,
5656
backend_config: &BackendConfig,
57-
) -> (CodegenResults, FxHashMap<WorkProductId, WorkProduct>) {
58-
let mut work_products = FxHashMap::default();
57+
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
58+
let mut work_products = FxIndexMap::default();
5959
let mut modules = vec![];
6060

6161
for module_codegen in self.modules {

compiler/rustc_codegen_cranelift/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ mod prelude {
8888
};
8989
pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT};
9090

91-
pub(crate) use rustc_data_structures::fx::FxHashMap;
91+
pub(crate) use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
9292

9393
pub(crate) use rustc_index::Idx;
9494

@@ -223,7 +223,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
223223
ongoing_codegen: Box<dyn Any>,
224224
sess: &Session,
225225
_outputs: &OutputFilenames,
226-
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
226+
) -> Result<(CodegenResults, FxIndexMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
227227
Ok(ongoing_codegen
228228
.downcast::<driver::aot::OngoingCodegen>()
229229
.unwrap()

compiler/rustc_codegen_gcc/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig,
7575
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
7676
use rustc_codegen_ssa::target_features::supported_target_features;
7777
use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods};
78-
use rustc_data_structures::fx::FxHashMap;
78+
use rustc_data_structures::fx::FxIndexMap;
7979
use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, Handler, SubdiagnosticMessage};
8080
use rustc_fluent_macro::fluent_messages;
8181
use rustc_metadata::EncodedMetadata;
@@ -137,7 +137,7 @@ impl CodegenBackend for GccCodegenBackend {
137137
Box::new(res)
138138
}
139139

140-
fn join_codegen(&self, ongoing_codegen: Box<dyn Any>, sess: &Session, _outputs: &OutputFilenames) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
140+
fn join_codegen(&self, ongoing_codegen: Box<dyn Any>, sess: &Session, _outputs: &OutputFilenames) -> Result<(CodegenResults, FxIndexMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
141141
let (codegen_results, work_products) = ongoing_codegen
142142
.downcast::<rustc_codegen_ssa::back::write::OngoingCodegen<GccCodegenBackend>>()
143143
.expect("Expected GccCodegenBackend's OngoingCodegen, found Box<Any>")

compiler/rustc_codegen_llvm/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use rustc_codegen_ssa::back::write::{
3434
use rustc_codegen_ssa::traits::*;
3535
use rustc_codegen_ssa::ModuleCodegen;
3636
use rustc_codegen_ssa::{CodegenResults, CompiledModule};
37-
use rustc_data_structures::fx::FxHashMap;
37+
use rustc_data_structures::fx::FxIndexMap;
3838
use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, FatalError, Handler, SubdiagnosticMessage};
3939
use rustc_fluent_macro::fluent_messages;
4040
use rustc_metadata::EncodedMetadata;
@@ -356,7 +356,7 @@ impl CodegenBackend for LlvmCodegenBackend {
356356
ongoing_codegen: Box<dyn Any>,
357357
sess: &Session,
358358
outputs: &OutputFilenames,
359-
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
359+
) -> Result<(CodegenResults, FxIndexMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
360360
let (codegen_results, work_products) = ongoing_codegen
361361
.downcast::<rustc_codegen_ssa::back::write::OngoingCodegen<LlvmCodegenBackend>>()
362362
.expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box<Any>")

compiler/rustc_codegen_ssa/src/back/write.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::{
99
};
1010
use jobserver::{Acquired, Client};
1111
use rustc_ast::attr;
12-
use rustc_data_structures::fx::FxHashMap;
12+
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
1313
use rustc_data_structures::memmap::Mmap;
1414
use rustc_data_structures::profiling::SelfProfilerRef;
1515
use rustc_data_structures::profiling::TimingGuard;
@@ -498,8 +498,8 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
498498
fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
499499
sess: &Session,
500500
compiled_modules: &CompiledModules,
501-
) -> FxHashMap<WorkProductId, WorkProduct> {
502-
let mut work_products = FxHashMap::default();
501+
) -> FxIndexMap<WorkProductId, WorkProduct> {
502+
let mut work_products = FxIndexMap::default();
503503

504504
if sess.opts.incremental.is_none() {
505505
return work_products;
@@ -1885,7 +1885,7 @@ pub struct OngoingCodegen<B: ExtraBackendMethods> {
18851885
}
18861886

18871887
impl<B: ExtraBackendMethods> OngoingCodegen<B> {
1888-
pub fn join(self, sess: &Session) -> (CodegenResults, FxHashMap<WorkProductId, WorkProduct>) {
1888+
pub fn join(self, sess: &Session) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
18891889
let _timer = sess.timer("finish_ongoing_codegen");
18901890

18911891
self.shared_emitter_main.check(sess, true);

compiler/rustc_codegen_ssa/src/traits/backend.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::back::write::TargetMachineFactoryFn;
66
use crate::{CodegenResults, ModuleCodegen};
77

88
use rustc_ast::expand::allocator::AllocatorKind;
9-
use rustc_data_structures::fx::FxHashMap;
9+
use rustc_data_structures::fx::FxIndexMap;
1010
use rustc_data_structures::sync::{DynSend, DynSync};
1111
use rustc_errors::ErrorGuaranteed;
1212
use rustc_metadata::EncodedMetadata;
@@ -101,7 +101,7 @@ pub trait CodegenBackend {
101101
ongoing_codegen: Box<dyn Any>,
102102
sess: &Session,
103103
outputs: &OutputFilenames,
104-
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorGuaranteed>;
104+
) -> Result<(CodegenResults, FxIndexMap<WorkProductId, WorkProduct>), ErrorGuaranteed>;
105105

106106
/// This is called on the returned `Box<dyn Any>` from `join_codegen`
107107
///

compiler/rustc_data_structures/src/stable_hasher.rs

+45-5
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,17 @@ pub trait ToStableHashKey<HCX> {
233233
/// - `DefIndex`, `CrateNum`, `LocalDefId`, because their concrete
234234
/// values depend on state that might be different between
235235
/// compilation sessions.
236-
pub unsafe trait StableOrd: Ord {}
236+
///
237+
/// The associated constant `CAN_USE_UNSTABLE_SORT` denotes whether
238+
/// unstable sorting can be used for this type. Set to true if and
239+
/// only if `a == b` implies `a` and `b` are fully indistinguishable.
240+
pub unsafe trait StableOrd: Ord {
241+
const CAN_USE_UNSTABLE_SORT: bool;
242+
}
243+
244+
unsafe impl<T: StableOrd> StableOrd for &T {
245+
const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
246+
}
237247

238248
/// Implement HashStable by just calling `Hash::hash()`. Also implement `StableOrd` for the type since
239249
/// that has the same requirements.
@@ -253,7 +263,9 @@ macro_rules! impl_stable_traits_for_trivial_type {
253263
}
254264
}
255265

256-
unsafe impl $crate::stable_hasher::StableOrd for $t {}
266+
unsafe impl $crate::stable_hasher::StableOrd for $t {
267+
const CAN_USE_UNSTABLE_SORT: bool = true;
268+
}
257269
};
258270
}
259271

@@ -339,6 +351,10 @@ impl<T1: HashStable<CTX>, T2: HashStable<CTX>, CTX> HashStable<CTX> for (T1, T2)
339351
}
340352
}
341353

354+
unsafe impl<T1: StableOrd, T2: StableOrd> StableOrd for (T1, T2) {
355+
const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT;
356+
}
357+
342358
impl<T1, T2, T3, CTX> HashStable<CTX> for (T1, T2, T3)
343359
where
344360
T1: HashStable<CTX>,
@@ -353,6 +369,11 @@ where
353369
}
354370
}
355371

372+
unsafe impl<T1: StableOrd, T2: StableOrd, T3: StableOrd> StableOrd for (T1, T2, T3) {
373+
const CAN_USE_UNSTABLE_SORT: bool =
374+
T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT && T3::CAN_USE_UNSTABLE_SORT;
375+
}
376+
356377
impl<T1, T2, T3, T4, CTX> HashStable<CTX> for (T1, T2, T3, T4)
357378
where
358379
T1: HashStable<CTX>,
@@ -369,6 +390,15 @@ where
369390
}
370391
}
371392

393+
unsafe impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd
394+
for (T1, T2, T3, T4)
395+
{
396+
const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT
397+
&& T2::CAN_USE_UNSTABLE_SORT
398+
&& T3::CAN_USE_UNSTABLE_SORT
399+
&& T4::CAN_USE_UNSTABLE_SORT;
400+
}
401+
372402
impl<T: HashStable<CTX>, CTX> HashStable<CTX> for [T] {
373403
default fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
374404
self.len().hash_stable(ctx, hasher);
@@ -459,6 +489,10 @@ impl<CTX> HashStable<CTX> for str {
459489
}
460490
}
461491

492+
unsafe impl StableOrd for &str {
493+
const CAN_USE_UNSTABLE_SORT: bool = true;
494+
}
495+
462496
impl<CTX> HashStable<CTX> for String {
463497
#[inline]
464498
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
@@ -468,7 +502,9 @@ impl<CTX> HashStable<CTX> for String {
468502

469503
// Safety: String comparison only depends on their contents and the
470504
// contents are not changed by (de-)serialization.
471-
unsafe impl StableOrd for String {}
505+
unsafe impl StableOrd for String {
506+
const CAN_USE_UNSTABLE_SORT: bool = true;
507+
}
472508

473509
impl<HCX> ToStableHashKey<HCX> for String {
474510
type KeyType = String;
@@ -494,7 +530,9 @@ impl<CTX> HashStable<CTX> for bool {
494530
}
495531

496532
// Safety: sort order of bools is not changed by (de-)serialization.
497-
unsafe impl StableOrd for bool {}
533+
unsafe impl StableOrd for bool {
534+
const CAN_USE_UNSTABLE_SORT: bool = true;
535+
}
498536

499537
impl<T, CTX> HashStable<CTX> for Option<T>
500538
where
@@ -512,7 +550,9 @@ where
512550
}
513551

514552
// Safety: the Option wrapper does not add instability to comparison.
515-
unsafe impl<T: StableOrd> StableOrd for Option<T> {}
553+
unsafe impl<T: StableOrd> StableOrd for Option<T> {
554+
const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
555+
}
516556

517557
impl<T1, T2, CTX> HashStable<CTX> for Result<T1, T2>
518558
where

compiler/rustc_data_structures/src/unord.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,12 @@ impl<T: Ord, I: Iterator<Item = T>> UnordItems<T, I> {
140140
}
141141

142142
#[inline]
143-
pub fn into_sorted_stable_ord(self, use_stable_sort: bool) -> Vec<T>
143+
pub fn into_sorted_stable_ord(self) -> Vec<T>
144144
where
145145
T: Ord + StableOrd,
146146
{
147147
let mut items: Vec<T> = self.0.collect();
148-
if use_stable_sort {
148+
if !T::CAN_USE_UNSTABLE_SORT {
149149
items.sort();
150150
} else {
151151
items.sort_unstable()
@@ -161,6 +161,10 @@ impl<T: Ord, I: Iterator<Item = T>> UnordItems<T, I> {
161161
items.sort_by_cached_key(|x| x.to_stable_hash_key(hcx));
162162
items
163163
}
164+
165+
pub fn collect<C: From<UnordItems<T, I>>>(self) -> C {
166+
self.into()
167+
}
164168
}
165169

166170
/// This is a set collection type that tries very hard to not expose

compiler/rustc_hir/src/hir_id.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@ impl ItemLocalId {
166166

167167
// Safety: Ord is implement as just comparing the ItemLocalId's numerical
168168
// values and these are not changed by (de-)serialization.
169-
unsafe impl StableOrd for ItemLocalId {}
169+
unsafe impl StableOrd for ItemLocalId {
170+
const CAN_USE_UNSTABLE_SORT: bool = true;
171+
}
170172

171173
/// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`.
172174
pub const CRATE_HIR_ID: HirId =

compiler/rustc_incremental/src/assert_dep_graph.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
3636
use crate::errors;
3737
use rustc_ast as ast;
38-
use rustc_data_structures::fx::FxHashSet;
38+
use rustc_data_structures::fx::FxIndexSet;
3939
use rustc_data_structures::graph::implementation::{Direction, NodeIndex, INCOMING, OUTGOING};
4040
use rustc_graphviz as dot;
4141
use rustc_hir as hir;
@@ -258,7 +258,7 @@ fn dump_graph(query: &DepGraphQuery) {
258258
}
259259

260260
#[allow(missing_docs)]
261-
pub struct GraphvizDepGraph(FxHashSet<DepKind>, Vec<(DepKind, DepKind)>);
261+
pub struct GraphvizDepGraph(FxIndexSet<DepKind>, Vec<(DepKind, DepKind)>);
262262

263263
impl<'a> dot::GraphWalk<'a> for GraphvizDepGraph {
264264
type Node = DepKind;
@@ -303,7 +303,7 @@ impl<'a> dot::Labeller<'a> for GraphvizDepGraph {
303303
fn node_set<'q>(
304304
query: &'q DepGraphQuery,
305305
filter: &DepNodeFilter,
306-
) -> Option<FxHashSet<&'q DepNode>> {
306+
) -> Option<FxIndexSet<&'q DepNode>> {
307307
debug!("node_set(filter={:?})", filter);
308308

309309
if filter.accepts_all() {
@@ -315,9 +315,9 @@ fn node_set<'q>(
315315

316316
fn filter_nodes<'q>(
317317
query: &'q DepGraphQuery,
318-
sources: &Option<FxHashSet<&'q DepNode>>,
319-
targets: &Option<FxHashSet<&'q DepNode>>,
320-
) -> FxHashSet<DepKind> {
318+
sources: &Option<FxIndexSet<&'q DepNode>>,
319+
targets: &Option<FxIndexSet<&'q DepNode>>,
320+
) -> FxIndexSet<DepKind> {
321321
if let Some(sources) = sources {
322322
if let Some(targets) = targets {
323323
walk_between(query, sources, targets)
@@ -333,10 +333,10 @@ fn filter_nodes<'q>(
333333

334334
fn walk_nodes<'q>(
335335
query: &'q DepGraphQuery,
336-
starts: &FxHashSet<&'q DepNode>,
336+
starts: &FxIndexSet<&'q DepNode>,
337337
direction: Direction,
338-
) -> FxHashSet<DepKind> {
339-
let mut set = FxHashSet::default();
338+
) -> FxIndexSet<DepKind> {
339+
let mut set = FxIndexSet::default();
340340
for &start in starts {
341341
debug!("walk_nodes: start={:?} outgoing?={:?}", start, direction == OUTGOING);
342342
if set.insert(start.kind) {
@@ -357,9 +357,9 @@ fn walk_nodes<'q>(
357357

358358
fn walk_between<'q>(
359359
query: &'q DepGraphQuery,
360-
sources: &FxHashSet<&'q DepNode>,
361-
targets: &FxHashSet<&'q DepNode>,
362-
) -> FxHashSet<DepKind> {
360+
sources: &FxIndexSet<&'q DepNode>,
361+
targets: &FxIndexSet<&'q DepNode>,
362+
) -> FxIndexSet<DepKind> {
363363
// This is a bit tricky. We want to include a node only if it is:
364364
// (a) reachable from a source and (b) will reach a target. And we
365365
// have to be careful about cycles etc. Luckily efficiency is not
@@ -426,8 +426,8 @@ fn walk_between<'q>(
426426
}
427427
}
428428

429-
fn filter_edges(query: &DepGraphQuery, nodes: &FxHashSet<DepKind>) -> Vec<(DepKind, DepKind)> {
430-
let uniq: FxHashSet<_> = query
429+
fn filter_edges(query: &DepGraphQuery, nodes: &FxIndexSet<DepKind>) -> Vec<(DepKind, DepKind)> {
430+
let uniq: FxIndexSet<_> = query
431431
.edges()
432432
.into_iter()
433433
.map(|(s, t)| (s.kind, t.kind))

compiler/rustc_incremental/src/assert_module_sources.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
2525
use crate::errors;
2626
use rustc_ast as ast;
27-
use rustc_data_structures::fx::FxHashSet;
27+
use rustc_data_structures::unord::UnordSet;
2828
use rustc_hir::def_id::LOCAL_CRATE;
2929
use rustc_middle::mir::mono::CodegenUnitNameBuilder;
3030
use rustc_middle::ty::TyCtxt;
@@ -52,7 +52,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) {
5252

5353
struct AssertModuleSource<'tcx> {
5454
tcx: TyCtxt<'tcx>,
55-
available_cgus: FxHashSet<Symbol>,
55+
available_cgus: UnordSet<Symbol>,
5656
}
5757

5858
impl<'tcx> AssertModuleSource<'tcx> {
@@ -118,9 +118,8 @@ impl<'tcx> AssertModuleSource<'tcx> {
118118
debug!("mapping '{}' to cgu name '{}'", self.field(attr, sym::module), cgu_name);
119119

120120
if !self.available_cgus.contains(&cgu_name) {
121-
let mut cgu_names: Vec<&str> =
122-
self.available_cgus.iter().map(|cgu| cgu.as_str()).collect();
123-
cgu_names.sort();
121+
let cgu_names: Vec<&str> =
122+
self.available_cgus.items().map(|cgu| cgu.as_str()).into_sorted_stable_ord();
124123
self.tcx.sess.emit_err(errors::NoModuleNamed {
125124
span: attr.span,
126125
user_path,

compiler/rustc_incremental/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
55
#![feature(never_type)]
66
#![recursion_limit = "256"]
7-
#![allow(rustc::potential_query_instability)]
87
#![deny(rustc::untranslatable_diagnostic)]
98
#![deny(rustc::diagnostic_outside_of_impl)]
109

0 commit comments

Comments
 (0)