Skip to content

Commit

Permalink
Auto merge of rust-lang#110040 - ndrewxie:issue-84447-partial-1, r=lc…
Browse files Browse the repository at this point in the history
…nr,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 rust-lang#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.
  • Loading branch information
bors committed Jun 8, 2023
2 parents 8091736 + 3f324a8 commit a0df04c
Show file tree
Hide file tree
Showing 25 changed files with 261 additions and 192 deletions.
4 changes: 3 additions & 1 deletion compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,9 @@ pub struct Size {
// Safety: Ord is implement as just comparing numerical values and numerical values
// are not changed by (de-)serialization.
#[cfg(feature = "nightly")]
unsafe impl StableOrd for Size {}
unsafe impl StableOrd for Size {
const CAN_USE_UNSTABLE_SORT: bool = true;
}

// This is debug-printed a lot in larger structs, don't waste too much space there
impl fmt::Debug for Size {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/driver/aot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ impl OngoingCodegen {
self,
sess: &Session,
backend_config: &BackendConfig,
) -> (CodegenResults, FxHashMap<WorkProductId, WorkProduct>) {
let mut work_products = FxHashMap::default();
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
let mut work_products = FxIndexMap::default();
let mut modules = vec![];

for module_codegen in self.modules {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ mod prelude {
};
pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT};

pub(crate) use rustc_data_structures::fx::FxHashMap;
pub(crate) use rustc_data_structures::fx::{FxHashMap, FxIndexMap};

pub(crate) use rustc_index::Idx;

Expand Down Expand Up @@ -223,7 +223,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
ongoing_codegen: Box<dyn Any>,
sess: &Session,
_outputs: &OutputFilenames,
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
) -> Result<(CodegenResults, FxIndexMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
Ok(ongoing_codegen
.downcast::<driver::aot::OngoingCodegen>()
.unwrap()
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_gcc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig,
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
use rustc_codegen_ssa::target_features::supported_target_features;
use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, Handler, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
use rustc_metadata::EncodedMetadata;
Expand Down Expand Up @@ -137,7 +137,7 @@ impl CodegenBackend for GccCodegenBackend {
Box::new(res)
}

fn join_codegen(&self, ongoing_codegen: Box<dyn Any>, sess: &Session, _outputs: &OutputFilenames) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
fn join_codegen(&self, ongoing_codegen: Box<dyn Any>, sess: &Session, _outputs: &OutputFilenames) -> Result<(CodegenResults, FxIndexMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
let (codegen_results, work_products) = ongoing_codegen
.downcast::<rustc_codegen_ssa::back::write::OngoingCodegen<GccCodegenBackend>>()
.expect("Expected GccCodegenBackend's OngoingCodegen, found Box<Any>")
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use rustc_codegen_ssa::back::write::{
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::ModuleCodegen;
use rustc_codegen_ssa::{CodegenResults, CompiledModule};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, FatalError, Handler, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
use rustc_metadata::EncodedMetadata;
Expand Down Expand Up @@ -356,7 +356,7 @@ impl CodegenBackend for LlvmCodegenBackend {
ongoing_codegen: Box<dyn Any>,
sess: &Session,
outputs: &OutputFilenames,
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
) -> Result<(CodegenResults, FxIndexMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
let (codegen_results, work_products) = ongoing_codegen
.downcast::<rustc_codegen_ssa::back::write::OngoingCodegen<LlvmCodegenBackend>>()
.expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box<Any>")
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
};
use jobserver::{Acquired, Client};
use rustc_ast::attr;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::profiling::TimingGuard;
Expand Down Expand Up @@ -498,8 +498,8 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
sess: &Session,
compiled_modules: &CompiledModules,
) -> FxHashMap<WorkProductId, WorkProduct> {
let mut work_products = FxHashMap::default();
) -> FxIndexMap<WorkProductId, WorkProduct> {
let mut work_products = FxIndexMap::default();

if sess.opts.incremental.is_none() {
return work_products;
Expand Down Expand Up @@ -1885,7 +1885,7 @@ pub struct OngoingCodegen<B: ExtraBackendMethods> {
}

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

self.shared_emitter_main.check(sess, true);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/traits/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::back::write::TargetMachineFactoryFn;
use crate::{CodegenResults, ModuleCodegen};

use rustc_ast::expand::allocator::AllocatorKind;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_errors::ErrorGuaranteed;
use rustc_metadata::EncodedMetadata;
Expand Down Expand Up @@ -101,7 +101,7 @@ pub trait CodegenBackend {
ongoing_codegen: Box<dyn Any>,
sess: &Session,
outputs: &OutputFilenames,
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorGuaranteed>;
) -> Result<(CodegenResults, FxIndexMap<WorkProductId, WorkProduct>), ErrorGuaranteed>;

/// This is called on the returned `Box<dyn Any>` from `join_codegen`
///
Expand Down
50 changes: 45 additions & 5 deletions compiler/rustc_data_structures/src/stable_hasher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,17 @@ pub trait ToStableHashKey<HCX> {
/// - `DefIndex`, `CrateNum`, `LocalDefId`, because their concrete
/// values depend on state that might be different between
/// compilation sessions.
pub unsafe trait StableOrd: Ord {}
///
/// The associated constant `CAN_USE_UNSTABLE_SORT` denotes whether
/// unstable sorting can be used for this type. Set to true if and
/// only if `a == b` implies `a` and `b` are fully indistinguishable.
pub unsafe trait StableOrd: Ord {
const CAN_USE_UNSTABLE_SORT: bool;
}

unsafe impl<T: StableOrd> StableOrd for &T {
const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
}

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

unsafe impl $crate::stable_hasher::StableOrd for $t {}
unsafe impl $crate::stable_hasher::StableOrd for $t {
const CAN_USE_UNSTABLE_SORT: bool = true;
}
};
}

Expand Down Expand Up @@ -339,6 +351,10 @@ impl<T1: HashStable<CTX>, T2: HashStable<CTX>, CTX> HashStable<CTX> for (T1, T2)
}
}

unsafe impl<T1: StableOrd, T2: StableOrd> StableOrd for (T1, T2) {
const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT;
}

impl<T1, T2, T3, CTX> HashStable<CTX> for (T1, T2, T3)
where
T1: HashStable<CTX>,
Expand All @@ -353,6 +369,11 @@ where
}
}

unsafe impl<T1: StableOrd, T2: StableOrd, T3: StableOrd> StableOrd for (T1, T2, T3) {
const CAN_USE_UNSTABLE_SORT: bool =
T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT && T3::CAN_USE_UNSTABLE_SORT;
}

impl<T1, T2, T3, T4, CTX> HashStable<CTX> for (T1, T2, T3, T4)
where
T1: HashStable<CTX>,
Expand All @@ -369,6 +390,15 @@ where
}
}

