Refactor call terminator to always hold a destination place
This commit is contained in:
parent
222c5724ec
commit
09b0936db2
67 changed files with 422 additions and 412 deletions
|
@ -625,7 +625,8 @@ where
|
|||
kind: TerminatorKind::Call {
|
||||
func: Operand::function_handle(tcx, drop_fn, substs, self.source_info.span),
|
||||
args: vec![Operand::Move(Place::from(ref_place))],
|
||||
destination: Some((unit_temp, succ)),
|
||||
destination: unit_temp,
|
||||
target: Some(succ),
|
||||
cleanup: unwind.into_option(),
|
||||
from_hir_call: true,
|
||||
fn_span: self.source_info.span,
|
||||
|
@ -963,7 +964,8 @@ where
|
|||
let call = TerminatorKind::Call {
|
||||
func: Operand::function_handle(tcx, free_func, substs, self.source_info.span),
|
||||
args,
|
||||
destination: Some((unit_temp, target)),
|
||||
destination: unit_temp,
|
||||
target: Some(target),
|
||||
cleanup: None,
|
||||
from_hir_call: false,
|
||||
fn_span: self.source_info.span,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -169,8 +169,8 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc
|
|||
self.borrowed_locals.borrow().analysis().terminator_effect(trans, terminator, loc);
|
||||
|
||||
match &terminator.kind {
|
||||
TerminatorKind::Call { destination: Some((place, _)), .. } => {
|
||||
trans.gen(place.local);
|
||||
TerminatorKind::Call { destination, .. } => {
|
||||
trans.gen(destination.local);
|
||||
}
|
||||
|
||||
// Note that we do *not* gen the `resume_arg` of `Yield` terminators. The reason for
|
||||
|
@ -198,8 +198,7 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc
|
|||
|
||||
// Nothing to do for these. Match exhaustively so this fails to compile when new
|
||||
// variants are added.
|
||||
TerminatorKind::Call { destination: None, .. }
|
||||
| TerminatorKind::Abort
|
||||
TerminatorKind::Abort
|
||||
| TerminatorKind::Assert { .. }
|
||||
| TerminatorKind::Drop { .. }
|
||||
| TerminatorKind::DropAndReplace { .. }
|
||||
|
@ -225,8 +224,8 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc
|
|||
// and after the call returns successfully, but not after a panic.
|
||||
// Since `propagate_call_unwind` doesn't exist, we have to kill the
|
||||
// destination here, and then gen it again in `call_return_effect`.
|
||||
TerminatorKind::Call { destination: Some((place, _)), .. } => {
|
||||
trans.kill(place.local);
|
||||
TerminatorKind::Call { destination, .. } => {
|
||||
trans.kill(destination.local);
|
||||
}
|
||||
|
||||
// The same applies to InlineAsm outputs.
|
||||
|
@ -236,8 +235,7 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc
|
|||
|
||||
// Nothing to do for these. Match exhaustively so this fails to compile when new
|
||||
// variants are added.
|
||||
TerminatorKind::Call { destination: None, .. }
|
||||
| TerminatorKind::Yield { .. }
|
||||
TerminatorKind::Yield { .. }
|
||||
| TerminatorKind::Abort
|
||||
| TerminatorKind::Assert { .. }
|
||||
| TerminatorKind::Drop { .. }
|
||||
|
|
|
@ -376,7 +376,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
TerminatorKind::Call {
|
||||
ref func,
|
||||
ref args,
|
||||
ref destination,
|
||||
destination,
|
||||
target,
|
||||
cleanup: _,
|
||||
from_hir_call: _,
|
||||
fn_span: _,
|
||||
|
@ -385,7 +386,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
for arg in args {
|
||||
self.gather_operand(arg);
|
||||
}
|
||||
if let Some((destination, _bb)) = *destination {
|
||||
if let Some(_bb) = target {
|
||||
self.create_move_path(destination);
|
||||
self.gather_init(destination.as_ref(), InitKind::NonPanicPathOnly);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue