Skip to content

Commit e972d15

Browse files
Auto merge of #144576 - ywxt:parallel-reproducibility, r=<try>
Fix parallel rustc not being reproducible due to unstable sorts of items
2 parents 5529041 + f7fba9a commit e972d15

21 files changed

+1615
-1589
lines changed

compiler/rustc_middle/src/mir/mono.rs

Lines changed: 70 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
use std::borrow::Cow;
2+
use std::cmp::Ordering;
23
use std::fmt;
34
use std::hash::Hash;
45

56
use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
67
use rustc_attr_data_structures::InlineAttr;
78
use rustc_data_structures::base_n::{BaseNString, CASE_INSENSITIVE, ToBaseN};
89
use rustc_data_structures::fingerprint::Fingerprint;
9-
use rustc_data_structures::fx::FxIndexMap;
10+
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
1011
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
1112
use rustc_data_structures::unord::UnordMap;
1213
use rustc_hashes::Hash128;
1314
use rustc_hir::ItemId;
1415
use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, LOCAL_CRATE};
15-
use rustc_index::Idx;
1616
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
1717
use rustc_query_system::ich::StableHashingContext;
1818
use rustc_session::config::OptLevel;
@@ -526,45 +526,78 @@ impl<'tcx> CodegenUnit<'tcx> {
526526
tcx: TyCtxt<'tcx>,
527527
) -> Vec<(MonoItem<'tcx>, MonoItemData)> {
528528
// The codegen tests rely on items being process in the same order as
529-
// they appear in the file, so for local items, we sort by node_id first
530-
#[derive(PartialEq, Eq, PartialOrd, Ord)]
531-
struct ItemSortKey<'tcx>(Option<usize>, SymbolName<'tcx>);
532-
533-
fn item_sort_key<'tcx>(tcx: TyCtxt<'tcx>, item: MonoItem<'tcx>) -> ItemSortKey<'tcx> {
534-
ItemSortKey(
535-
match item {
536-
MonoItem::Fn(ref instance) => {
537-
match instance.def {
538-
// We only want to take HirIds of user-defined
539-
// instances into account. The others don't matter for
540-
// the codegen tests and can even make item order
541-
// unstable.
542-
InstanceKind::Item(def) => def.as_local().map(Idx::index),
543-
InstanceKind::VTableShim(..)
544-
| InstanceKind::ReifyShim(..)
545-
| InstanceKind::Intrinsic(..)
546-
| InstanceKind::FnPtrShim(..)
547-
| InstanceKind::Virtual(..)
548-
| InstanceKind::ClosureOnceShim { .. }
549-
| InstanceKind::ConstructCoroutineInClosureShim { .. }
550-
| InstanceKind::DropGlue(..)
551-
| InstanceKind::CloneShim(..)
552-
| InstanceKind::ThreadLocalShim(..)
553-
| InstanceKind::FnPtrAddrShim(..)
554-
| InstanceKind::AsyncDropGlue(..)
555-
| InstanceKind::FutureDropPollShim(..)
556-
| InstanceKind::AsyncDropGlueCtorShim(..) => None,
557-
}
529+
// they appear in the file, so for local items, we sort by span and def_path first
530+
struct ItemSortKey<'tcx>(Option<Span>, Option<String>, Option<SymbolName<'tcx>>);
531+
532+
// Avoids def_path querying for items that have different spans
533+
fn item_sort<'tcx>(
534+
tcx: TyCtxt<'tcx>,
535+
cached_keys_map: &'_ mut FxHashMap<MonoItem<'tcx>, ItemSortKey<'tcx>>,
536+
item1: MonoItem<'tcx>,
537+
item2: MonoItem<'tcx>,
538+
) -> Ordering {
539+
let is_local1 = item1.def_id().is_local();
540+
let is_local2 = item2.def_id().is_local();
541+
542+
match (is_local1, is_local2) {
543+
(false, false) => {
544+
cached_keys_map
545+
.entry(item1)
546+
.or_insert_with(|| ItemSortKey(None, None, Some(item1.symbol_name(tcx))));
547+
cached_keys_map
548+
.entry(item2)
549+
.or_insert_with(|| ItemSortKey(None, None, Some(item2.symbol_name(tcx))));
550+
let ItemSortKey(_, _, name1) = &cached_keys_map[&item1];
551+
let ItemSortKey(_, _, name2) = &cached_keys_map[&item2];
552+
name1.cmp(name2)
553+
}
554+
(false, true) => Ordering::Less,
555+
(true, false) => Ordering::Greater,
556+
(true, true) => {
557+
cached_keys_map
558+
.entry(item1)
559+
.or_insert_with(|| ItemSortKey(item1.local_span(tcx), None, None));
560+
cached_keys_map
561+
.entry(item2)
562+
.or_insert_with(|| ItemSortKey(item2.local_span(tcx), None, None));
563+
let ItemSortKey(span1, _, _) = &cached_keys_map[&item1];
564+
let ItemSortKey(span2, _, _) = &cached_keys_map[&item2];
565+
let ord = span1.cmp(span2);
566+
if ord != Ordering::Equal {
567+
return ord;
558568
}
559-
MonoItem::Static(def_id) => def_id.as_local().map(Idx::index),
560-
MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.def_id.index()),
561-
},
562-
item.symbol_name(tcx),
563-
)
569+
570+
cached_keys_map.entry(item1).and_modify(
571+
|ItemSortKey(_, def_path, symbol_name)| {
572+
def_path.get_or_insert_with(|| {
573+
tcx.def_path(item1.def_id()).to_string_no_crate_verbose()
574+
});
575+
symbol_name.get_or_insert_with(|| item1.symbol_name(tcx));
576+
},
577+
);
578+
cached_keys_map.entry(item2).and_modify(
579+
|ItemSortKey(_, def_path, symbol_name)| {
580+
def_path.get_or_insert_with(|| {
581+
tcx.def_path(item2.def_id()).to_string_no_crate_verbose()
582+
});
583+
symbol_name.get_or_insert_with(|| item2.symbol_name(tcx));
584+
},
585+
);
586+
let ItemSortKey(_, def_path1, name1) = &cached_keys_map[&item1];
587+
let ItemSortKey(_, def_path2, name2) = &cached_keys_map[&item2];
588+
match def_path1.cmp(def_path2) {
589+
Ordering::Equal => name1.cmp(name2),
590+
other => other,
591+
}
592+
}
593+
}
564594
}
565595