unsafe impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd
for (T1, T2, T3, T4)
{
const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT
&& T2::CAN_USE_UNSTABLE_SORT
&& T3::CAN_USE_UNSTABLE_SORT
&& T4::CAN_USE_UNSTABLE_SORT;
}

impl<T: HashStable<CTX>, CTX> HashStable<CTX> for [T] {
default fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.len().hash_stable(ctx, hasher);
Expand Down Expand Up @@ -459,6 +489,10 @@ impl<CTX> HashStable<CTX> for str {
}
}

unsafe impl StableOrd for &str {
const CAN_USE_UNSTABLE_SORT: bool = true;
}

impl<CTX> HashStable<CTX> for String {
#[inline]
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
Expand All @@ -468,7 +502,9 @@ impl<CTX> HashStable<CTX> for String {

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

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

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

impl<T, CTX> HashStable<CTX> for Option<T>
where
Expand All @@ -512,7 +550,9 @@ where
}

// Safety: the Option wrapper does not add instability to comparison.
unsafe impl<T: StableOrd> StableOrd for Option<T> {}
unsafe impl<T: StableOrd> StableOrd for Option<T> {
const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
}

impl<T1, T2, CTX> HashStable<CTX> for Result<T1, T2>
where
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_data_structures/src/unord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,12 @@ impl<T: Ord, I: Iterator<Item = T>> UnordItems<T, I> {
}

#[inline]
pub fn into_sorted_stable_ord(self, use_stable_sort: bool) -> Vec<T>
pub fn into_sorted_stable_ord(self) -> Vec<T>
where
T: Ord + StableOrd,
{
let mut items: Vec<T> = self.0.collect();
if use_stable_sort {
if !T::CAN_USE_UNSTABLE_SORT {
items.sort();
} else {
items.sort_unstable()
Expand All @@ -161,6 +161,10 @@ impl<T: Ord, I: Iterator<Item = T>> UnordItems<T, I> {
items.sort_by_cached_key(|x| x.to_stable_hash_key(hcx));
items
}

pub fn collect<C: From<UnordItems<T, I>>>(self) -> C {
self.into()
}
}

/// This is a set collection type that tries very hard to not expose
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir/src/hir_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ impl ItemLocalId {

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

/// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`.
pub const CRATE_HIR_ID: HirId =
Expand Down
28 changes: 14 additions & 14 deletions compiler/rustc_incremental/src/assert_dep_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

use crate::errors;
use rustc_ast as ast;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::graph::implementation::{Direction, NodeIndex, INCOMING, OUTGOING};
use rustc_graphviz as dot;
use rustc_hir as hir;
Expand Down Expand Up @@ -258,7 +258,7 @@ fn dump_graph(query: &DepGraphQuery) {
}

#[allow(missing_docs)]
pub struct GraphvizDepGraph(FxHashSet<DepKind>, Vec<(DepKind, DepKind)>);
pub struct GraphvizDepGraph(FxIndexSet<DepKind>, Vec<(DepKind, DepKind)>);

impl<'a> dot::GraphWalk<'a> for GraphvizDepGraph {
type Node = DepKind;
Expand Down Expand Up @@ -303,7 +303,7 @@ impl<'a> dot::Labeller<'a> for GraphvizDepGraph {
fn node_set<'q>(
query: &'q DepGraphQuery,
filter: &DepNodeFilter,
) -> Option<FxHashSet<&'q DepNode>> {
) -> Option<FxIndexSet<&'q DepNode>> {
debug!("node_set(filter={:?})", filter);

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

fn filter_nodes<'q>(
query: &'q DepGraphQuery,
sources: &Option<FxHashSet<&'q DepNode>>,
targets: &Option<FxHashSet<&'q DepNode>>,
) -> FxHashSet<DepKind> {
sources: &Option<FxIndexSet<&'q DepNode>>,
targets: &Option<FxIndexSet<&'q DepNode>>,
) -> FxIndexSet<DepKind> {
if let Some(sources) = sources {
if let Some(targets) = targets {
walk_between(query, sources, targets)
Expand All @@ -333,10 +333,10 @@ fn filter_nodes<'q>(

fn walk_nodes<'q>(
query: &'q DepGraphQuery,
starts: &FxHashSet<&'q DepNode>,
starts: &FxIndexSet<&'q DepNode>,
direction: Direction,
) -> FxHashSet<DepKind> {
let mut set = FxHashSet::default();
) -> FxIndexSet<DepKind> {
let mut set = FxIndexSet::default();
for &start in starts {
debug!("walk_nodes: start={:?} outgoing?={:?}", start, direction == OUTGOING);
if set.insert(start.kind) {
Expand All @@ -357,9 +357,9 @@ fn walk_nodes<'q>(

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

fn filter_edges(query: &DepGraphQuery, nodes: &FxHashSet<DepKind>) -> Vec<(DepKind, DepKind)> {
let uniq: FxHashSet<_> = query
fn filter_edges(query: &DepGraphQuery, nodes: &FxIndexSet<DepKind>) -> Vec<(DepKind, DepKind)> {
let uniq: FxIndexSet<_> = query
.edges()
.into_iter()
.map(|(s, t)| (s.kind, t.kind))
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_incremental/src/assert_module_sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

use crate::errors;
use rustc_ast as ast;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::unord::UnordSet;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::mir::mono::CodegenUnitNameBuilder;
use rustc_middle::ty::TyCtxt;
Expand Down Expand Up @@ -52,7 +52,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) {

struct AssertModuleSource<'tcx> {
tcx: TyCtxt<'tcx>,
available_cgus: FxHashSet<Symbol>,
available_cgus: UnordSet<Symbol>,
}

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

if !self.available_cgus.contains(&cgu_name) {
let mut cgu_names: Vec<&str> =
self.available_cgus.iter().map(|cgu| cgu.as_str()).collect();
cgu_names.sort();
let cgu_names: Vec<&str> =
self.available_cgus.items().map(|cgu| cgu.as_str()).into_sorted_stable_ord();
self.tcx.sess.emit_err(errors::NoModuleNamed {
span: attr.span,
user_path,
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_incremental/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(never_type)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]

Expand Down
Loading

0 comments on commit a0df04c

Please sign in to comment.