Skip to content

Commit 7d19a6d

Browse files
committed
Elaborate comment.
1 parent aee7d70 commit 7d19a6d

File tree

1 file changed

+23
-27
lines changed

1 file changed

+23
-27
lines changed

compiler/rustc_mir_transform/src/dest_prop.rs

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,21 @@ fn save_as_intervals<'tcx>(
547547
}
548548
}
549549
};
550+
let second_half_visitor = |mark_reads| {
551+
VisitPlacesWith(|place: Place<'tcx>, ctxt| {
552+
if let Some(relevant) = relevant.shrink[place.local] {
553+
match DefUse::for_place(place, ctxt) {
554+
DefUse::Def | DefUse::PartialWrite => {
555+
values.insert(relevant, twostep);
556+
}
557+
DefUse::Use if mark_reads => {
558+
values.insert(relevant, twostep);
559+
}
560+
DefUse::NonUse => {}
561+
}
562+
}
563+
})
564+
};
550565

551566
// Iterate blocks in decreasing order, to visit locations in decreasing order. This
552567
// allows to use the more efficient `append` method to interval sets.
@@ -567,17 +582,7 @@ fn save_as_intervals<'tcx>(
567582
// the written-to locals as live in the second half of the statement.
568583
// We also ensure that operands read by terminators conflict with writes by that terminator.
569584
// For instance a function call may read args after having written to the destination.
570-
VisitPlacesWith(|place: Place<'tcx>, ctxt| {
571-
if let Some(relevant) = relevant.shrink[place.local] {
572-
match DefUse::for_place(place, ctxt) {
573-
DefUse::Def | DefUse::Use | DefUse::PartialWrite => {
574-
values.insert(relevant, twostep);
575-
}
576-
DefUse::NonUse => {}
577-
}
578-
}
579-
})
580-
.visit_terminator(term, loc);
585+
second_half_visitor(/* mark reads */ true).visit_terminator(term, loc);
581586

582587
twostep = TwoStepIndex::from_u32(twostep.as_u32() + 1);
583588
debug_assert_eq!(twostep, two_step_loc(loc, Effect::Before));
@@ -590,24 +595,15 @@ fn save_as_intervals<'tcx>(
590595
twostep = TwoStepIndex::from_u32(twostep.as_u32() + 1);
591596
debug_assert_eq!(twostep, two_step_loc(loc, Effect::After));
592597
append_at(&mut values, &state, twostep);
593-
// Ensure we have a non-zero live range even for dead stores. This is done by marking
594-
// all the written-to locals as live in the second half of the statement.
598+
// Like terminators, ensure we have a non-zero live range even for dead stores.
599+
// Some rvalues interleave reads and writes, for instance `Rvalue::Aggregate`, see
600+
// https://github.com/rust-lang/rust/issues/146383. By precaution, treat statements
601+
// as behaving so by default.
602+
// We make an exception for simple assignments `_a.stuff = {copy|move} _b.stuff`,
603+
// as marking `_b` live here would prevent unification.
595604
let is_simple_assignment =
596605
matches!(stmt.kind, StatementKind::Assign(box (_, Rvalue::Use(_))));
597-
VisitPlacesWith(|place: Place<'tcx>, ctxt| {
598-
if let Some(relevant) = relevant.shrink[place.local] {
599-
match DefUse::for_place(place, ctxt) {
600-
DefUse::Def | DefUse::PartialWrite => {
601-
values.insert(relevant, twostep);
602-
}
603-
DefUse::Use if !is_simple_assignment => {
604-
values.insert(relevant, twostep);
605-
}
606-
DefUse::Use | DefUse::NonUse => {}
607-
}
608-
}
609-
})
610-
.visit_statement(stmt, loc);
606+
second_half_visitor(/* mark reads */ is_simple_assignment).visit_statement(stmt, loc);
611607

612608
twostep = TwoStepIndex::from_u32(twostep.as_u32() + 1);
613609
debug_assert_eq!(twostep, two_step_loc(loc, Effect::Before));

0 commit comments

Comments
 (0)