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

@@ -250,8 +250,10 @@ pub enum TerminatorKind<'tcx> {
/// This allows the memory occupied by "by-value" arguments to be
/// reused across function calls without duplicating the contents.
args: Vec<Operand<'tcx>>,
/// Destination for the return value. If none, the call necessarily diverges.
destination: Option<(Place<'tcx>, BasicBlock)>,
/// Where the returned value will be written
destination: Place<'tcx>,
/// Where to go after this call returns. If none, the call necessarily diverges.
target: Option<BasicBlock>,
/// Cleanups to be done if the call unwinds.
cleanup: Option<BasicBlock>,
/// `true` if this is from a call in HIR rather than from an overloaded
@@ -415,13 +417,13 @@ impl<'tcx> TerminatorKind<'tcx> {
| GeneratorDrop
| Return
| Unreachable
| Call { destination: None, cleanup: None, .. }
| Call { target: None, cleanup: None, .. }
| InlineAsm { destination: None, cleanup: None, .. } => {
None.into_iter().chain((&[]).into_iter().copied())
}
Goto { target: t }
| Call { destination: None, cleanup: Some(t), .. }
| Call { destination: Some((_, t)), cleanup: None, .. }
| Call { target: None, cleanup: Some(t), .. }
| Call { target: Some(t), cleanup: None, .. }
| Yield { resume: t, drop: None, .. }
| DropAndReplace { target: t, unwind: None, .. }
| Drop { target: t, unwind: None, .. }
@@ -431,7 +433,7 @@ impl<'tcx> TerminatorKind<'tcx> {
| InlineAsm { destination: None, cleanup: Some(t), .. } => {
Some(t).into_iter().chain((&[]).into_iter().copied())
}
Call { destination: Some((_, t)), cleanup: Some(ref u), .. }
Call { target: Some(t), cleanup: Some(ref u), .. }
| Yield { resume: t, drop: Some(ref u), .. }
| DropAndReplace { target: t, unwind: Some(ref u), .. }
| Drop { target: t, unwind: Some(ref u), .. }
@@ -457,11 +459,11 @@ impl<'tcx> TerminatorKind<'tcx> {
| GeneratorDrop
| Return
| Unreachable
| Call { destination: None, cleanup: None, .. }
| Call { target: None, cleanup: None, .. }
| InlineAsm { destination: None, cleanup: None, .. } => None.into_iter().chain(&mut []),
Goto { target: ref mut t }
| Call { destination: None, cleanup: Some(ref mut t), .. }
| Call { destination: Some((_, ref mut t)), cleanup: None, .. }
| Call { target: None, cleanup: Some(ref mut t), .. }
| Call { target: Some(ref mut t), cleanup: None, .. }
| Yield { resume: ref mut t, drop: None, .. }
| DropAndReplace { target: ref mut t, unwind: None, .. }
| Drop { target: ref mut t, unwind: None, .. }
@@ -471,7 +473,7 @@ impl<'tcx> TerminatorKind<'tcx> {
| InlineAsm { destination: None, cleanup: Some(ref mut t), .. } => {
Some(t).into_iter().chain(&mut [])
}
Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut u), .. }
Call { target: Some(ref mut t), cleanup: Some(ref mut u), .. }
| Yield { resume: ref mut t, drop: Some(ref mut u), .. }
| DropAndReplace { target: ref mut t, unwind: Some(ref mut u), .. }
| Drop { target: ref mut t, unwind: Some(ref mut u), .. }
@@ -590,9 +592,7 @@ impl<'tcx> TerminatorKind<'tcx> {
write!(fmt, "replace({:?} <- {:?})", place, value)
}
Call { func, args, destination, .. } => {
if let Some((destination, _)) = destination {
write!(fmt, "{:?} = ", destination)?;
}
write!(fmt, "{:?} = ", destination)?;
write!(fmt, "{:?}(", func)?;
for (index, arg) in args.iter().enumerate() {
if index > 0 {
@@ -683,12 +683,12 @@ impl<'tcx> TerminatorKind<'tcx> {
.chain(iter::once("otherwise".into()))
.collect()
}),
Call { destination: Some(_), cleanup: Some(_), .. } => {
Call { target: Some(_), cleanup: Some(_), .. } => {
vec!["return".into(), "unwind".into()]
}
Call { destination: Some(_), cleanup: None, .. } => vec!["return".into()],
Call { destination: None, cleanup: Some(_), .. } => vec!["unwind".into()],
Call { destination: None, cleanup: None, .. } => vec![],
Call { target: Some(_), cleanup: None, .. } => vec!["return".into()],
Call { target: None, cleanup: Some(_), .. } => vec!["unwind".into()],
Call { target: None, cleanup: None, .. } => vec![],
Yield { drop: Some(_), .. } => vec!["resume".into(), "drop".into()],
Yield { drop: None, .. } => vec!["resume".into()],
DropAndReplace { unwind: None, .. } | Drop { unwind: None, .. } => {

View File

@@ -44,20 +44,15 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
resume_arg: resume_arg.try_fold_with(folder)?,
drop,
},
Call { func, args, destination, cleanup, from_hir_call, fn_span } => {
let dest = destination
.map(|(loc, dest)| (loc.try_fold_with(folder).map(|loc| (loc, dest))))
.transpose()?;
Call {
func: func.try_fold_with(folder)?,
args: args.try_fold_with(folder)?,
destination: dest,
cleanup,
from_hir_call,
fn_span,
}
}
Call { func, args, destination, target, cleanup, from_hir_call, fn_span } => Call {
func: func.try_fold_with(folder)?,
args: args.try_fold_with(folder)?,
destination: destination.try_fold_with(folder)?,
target,
cleanup,
from_hir_call,
fn_span,
},
Assert { cond, expected, msg, target, cleanup } => {
use AssertKind::*;
let msg = match msg {
@@ -113,9 +108,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
}
Yield { ref value, .. } => value.visit_with(visitor),
Call { ref func, ref args, ref destination, .. } => {
if let Some((ref loc, _)) = *destination {
loc.visit_with(visitor)?;
};
destination.visit_with(visitor)?;
func.visit_with(visitor)?;
args.visit_with(visitor)
}

View File

@@ -534,6 +534,7 @@ macro_rules! make_mir_visitor {
func,
args,
destination,
target: _,
cleanup: _,
from_hir_call: _,
fn_span: _
@@ -542,13 +543,11 @@ macro_rules! make_mir_visitor {
for arg in args {
self.visit_operand(arg, location);
}
if let Some((destination, _)) = destination {
self.visit_place(
destination,
PlaceContext::MutatingUse(MutatingUseContext::Call),
location
);
}
self.visit_place(
destination,
PlaceContext::MutatingUse(MutatingUseContext::Call),
location
);
}
TerminatorKind::Assert {