Skip to content

Commit a06cbbf

Browse files
committed
Properly compute dominance property for calls and yields.
1 parent 387aa6b commit a06cbbf

File tree

1 file changed

+32
-14
lines changed
  • compiler/rustc_mir_transform/src

1 file changed

+32
-14
lines changed

compiler/rustc_mir_transform/src/ssa.rs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,13 @@ impl SmallDominators<'_> {
5050
let assign_dominates = match *set {
5151
Set1::Empty | Set1::Many => false,
5252
Set1::One(LocationExtended::Arg) => true,
53-
Set1::One(LocationExtended::Plain(assign)) => {
53+
Set1::One(LocationExtended::Assign(assign)) => {
5454
self.dominates(assign.successor_within_block(), loc)
5555
}
56+
Set1::One(LocationExtended::Terminator(_, effect_bb)) => {
57+
let effect_loc = Location { block: effect_bb, statement_index: 0 };
58+
self.dominates(effect_loc, loc)
59+
}
5660
};
5761
// We are visiting a use that is not dominated by an assignment.
5862
// Either there is a cycle involved, or we are reading for uninitialized local.
@@ -73,7 +77,8 @@ impl SsaLocals {
7377
let dominators = SmallDominators { inner: dominators };
7478

7579
let direct_uses = IndexVec::from_elem(0, &body.local_decls);
76-
let mut visitor = SsaVisitor { assignments, assignment_order, dominators, direct_uses };
80+
let mut visitor =
81+
SsaVisitor { body, assignments, assignment_order, dominators, direct_uses };
7782

7883
for local in body.args_iter() {
7984
visitor.assignments[local] = Set1::One(LocationExtended::Arg);
@@ -134,12 +139,9 @@ impl SsaLocals {
134139
body: &'a Body<'tcx>,
135140
) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>, Location)> + 'a {
136141
self.assignment_order.iter().filter_map(|&local| {
137-
if let Set1::One(LocationExtended::Plain(loc)) = self.assignments[local]
138-
// `loc` must point to:
139-
// - a direct assignment to `local`;
140-
// - a call or a yield terminator.
141-
&& let Either::Left(stmt) = body.stmt_at(loc)
142-
{
142+
if let Set1::One(LocationExtended::Assign(loc)) = self.assignments[local] {
143+
// `loc` must point to a direct assignment to `local`.
144+
let Either::Left(stmt) = body.stmt_at(loc) else { bug!() };
143145
let Some((target, rvalue)) = stmt.kind.as_assign() else { bug!() };
144146
assert_eq!(target.as_local(), Some(local));
145147
Some((local, rvalue, loc))
@@ -197,18 +199,24 @@ impl SsaLocals {
197199

198200
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
199201
enum LocationExtended {
200-
Plain(Location),
202+
/// This local was assigned as a function parameter, before any execution.
201203
Arg,
204+
/// `Location` points to the `Assign` statement.
205+
Assign(Location),
206+
/// The blocks are respectively the bb which contains the assignment,
207+
/// and the bb in which the assignment effect is complete.
208+
Terminator(BasicBlock, BasicBlock),
202209
}
203210

204-
struct SsaVisitor<'a> {
211+
struct SsaVisitor<'a, 'tcx> {
212+
body: &'a Body<'tcx>,
205213
dominators: SmallDominators<'a>,
206214
assignments: IndexVec<Local, Set1<LocationExtended>>,
207215
assignment_order: Vec<Local>,
208216
direct_uses: IndexVec<Local, u32>,
209217
}
210218

211-
impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
219+
impl<'tcx> Visitor<'tcx> for SsaVisitor<'_, 'tcx> {
212220
fn visit_local(&mut self, local: Local, ctxt: PlaceContext, loc: Location) {
213221
match ctxt {
214222
PlaceContext::MutatingUse(MutatingUseContext::Projection)
@@ -233,10 +241,20 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
233241
}
234242

235243
fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, loc: Location) {
236-
if let PlaceContext::MutatingUse(MutatingUseContext::Store | MutatingUseContext::Call | MutatingUseContext::Yield) = ctxt
244+
let location = match ctxt {
245+
PlaceContext::MutatingUse(MutatingUseContext::Store) => {
246+
Some(LocationExtended::Assign(loc))
247+
}
248+
PlaceContext::MutatingUse(MutatingUseContext::Call | MutatingUseContext::Yield) => {
249+
let target = self.body.basic_blocks[loc.block].terminator().successors().next();
250+
target.map(|target| LocationExtended::Terminator(loc.block, target))
251+
}
252+
_ => None,
253+
};
254+
if let Some(location) = location
237255
&& let Some(local) = place.as_local()
238256
{
239-
self.assignments[local].insert(LocationExtended::Plain(loc));
257+
self.assignments[local].insert(location);
240258
if let Set1::One(_) = self.assignments[local] {
241259
// Only record if SSA-like, to avoid growing the vector needlessly.
242260
self.assignment_order.push(local);
@@ -337,7 +355,7 @@ impl StorageLiveLocals {
337355
for (statement_index, statement) in bbdata.statements.iter().enumerate() {
338356
if let StatementKind::StorageLive(local) = statement.kind {
339357
storage_live[local]
340-
.insert(LocationExtended::Plain(Location { block, statement_index }));
358+
.insert(LocationExtended::Assign(Location { block, statement_index }));
341359
}
342360
}
343361
}

0 commit comments

Comments
 (0)