Refactor call terminator to always hold a destination place

This commit is contained in:
Jakob Degen
2022-04-16 09:27:54 -04:00
parent 222c5724ec
commit 09b0936db2
67 changed files with 422 additions and 412 deletions

View File

@@ -237,14 +237,12 @@ impl Direction for Backward {
// Apply terminator-specific edge effects.
//
// FIXME(ecstaticmorse): Avoid cloning the exit state unconditionally.
mir::TerminatorKind::Call { destination: Some((return_place, dest)), .. }
if dest == bb =>
{
mir::TerminatorKind::Call { destination, target: Some(dest), .. } if dest == bb => {
let mut tmp = exit_state.clone();
analysis.apply_call_return_effect(
&mut tmp,
pred,
CallReturnPlaces::Call(return_place),
CallReturnPlaces::Call(destination),
);
propagate(pred, &tmp);
}
@@ -532,20 +530,28 @@ impl Direction for Forward {
propagate(target, exit_state);
}
Call { cleanup, destination, func: _, args: _, from_hir_call: _, fn_span: _ } => {
Call {
cleanup,
destination,
target,
func: _,
args: _,
from_hir_call: _,
fn_span: _,
} => {
if let Some(unwind) = cleanup {
if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
propagate(unwind, exit_state);
}
}
if let Some((dest_place, target)) = destination {
if let Some(target) = target {
// N.B.: This must be done *last*, otherwise the unwind path will see the call
// return effect.
analysis.apply_call_return_effect(
exit_state,
bb,
CallReturnPlaces::Call(dest_place),
CallReturnPlaces::Call(destination),
);
propagate(target, exit_state);
}

View File

@@ -218,7 +218,7 @@ where
self.results.seek_to_block_end(block);
if self.results.get() != &block_start_state || A::Direction::is_backward() {
let after_terminator_name = match terminator.kind {
mir::TerminatorKind::Call { destination: Some(_), .. } => "(on unwind)",
mir::TerminatorKind::Call { target: Some(_), .. } => "(on unwind)",
_ => "(on end)",
};
@@ -231,14 +231,14 @@ where
// for the basic block itself. That way, we could display terminator-specific effects for
// backward dataflow analyses as well as effects for `SwitchInt` terminators.
match terminator.kind {
mir::TerminatorKind::Call { destination: Some((return_place, _)), .. } => {
mir::TerminatorKind::Call { destination, .. } => {
self.write_row(w, "", "(on successful return)", |this, w, fmt| {
let state_on_unwind = this.results.get().clone();
this.results.apply_custom_effect(|analysis, state| {
analysis.apply_call_return_effect(
state,
block,
CallReturnPlaces::Call(return_place),
CallReturnPlaces::Call(destination),
);
});

View File

@@ -37,7 +37,8 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
mir::TerminatorKind::Call {
func: mir::Operand::Copy(dummy_place.clone()),
args: vec![],
destination: Some((dummy_place.clone(), mir::START_BLOCK)),
destination: dummy_place.clone(),
target: Some(mir::START_BLOCK),
cleanup: None,
from_hir_call: false,
fn_span: DUMMY_SP,
@@ -50,7 +51,8 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
mir::TerminatorKind::Call {
func: mir::Operand::Copy(dummy_place.clone()),
args: vec![],
destination: Some((dummy_place.clone(), mir::START_BLOCK)),
destination: dummy_place.clone(),
target: Some(mir::START_BLOCK),
cleanup: None,
from_hir_call: false,
fn_span: DUMMY_SP,