566596
let mut items: Vec<_> = self.items().iter().map(|(&i, &data)| (i, data)).collect();
567-
items.sort_by_cached_key(|&(i, _)| item_sort_key(tcx, i));
597+
let mut cached_keys_map =
598+
FxHashMap::with_capacity_and_hasher(items.len(), Default::default());
599+
items
600+
.sort_by(|&(item1, _), &(item2, _)| item_sort(tcx, &mut cached_keys_map, item1, item2));
568601
items
569602
}
570603

tests/assembly-llvm/asm/aarch64-modifiers.rs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -55,35 +55,17 @@ check!(vreg vreg "add {0}.4s, {0}.4s, {0}.4s");
5555
// CHECK: //NO_APP
5656
check!(vreg_b vreg "ldr {:b}, [x0]");
5757

58-
// CHECK-LABEL: vreg_h:
59-
// CHECK: //APP
60-
// CHECK: ldr h0, [x0]
61-
// CHECK: //NO_APP
62-
check!(vreg_h vreg "ldr {:h}, [x0]");
63-
64-
// CHECK-LABEL: vreg_s:
65-
// CHECK: //APP
66-
// CHECK: ldr s0, [x0]
67-
// CHECK: //NO_APP
68-
check!(vreg_s vreg "ldr {:s}, [x0]");
69-
7058
// CHECK-LABEL: vreg_d:
7159
// CHECK: //APP
7260
// CHECK: ldr d0, [x0]
7361
// CHECK: //NO_APP
7462
check!(vreg_d vreg "ldr {:d}, [x0]");
7563

