cache the terminate block with the last reason that we saw
This commit is contained in:
parent
ddea3f981e
commit
114fde6ac7
@ -1581,8 +1581,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn terminate_block(&mut self, reason: UnwindTerminateReason) -> Bx::BasicBlock {
|
fn terminate_block(&mut self, reason: UnwindTerminateReason) -> Bx::BasicBlock {
|
||||||
if let Some(bb) = self.terminate_in_cleanup_block && reason == UnwindTerminateReason::InCleanup {
|
if let Some((cached_bb, cached_reason)) = self.terminate_block && reason == cached_reason {
|
||||||
return bb;
|
return cached_bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
let funclet;
|
let funclet;
|
||||||
@ -1653,9 +1653,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
|
|
||||||
bx.unreachable();
|
bx.unreachable();
|
||||||
|
|
||||||
if reason == UnwindTerminateReason::InCleanup {
|
self.terminate_block = Some((llbb, reason));
|
||||||
self.terminate_in_cleanup_block = Some(llbb);
|
|
||||||
}
|
|
||||||
llbb
|
llbb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ use rustc_index::IndexVec;
|
|||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
use rustc_middle::mir::traversal;
|
use rustc_middle::mir::traversal;
|
||||||
|
use rustc_middle::mir::UnwindTerminateReason;
|
||||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
|
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
|
||||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
||||||
use rustc_target::abi::call::{FnAbi, PassMode};
|
use rustc_target::abi::call::{FnAbi, PassMode};
|
||||||
@ -83,8 +84,8 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
|
|||||||
/// Cached unreachable block
|
/// Cached unreachable block
|
||||||
unreachable_block: Option<Bx::BasicBlock>,
|
unreachable_block: Option<Bx::BasicBlock>,
|
||||||
|
|
||||||
/// Cached terminate upon unwinding (reason: InCleanup) block
|
/// Cached terminate upon unwinding block and its reason
|
||||||
terminate_in_cleanup_block: Option<Bx::BasicBlock>,
|
terminate_block: Option<(Bx::BasicBlock, UnwindTerminateReason)>,
|
||||||
|
|
||||||
/// The location where each MIR arg/var/tmp/ret is stored. This is
|
/// The location where each MIR arg/var/tmp/ret is stored. This is
|
||||||
/// usually an `PlaceRef` representing an alloca, but not always:
|
/// usually an `PlaceRef` representing an alloca, but not always:
|
||||||
@ -199,7 +200,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||||||
personality_slot: None,
|
personality_slot: None,
|
||||||
cached_llbbs,
|
cached_llbbs,
|
||||||
unreachable_block: None,
|
unreachable_block: None,
|
||||||
terminate_in_cleanup_block: None,
|
terminate_block: None,
|
||||||
cleanup_kinds,
|
cleanup_kinds,
|
||||||
landing_pads: IndexVec::from_elem(None, &mir.basic_blocks),
|
landing_pads: IndexVec::from_elem(None, &mir.basic_blocks),
|
||||||
funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks.len()),
|
funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks.len()),
|
||||||
|
@ -14,8 +14,8 @@ pub struct MirPatch<'tcx> {
|
|||||||
resume_block: Option<BasicBlock>,
|
resume_block: Option<BasicBlock>,
|
||||||
// Only for unreachable in cleanup path.
|
// Only for unreachable in cleanup path.
|
||||||
unreachable_cleanup_block: Option<BasicBlock>,
|
unreachable_cleanup_block: Option<BasicBlock>,
|
||||||
// Cached block for UnwindTerminate(InCleanup)
|
// Cached block for UnwindTerminate (with reason)
|
||||||
terminate_in_cleanup_block: Option<BasicBlock>,
|
terminate_block: Option<(BasicBlock, UnwindTerminateReason)>,
|
||||||
body_span: Span,
|
body_span: Span,
|
||||||
next_local: usize,
|
next_local: usize,
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ impl<'tcx> MirPatch<'tcx> {
|
|||||||
next_local: body.local_decls.len(),
|
next_local: body.local_decls.len(),
|
||||||
resume_block: None,
|
resume_block: None,
|
||||||
unreachable_cleanup_block: None,
|
unreachable_cleanup_block: None,
|
||||||
terminate_in_cleanup_block: None,
|
terminate_block: None,
|
||||||
body_span: body.span,
|
body_span: body.span,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,12 +53,10 @@ impl<'tcx> MirPatch<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if we already have a terminate block
|
// Check if we already have a terminate block
|
||||||
if matches!(
|
if let TerminatorKind::UnwindTerminate(reason) = block.terminator().kind
|
||||||
block.terminator().kind,
|
&& block.statements.is_empty()
|
||||||
TerminatorKind::UnwindTerminate(UnwindTerminateReason::InCleanup)
|
|
||||||
) && block.statements.is_empty()
|
|
||||||
{
|
{
|
||||||
result.terminate_in_cleanup_block = Some(bb);
|
result.terminate_block = Some((bb, reason));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,8 +99,8 @@ impl<'tcx> MirPatch<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn terminate_block(&mut self, reason: UnwindTerminateReason) -> BasicBlock {
|
pub fn terminate_block(&mut self, reason: UnwindTerminateReason) -> BasicBlock {
|
||||||
if let Some(bb) = self.terminate_in_cleanup_block && reason == UnwindTerminateReason::InCleanup {
|
if let Some((cached_bb, cached_reason)) = self.terminate_block && reason == cached_reason {
|
||||||
return bb;
|
return cached_bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bb = self.new_block(BasicBlockData {
|
let bb = self.new_block(BasicBlockData {
|
||||||
@ -113,9 +111,7 @@ impl<'tcx> MirPatch<'tcx> {
|
|||||||
}),
|
}),
|
||||||
is_cleanup: true,
|
is_cleanup: true,
|
||||||
});
|
});
|
||||||
if reason == UnwindTerminateReason::InCleanup {
|
self.terminate_block = Some((bb, reason));
|
||||||
self.terminate_in_cleanup_block = Some(bb);
|
|
||||||
}
|
|
||||||
bb
|
bb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user