Skip to content

Commit aa12f6a

Browse files
committed
Separate SSA vs non-SSA locals map.
1 parent 99438d1 commit aa12f6a

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,9 @@ struct VnState<'body, 'a, 'tcx> {
364364
local_decls: &'body LocalDecls<'tcx>,
365365
is_coroutine: bool,
366366
/// Value stored in each local.
367-
locals: IndexVec<Local, Option<VnIndex>>,
367+
locals_ssa: FxHashMap<Local, VnIndex>,
368+
// Keep two separate maps to efficiently clear non-SSA locals.
369+
locals_non_ssa: FxHashMap<Local, VnIndex>,
368370
/// Locals that are assigned that value.
369371
// This vector holds the locals that are SSA.
370372
rev_locals_ssa: IndexVec<VnIndex, SmallVec<[Local; 1]>>,
@@ -404,7 +406,11 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
404406
ecx: InterpCx::new(tcx, DUMMY_SP, typing_env, DummyMachine),
405407
local_decls,
406408
is_coroutine: body.coroutine.is_some(),
407-
locals: IndexVec::from_elem(None, local_decls),
409+
locals_ssa: FxHashMap::with_capacity_and_hasher(local_decls.len(), Default::default()),
410+
locals_non_ssa: FxHashMap::with_capacity_and_hasher(
411+
local_decls.len(),
412+
Default::default(),
413+
),
408414
rev_locals_ssa: IndexVec::with_capacity(num_values),
409415
rev_locals_non_ssa: FxHashMap::default(),
410416
values: ValueSet::new(num_values),
@@ -527,22 +533,28 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
527533
/// Record that `local` is assigned `value`.
528534
#[instrument(level = "trace", skip(self))]
529535
fn assign(&mut self, local: Local, value: VnIndex) {
530-
self.locals[local] = Some(value);
531536
if self.ssa.is_ssa(local) {
537+
self.locals_ssa.insert(local, value);
532538
self.rev_locals_ssa[value].push(local);
533539
} else {
540+
self.locals_non_ssa.insert(local, value);
534541
self.rev_locals_non_ssa.entry(value).or_default().push(local);
535542
}
536543
}
537544

538545
/// Return the value assigned to a local, or assign an opaque value and return it.
539546
#[instrument(level = "trace", skip(self), ret)]
540547
fn local(&mut self, local: Local) -> VnIndex {
541-
if let Some(value) = self.locals[local] {
542-
return value;
548+
if let Some(value) = self.locals_ssa.get(&local) {
549+
return *value;
550+
}
551+
if let Some(value) = self.locals_non_ssa.get(&local) {
552+
return *value;
543553
}
544554
let value = self.new_opaque(self.local_decls[local].ty);
545-
self.locals[local] = Some(value);
555+
// For SSA locals, the assignment dominates all uses.
556+
// If we are here, this means the locals is not SSA.
557+
self.locals_non_ssa.insert(local, value);
546558
self.rev_locals_non_ssa.entry(value).or_default().push(local);
547559
value
548560
}
@@ -553,7 +565,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
553565
if this.ssa.is_ssa(local) {
554566
return;
555567
}
556-
if let Some(value) = this.locals[local].take() {
568+
if let Some(value) = this.locals_non_ssa.remove(&local) {
557569
this.rev_locals_non_ssa.entry(value).or_default().retain(|l| *l != local);
558570
}
559571
};
@@ -1879,12 +1891,8 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, '_, 'tcx> {
18791891
}
18801892

18811893
fn visit_basic_block_data(&mut self, block: BasicBlock, bbdata: &mut BasicBlockData<'tcx>) {
1894+
self.locals_non_ssa.clear();
18821895
self.rev_locals_non_ssa.clear();
1883-
for local in self.locals.indices() {
1884-
if !self.ssa.is_ssa(local) {
1885-
self.locals[local] = None;
1886-
}
1887-
}
18881896
self.super_basic_block_data(block, bbdata);
18891897
}
18901898

compiler/rustc_mir_transform/src/ssa.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,19 +99,23 @@ impl SsaLocals {
9999
ssa
100100
}
101101

102+
#[inline]
102103
pub(super) fn num_locals(&self) -> usize {
103104
self.assignments.len()
104105
}
105106

107+
#[inline]
106108
pub(super) fn locals(&self) -> impl Iterator<Item = Local> {
107109
self.assignments.indices()
108110
}
109111

112+
#[inline]
110113
pub(super) fn is_ssa(&self, local: Local) -> bool {
111114
matches!(self.assignments[local], Set1::One(_))
112115
}
113116

114117
/// Return the number of uses if a local that are not "Deref".
118+
#[inline]
115119
pub(super) fn num_direct_uses(&self, local: Local) -> u32 {
116120
self.direct_uses[local]
117121
}

0 commit comments

Comments
 (0)