Streamline AbortUnwindingCalls
.
Currently it constructs two vectors `calls_to_terminated` and `cleanups_to_remove` in the main loop, and then processes them after the main loop. But the processing can be done in the main loop, avoiding the need for the vectors.
This commit is contained in:
parent
cd9fd274d1
commit
ec6fe4e198
@ -50,9 +50,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||||||
// with a function call, and whose function we're calling may unwind.
|
// with a function call, and whose function we're calling may unwind.
|
||||||
// This will filter to functions with `extern "C-unwind"` ABIs, for
|
// This will filter to functions with `extern "C-unwind"` ABIs, for
|
||||||
// example.
|
// example.
|
||||||
let mut calls_to_terminate = Vec::new();
|
for block in body.basic_blocks.as_mut() {
|
||||||
let mut cleanups_to_remove = Vec::new();
|
|
||||||
for (id, block) in body.basic_blocks.iter_enumerated() {
|
|
||||||
if block.is_cleanup {
|
if block.is_cleanup {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -61,7 +59,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||||||
|
|
||||||
let call_can_unwind = match &terminator.kind {
|
let call_can_unwind = match &terminator.kind {
|
||||||
TerminatorKind::Call { func, .. } => {
|
TerminatorKind::Call { func, .. } => {
|
||||||
let ty = func.ty(body, tcx);
|
let ty = func.ty(&body.local_decls, tcx);
|
||||||
let sig = ty.fn_sig(tcx);
|
let sig = ty.fn_sig(tcx);
|
||||||
let fn_def_id = match ty.kind() {
|
let fn_def_id = match ty.kind() {
|
||||||
ty::FnPtr(..) => None,
|
ty::FnPtr(..) => None,
|
||||||
@ -86,31 +84,20 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !call_can_unwind {
|
||||||
// If this function call can't unwind, then there's no need for it
|
// If this function call can't unwind, then there's no need for it
|
||||||
// to have a landing pad. This means that we can remove any cleanup
|
// to have a landing pad. This means that we can remove any cleanup
|
||||||
// registered for it.
|
// registered for it.
|
||||||
if !call_can_unwind {
|
let cleanup = block.terminator_mut().unwind_mut().unwrap();
|
||||||
cleanups_to_remove.push(id);
|
*cleanup = UnwindAction::Unreachable;
|
||||||
continue;
|
} else if !body_can_unwind {
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise if this function can unwind, then if the outer function
|
// Otherwise if this function can unwind, then if the outer function
|
||||||
// can also unwind there's nothing to do. If the outer function
|
// can also unwind there's nothing to do. If the outer function
|
||||||
// can't unwind, however, we need to change the landing pad for this
|
// can't unwind, however, we need to change the landing pad for this
|
||||||
// function call to one that aborts.
|
// function call to one that aborts.
|
||||||
if !body_can_unwind {
|
let cleanup = block.terminator_mut().unwind_mut().unwrap();
|
||||||
calls_to_terminate.push(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for id in calls_to_terminate {
|
|
||||||
let cleanup = body.basic_blocks_mut()[id].terminator_mut().unwind_mut().unwrap();
|
|
||||||
*cleanup = UnwindAction::Terminate(UnwindTerminateReason::Abi);
|
*cleanup = UnwindAction::Terminate(UnwindTerminateReason::Abi);
|
||||||
}
|
}
|
||||||
|
|
||||||
for id in cleanups_to_remove {
|
|
||||||
let cleanup = body.basic_blocks_mut()[id].terminator_mut().unwind_mut().unwrap();
|
|
||||||
*cleanup = UnwindAction::Unreachable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We may have invalidated some `cleanup` blocks so clean those up now.
|
// We may have invalidated some `cleanup` blocks so clean those up now.
|
||||||
|
Loading…
Reference in New Issue
Block a user