76-
// CHECK-LABEL: vreg_q:
77-
// CHECK: //APP
78-
// CHECK: ldr q0, [x0]
79-
// CHECK: //NO_APP
80-
check!(vreg_q vreg "ldr {:q}, [x0]");
81-
82-
// CHECK-LABEL: vreg_v:
64+
// CHECK-LABEL: vreg_h:
8365
// CHECK: //APP
84-
// CHECK: add v0.4s, v0.4s, v0.4s
66+
// CHECK: ldr h0, [x0]
8567
// CHECK: //NO_APP
86-
check!(vreg_v vreg "add {0:v}.4s, {0:v}.4s, {0:v}.4s");
68+
check!(vreg_h vreg "ldr {:h}, [x0]");
8769

8870
// CHECK-LABEL: vreg_low16:
8971
// CHECK: //APP
@@ -97,32 +79,50 @@ check!(vreg_low16 vreg_low16 "add {0}.4s, {0}.4s, {0}.4s");
9779
// CHECK: //NO_APP
9880
check!(vreg_low16_b vreg_low16 "ldr {:b}, [x0]");
9981

82+
// CHECK-LABEL: vreg_low16_d:
83+
// CHECK: //APP
84+
// CHECK: ldr d0, [x0]
85+
// CHECK: //NO_APP
86+
check!(vreg_low16_d vreg_low16 "ldr {:d}, [x0]");
87+
10088
// CHECK-LABEL: vreg_low16_h:
10189
// CHECK: //APP
10290
// CHECK: ldr h0, [x0]
10391
// CHECK: //NO_APP
10492
check!(vreg_low16_h vreg_low16 "ldr {:h}, [x0]");
10593

94+
// CHECK-LABEL: vreg_low16_q:
95+
// CHECK: //APP
96+
// CHECK: ldr q0, [x0]
97+
// CHECK: //NO_APP
98+
check!(vreg_low16_q vreg_low16 "ldr {:q}, [x0]");
99+
106100
// CHECK-LABEL: vreg_low16_s:
107101
// CHECK: //APP
108102
// CHECK: ldr s0, [x0]
109103
// CHECK: //NO_APP
110104
check!(vreg_low16_s vreg_low16 "ldr {:s}, [x0]");
111105

112-
// CHECK-LABEL: vreg_low16_d:
106+
// CHECK-LABEL: vreg_low16_v:
113107
// CHECK: //APP
114-
// CHECK: ldr d0, [x0]
108+
// CHECK: add v0.4s, v0.4s, v0.4s
115109
// CHECK: //NO_APP
116-
check!(vreg_low16_d vreg_low16 "ldr {:d}, [x0]");
110+
check!(vreg_low16_v vreg_low16 "add {0:v}.4s, {0:v}.4s, {0:v}.4s");
117111

118-
// CHECK-LABEL: vreg_low16_q:
112+
// CHECK-LABEL: vreg_q:
119113
// CHECK: //APP
120114
// CHECK: ldr q0, [x0]
121115
// CHECK: //NO_APP
122-
check!(vreg_low16_q vreg_low16 "ldr {:q}, [x0]");
116+
check!(vreg_q vreg "ldr {:q}, [x0]");
123117

124-
// CHECK-LABEL: vreg_low16_v:
118+
// CHECK-LABEL: vreg_s:
119+
// CHECK: //APP
120+
// CHECK: ldr s0, [x0]
121+
// CHECK: //NO_APP
122+
check!(vreg_s vreg "ldr {:s}, [x0]");
123+
124+
// CHECK-LABEL: vreg_v:
125125
// CHECK: //APP
126126
// CHECK: add v0.4s, v0.4s, v0.4s
127127
// CHECK: //NO_APP
128-
check!(vreg_low16_v vreg_low16 "add {0:v}.4s, {0:v}.4s, {0:v}.4s");
128+
check!(vreg_v vreg "add {0:v}.4s, {0:v}.4s, {0:v}.4s");

0 commit comments

Comments
 (0)