Skip to content

Commit e521268

Browse files
committed
Separate SSA from non-SSA in rev_locals.
1 parent 27b5c0a commit e521268

File tree

1 file changed

+30
-17
lines changed
  • compiler/rustc_mir_transform/src

1 file changed

+30
-17
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ use rustc_const_eval::interpret::{
9494
ImmTy, Immediate, InterpCx, MemPlaceMeta, MemoryKind, OpTy, Projectable, Scalar,
9595
intern_const_alloc_for_constprop,
9696
};
97-
use rustc_data_structures::fx::{FxIndexSet, MutableValues};
97+
use rustc_data_structures::fx::{FxHashMap, FxIndexSet, MutableValues};
9898
use rustc_data_structures::graph::dominators::Dominators;
9999
use rustc_hir::def::DefKind;
100100
use rustc_index::bit_set::DenseBitSet;
@@ -229,8 +229,10 @@ struct VnState<'body, 'a, 'tcx> {
229229
/// Value stored in each local.
230230
locals: IndexVec<Local, VnIndex>,
231231
/// Locals that are assigned that value.
232-
// This vector does not hold all the values of `VnIndex` that we create.
233-
rev_locals: IndexVec<VnIndex, SmallVec<[(Local, Location); 1]>>,
232+
// This vector holds the locals that are SSA.
233+
rev_locals_ssa: IndexVec<VnIndex, SmallVec<[(Local, Location); 1]>>,
234+
// This vector holds the locals that are not SSA.
235+
rev_locals_non_ssa: FxHashMap<VnIndex, SmallVec<[(Local, Location); 1]>>,
234236
values: FxIndexSet<(Value<'a, 'tcx>, Ty<'tcx>)>,
235237
/// Values evaluated as constants if possible.
236238
evaluated: IndexVec<VnIndex, Option<OpTy<'tcx>>>,
@@ -267,7 +269,8 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
267269
local_decls,
268270
is_coroutine: body.coroutine.is_some(),
269271
locals: IndexVec::with_capacity(body.local_decls.len()),
270-
rev_locals: IndexVec::with_capacity(num_values),
272+
rev_locals_ssa: IndexVec::with_capacity(num_values),
273+
rev_locals_non_ssa: FxHashMap::default(),
271274
values: FxIndexSet::with_capacity_and_hasher(num_values, Default::default()),
272275
evaluated: IndexVec::with_capacity(num_values),
273276
next_opaque: 1,
@@ -281,7 +284,11 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
281284
for decl in body.local_decls.iter() {
282285
let value = this.new_opaque(decl.ty);
283286
let local = this.locals.push(value);
284-
this.rev_locals[value].push((local, init_loc));
287+
if ssa.is_ssa(local) {
288+
this.rev_locals_ssa[value].push((local, init_loc));
289+
} else {
290+
this.rev_locals_non_ssa.entry(value).or_default().push((local, init_loc));
291+
}
285292
}
286293
this
287294
}
@@ -299,7 +306,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
299306
let evaluated = self.eval_to_const(index);
300307
let _index = self.evaluated.push(evaluated);
301308
debug_assert_eq!(index, _index);
302-
let _index = self.rev_locals.push(SmallVec::new());
309+
let _index = self.rev_locals_ssa.push(Default::default());
303310
debug_assert_eq!(index, _index);
304311
}
305312
index
@@ -370,7 +377,11 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
370377
#[instrument(level = "trace", skip(self))]
371378
fn assign(&mut self, local: Local, value: VnIndex, loc: Location) {
372379
self.locals[local] = value;
373-
self.rev_locals[value].push((local, loc));
380+
if self.ssa.is_ssa(local) {
381+
self.rev_locals_ssa[value].push((local, loc));
382+
} else {
383+
self.rev_locals_non_ssa.entry(value).or_default().push((local, loc));
384+
}
374385
}
375386

376387
#[instrument(level = "trace", skip(self))]
@@ -380,11 +391,11 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
380391
return;
381392
}
382393
let value = this.locals[local];
383-
this.rev_locals[value].retain(|(l, _)| *l != local);
394+
this.rev_locals_non_ssa.entry(value).or_default().retain(|(l, _)| *l != local);
384395
this.locals[local] = this.new_opaque(this.ty(value));
385396
#[cfg(debug_assertions)]
386-
for local_vec in this.rev_locals.iter() {
387-
for (other, _) in local_vec {
397+
for local_vec in this.rev_locals_non_ssa.iter() {
398+
for (other, _) in local_vec.non_ssa {
388399
debug_assert_ne!(*other, local);
389400
}
390401
}
@@ -1769,9 +1780,10 @@ impl<'tcx> VnState<'_, '_, 'tcx> {
17691780
/// return it. If you used this local, add it to `reused_locals` to remove storage statements.
17701781
#[instrument(level = "trace", skip(self), ret)]
17711782
fn try_as_local(&mut self, index: VnIndex, loc: Location) -> Option<Local> {
1772-
let other = self.rev_locals.get(index)?;
1773-
other
1774-
.iter()
1783+
let ssa = self.rev_locals_ssa.get(index)?;
1784+
let non_ssa = self.rev_locals_non_ssa.entry(index).or_default();
1785+
ssa.iter()
1786+
.chain(non_ssa.iter())
17751787
.find(|&&(other, assign_loc)| {
17761788
self.ssa.assignment_dominates(&self.dominators, other, loc)
17771789
|| (assign_loc.block == loc.block
@@ -1787,15 +1799,16 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, '_, 'tcx> {
17871799
}
17881800

17891801
fn visit_basic_block_data(&mut self, block: BasicBlock, bbdata: &mut BasicBlockData<'tcx>) {
1790-
for local_set in self.rev_locals.iter_mut() {
1791-
local_set.retain(|(local, _)| self.ssa.is_ssa(*local));
1792-
}
1802+
self.rev_locals_non_ssa.clear();
17931803
for local in self.locals.indices() {
17941804
if !self.ssa.is_ssa(local) {
17951805
let current = self.locals[local];
17961806
let new = self.new_opaque(self.ty(current));
17971807
self.locals[local] = new;
1798-
self.rev_locals[new].push((local, Location { block, statement_index: 0 }));
1808+
self.rev_locals_non_ssa
1809+
.entry(new)
1810+
.or_default()
1811+
.push((local, Location { block, statement_index: 0 }));
17991812
}
18001813
}
18011814
self.super_basic_block_data(block, bbdata);

0 commit comments

Comments
 (0)