Refactor storage of LandingPad
s
This commit is contained in:
parent
06266eb3bd
commit
a9ab8096ba
7 changed files with 58 additions and 34 deletions
|
@ -988,7 +988,7 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn avoid_invoke(bcx: Block) -> bool {
|
pub fn avoid_invoke(bcx: Block) -> bool {
|
||||||
bcx.sess().no_landing_pads() || bcx.lpad.borrow().is_some()
|
bcx.sess().no_landing_pads() || bcx.lpad().is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn need_invoke(bcx: Block) -> bool {
|
pub fn need_invoke(bcx: Block) -> bool {
|
||||||
|
@ -1616,6 +1616,7 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
|
||||||
param_substs: param_substs,
|
param_substs: param_substs,
|
||||||
span: sp,
|
span: sp,
|
||||||
block_arena: block_arena,
|
block_arena: block_arena,
|
||||||
|
lpad_arena: TypedArena::new(),
|
||||||
ccx: ccx,
|
ccx: ccx,
|
||||||
debug_context: debug_context,
|
debug_context: debug_context,
|
||||||
scopes: RefCell::new(Vec::new()),
|
scopes: RefCell::new(Vec::new()),
|
||||||
|
|
|
@ -150,8 +150,7 @@ pub fn Invoke(cx: Block,
|
||||||
cx.val_to_string(fn_),
|
cx.val_to_string(fn_),
|
||||||
args.iter().map(|a| cx.val_to_string(*a)).collect::<Vec<String>>().join(", "));
|
args.iter().map(|a| cx.val_to_string(*a)).collect::<Vec<String>>().join(", "));
|
||||||
debug_loc.apply(cx.fcx);
|
debug_loc.apply(cx.fcx);
|
||||||
let lpad = cx.lpad.borrow();
|
let bundle = cx.lpad().and_then(|b| b.bundle());
|
||||||
let bundle = lpad.as_ref().and_then(|b| b.bundle());
|
|
||||||
B(cx).invoke(fn_, args, then, catch, bundle, attributes)
|
B(cx).invoke(fn_, args, then, catch, bundle, attributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -916,8 +915,7 @@ pub fn Call(cx: Block,
|
||||||
return _UndefReturn(cx, fn_);
|
return _UndefReturn(cx, fn_);
|
||||||
}
|
}
|
||||||
debug_loc.apply(cx.fcx);
|
debug_loc.apply(cx.fcx);
|
||||||
let lpad = cx.lpad.borrow();
|
let bundle = cx.lpad.get().and_then(|b| b.bundle());
|
||||||
let bundle = lpad.as_ref().and_then(|b| b.bundle());
|
|
||||||
B(cx).call(fn_, args, bundle, attributes)
|
B(cx).call(fn_, args, bundle, attributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,8 +930,7 @@ pub fn CallWithConv(cx: Block,
|
||||||
return _UndefReturn(cx, fn_);
|
return _UndefReturn(cx, fn_);
|
||||||
}
|
}
|
||||||
debug_loc.apply(cx.fcx);
|
debug_loc.apply(cx.fcx);
|
||||||
let lpad = cx.lpad.borrow();
|
let bundle = cx.lpad.get().and_then(|b| b.bundle());
|
||||||
let bundle = lpad.as_ref().and_then(|b| b.bundle());
|
|
||||||
B(cx).call_with_conv(fn_, args, conv, bundle, attributes)
|
B(cx).call_with_conv(fn_, args, conv, bundle, attributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -740,7 +740,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
|
||||||
UnwindExit(val) => {
|
UnwindExit(val) => {
|
||||||
// Generate a block that will resume unwinding to the
|
// Generate a block that will resume unwinding to the
|
||||||
// calling function
|
// calling function
|
||||||
let bcx = self.new_block("resume", None);
|
let bcx = self.new_block("resume", None, None);
|
||||||
match val {
|
match val {
|
||||||
UnwindKind::LandingPad => {
|
UnwindKind::LandingPad => {
|
||||||
let addr = self.landingpad_alloca.get()
|
let addr = self.landingpad_alloca.get()
|
||||||
|
@ -830,7 +830,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
|
||||||
let name = scope.block_name("clean");
|
let name = scope.block_name("clean");
|
||||||
debug!("generating cleanups for {}", name);
|
debug!("generating cleanups for {}", name);
|
||||||
|
|
||||||
let bcx_in = self.new_block(&name[..], None);
|
let bcx_in = self.new_block(&name[..], None, None);
|
||||||
let exit_label = label.start(bcx_in);
|
let exit_label = label.start(bcx_in);
|
||||||
let mut bcx_out = bcx_in;
|
let mut bcx_out = bcx_in;
|
||||||
let len = scope.cleanups.len();
|
let len = scope.cleanups.len();
|
||||||
|
@ -873,7 +873,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
|
||||||
Some(llbb) => return llbb,
|
Some(llbb) => return llbb,
|
||||||
None => {
|
None => {
|
||||||
let name = last_scope.block_name("unwind");
|
let name = last_scope.block_name("unwind");
|
||||||
pad_bcx = self.new_block(&name[..], None);
|
pad_bcx = self.new_block(&name[..], None, None);
|
||||||
last_scope.cached_landing_pad = Some(pad_bcx.llbb);
|
last_scope.cached_landing_pad = Some(pad_bcx.llbb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1054,11 +1054,11 @@ impl EarlyExitLabel {
|
||||||
match *self {
|
match *self {
|
||||||
UnwindExit(UnwindKind::CleanupPad(..)) => {
|
UnwindExit(UnwindKind::CleanupPad(..)) => {
|
||||||
let pad = build::CleanupPad(bcx, None, &[]);
|
let pad = build::CleanupPad(bcx, None, &[]);
|
||||||
*bcx.lpad.borrow_mut() = Some(LandingPad::msvc(pad));
|
bcx.lpad.set(Some(bcx.fcx.lpad_arena.alloc(LandingPad::msvc(pad))));
|
||||||
UnwindExit(UnwindKind::CleanupPad(pad))
|
UnwindExit(UnwindKind::CleanupPad(pad))
|
||||||
}
|
}
|
||||||
UnwindExit(UnwindKind::LandingPad) => {
|
UnwindExit(UnwindKind::LandingPad) => {
|
||||||
*bcx.lpad.borrow_mut() = Some(LandingPad::gnu());
|
bcx.lpad.set(Some(bcx.fcx.lpad_arena.alloc(LandingPad::gnu())));
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
label => label,
|
label => label,
|
||||||
|
|
|
@ -367,6 +367,9 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
|
||||||
// The arena that blocks are allocated from.
|
// The arena that blocks are allocated from.
|
||||||
pub block_arena: &'a TypedArena<BlockS<'a, 'tcx>>,
|
pub block_arena: &'a TypedArena<BlockS<'a, 'tcx>>,
|
||||||
|
|
||||||
|
// The arena that landing pads are allocated from.
|
||||||
|
pub lpad_arena: TypedArena<LandingPad>,
|
||||||
|
|
||||||
// This function's enclosing crate context.
|
// This function's enclosing crate context.
|
||||||
pub ccx: &'a CrateContext<'a, 'tcx>,
|
pub ccx: &'a CrateContext<'a, 'tcx>,
|
||||||
|
|
||||||
|
@ -431,14 +434,19 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
||||||
|
|
||||||
pub fn new_block(&'a self,
|
pub fn new_block(&'a self,
|
||||||
name: &str,
|
name: &str,
|
||||||
opt_node_id: Option<ast::NodeId>)
|
opt_node_id: Option<ast::NodeId>,
|
||||||
|
landing_pad: Option<LandingPad>)
|
||||||
-> Block<'a, 'tcx> {
|
-> Block<'a, 'tcx> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let name = CString::new(name).unwrap();
|
let name = CString::new(name).unwrap();
|
||||||
let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
|
let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
|
||||||
self.llfn,
|
self.llfn,
|
||||||
name.as_ptr());
|
name.as_ptr());
|
||||||
BlockS::new(llbb, opt_node_id, self)
|
let block = BlockS::new(llbb, opt_node_id, self);
|
||||||
|
if let Some(landing_pad) = landing_pad {
|
||||||
|
block.lpad.set(Some(self.lpad_arena.alloc(landing_pad)));
|
||||||
|
}
|
||||||
|
block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,13 +454,13 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
||||||
name: &str,
|
name: &str,
|
||||||
node_id: ast::NodeId)
|
node_id: ast::NodeId)
|
||||||
-> Block<'a, 'tcx> {
|
-> Block<'a, 'tcx> {
|
||||||
self.new_block(name, Some(node_id))
|
self.new_block(name, Some(node_id), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_temp_block(&'a self,
|
pub fn new_temp_block(&'a self,
|
||||||
name: &str)
|
name: &str)
|
||||||
-> Block<'a, 'tcx> {
|
-> Block<'a, 'tcx> {
|
||||||
self.new_block(name, None)
|
self.new_block(name, None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join_blocks(&'a self,
|
pub fn join_blocks(&'a self,
|
||||||
|
@ -584,7 +592,7 @@ pub struct BlockS<'blk, 'tcx: 'blk> {
|
||||||
|
|
||||||
// If this block part of a landing pad, then this is `Some` indicating what
|
// If this block part of a landing pad, then this is `Some` indicating what
|
||||||
// kind of landing pad its in, otherwise this is none.
|
// kind of landing pad its in, otherwise this is none.
|
||||||
pub lpad: RefCell<Option<LandingPad>>,
|
pub lpad: Cell<Option<&'blk LandingPad>>,
|
||||||
|
|
||||||
// AST node-id associated with this block, if any. Used for
|
// AST node-id associated with this block, if any. Used for
|
||||||
// debugging purposes only.
|
// debugging purposes only.
|
||||||
|
@ -606,7 +614,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
|
||||||
llbb: llbb,
|
llbb: llbb,
|
||||||
terminated: Cell::new(false),
|
terminated: Cell::new(false),
|
||||||
unreachable: Cell::new(false),
|
unreachable: Cell::new(false),
|
||||||
lpad: RefCell::new(None),
|
lpad: Cell::new(None),
|
||||||
opt_node_id: opt_node_id,
|
opt_node_id: opt_node_id,
|
||||||
fcx: fcx
|
fcx: fcx
|
||||||
})
|
})
|
||||||
|
@ -623,6 +631,10 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
|
||||||
}
|
}
|
||||||
pub fn sess(&self) -> &'blk Session { self.fcx.ccx.sess() }
|
pub fn sess(&self) -> &'blk Session { self.fcx.ccx.sess() }
|
||||||
|
|
||||||
|
pub fn lpad(&self) -> Option<&'blk LandingPad> {
|
||||||
|
self.lpad.get()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mir(&self) -> &'blk Mir<'tcx> {
|
pub fn mir(&self) -> &'blk Mir<'tcx> {
|
||||||
self.fcx.mir()
|
self.fcx.mir()
|
||||||
}
|
}
|
||||||
|
@ -747,6 +759,10 @@ impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> {
|
||||||
self.bcx.llbb
|
self.bcx.llbb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lpad(&self) -> Option<&'blk LandingPad> {
|
||||||
|
self.bcx.lpad()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mir(&self) -> &'blk Mir<'tcx> {
|
pub fn mir(&self) -> &'blk Mir<'tcx> {
|
||||||
self.bcx.mir()
|
self.bcx.mir()
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,13 +119,16 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||||
if let Some(unwind) = unwind {
|
if let Some(unwind) = unwind {
|
||||||
let uwbcx = self.bcx(unwind);
|
let uwbcx = self.bcx(unwind);
|
||||||
let unwind = self.make_landing_pad(uwbcx);
|
let unwind = self.make_landing_pad(uwbcx);
|
||||||
|
let bundle = bcx.lpad().and_then(|b| b.bundle());
|
||||||
bcx.invoke(drop_fn,
|
bcx.invoke(drop_fn,
|
||||||
&[llvalue],
|
&[llvalue],
|
||||||
self.llblock(target),
|
self.llblock(target),
|
||||||
unwind.llbb(),
|
unwind.llbb(),
|
||||||
|
bundle,
|
||||||
None);
|
None);
|
||||||
} else {
|
} else {
|
||||||
bcx.call(drop_fn, &[llvalue], None);
|
let bundle = bcx.lpad().and_then(|b| b.bundle());
|
||||||
|
bcx.call(drop_fn, &[llvalue], bundle, None);
|
||||||
bcx.br(self.llblock(target));
|
bcx.br(self.llblock(target));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,24 +190,28 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||||
let cleanup = self.bcx(cleanup);
|
let cleanup = self.bcx(cleanup);
|
||||||
let landingpad = self.make_landing_pad(cleanup);
|
let landingpad = self.make_landing_pad(cleanup);
|
||||||
let unreachable_blk = self.unreachable_block();
|
let unreachable_blk = self.unreachable_block();
|
||||||
|
let bundle = bcx.lpad().and_then(|b| b.bundle());
|
||||||
bcx.invoke(callee.immediate(),
|
bcx.invoke(callee.immediate(),
|
||||||
&llargs[..],
|
&llargs[..],
|
||||||
unreachable_blk.llbb,
|
unreachable_blk.llbb,
|
||||||
landingpad.llbb(),
|
landingpad.llbb(),
|
||||||
|
bundle,
|
||||||
Some(attrs));
|
Some(attrs));
|
||||||
},
|
},
|
||||||
(false, false, &Some(cleanup), &Some((_, success))) => {
|
(false, false, &Some(cleanup), &Some((_, success))) => {
|
||||||
let cleanup = self.bcx(cleanup);
|
let cleanup = self.bcx(cleanup);
|
||||||
let landingpad = self.make_landing_pad(cleanup);
|
let landingpad = self.make_landing_pad(cleanup);
|
||||||
let (target, postinvoke) = if must_copy_dest {
|
let (target, postinvoke) = if must_copy_dest {
|
||||||
(bcx.fcx().new_block("", None), Some(self.bcx(success)))
|
(bcx.fcx().new_block("", None, None).build(), Some(self.bcx(success)))
|
||||||
} else {
|
} else {
|
||||||
(self.bcx(success), None)
|
(self.bcx(success), None)
|
||||||
};
|
};
|
||||||
|
let bundle = bcx.lpad().and_then(|b| b.bundle());
|
||||||
let invokeret = bcx.invoke(callee.immediate(),
|
let invokeret = bcx.invoke(callee.immediate(),
|
||||||
&llargs[..],
|
&llargs[..],
|
||||||
target.llbb(),
|
target.llbb(),
|
||||||
landingpad.llbb(),
|
landingpad.llbb(),
|
||||||
|
bundle,
|
||||||
Some(attrs));
|
Some(attrs));
|
||||||
if let Some(postinvoketarget) = postinvoke {
|
if let Some(postinvoketarget) = postinvoke {
|
||||||
// We translate the copy into a temporary block. The temporary block is
|
// We translate the copy into a temporary block. The temporary block is
|
||||||
|
@ -240,7 +247,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(false, _, _, &None) => {
|
(false, _, _, &None) => {
|
||||||
bcx.call(callee.immediate(), &llargs[..], Some(attrs));
|
let bundle = bcx.lpad().and_then(|b| b.bundle());
|
||||||
|
bcx.call(callee.immediate(), &llargs[..], bundle, Some(attrs));
|
||||||
bcx.unreachable();
|
bcx.unreachable();
|
||||||
}
|
}
|
||||||
(false, _, _, &Some((_, target))) => {
|
(false, _, _, &Some((_, target))) => {
|
||||||
|
@ -301,12 +309,11 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||||
cleanup: BlockAndBuilder<'bcx, 'tcx>)
|
cleanup: BlockAndBuilder<'bcx, 'tcx>)
|
||||||
-> BlockAndBuilder<'bcx, 'tcx>
|
-> BlockAndBuilder<'bcx, 'tcx>
|
||||||
{
|
{
|
||||||
|
let cleanup_llbb = cleanup.llbb();
|
||||||
let bcx = cleanup.map_block(|cleanup| {
|
let bcx = cleanup.map_block(|cleanup| {
|
||||||
cleanup.fcx.new_block("cleanup", None)
|
|
||||||
});
|
|
||||||
// FIXME(#30941) this doesn't handle msvc-style exceptions
|
// FIXME(#30941) this doesn't handle msvc-style exceptions
|
||||||
*bcx.lpad.borrow_mut() = Some(LandingPad::gnu());
|
cleanup.fcx.new_block("cleanup", None, Some(LandingPad::gnu()))
|
||||||
let bcx = bcx.build();
|
});
|
||||||
let ccx = bcx.ccx();
|
let ccx = bcx.ccx();
|
||||||
let llpersonality = bcx.fcx().eh_personality();
|
let llpersonality = bcx.fcx().eh_personality();
|
||||||
let llretty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)], false);
|
let llretty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)], false);
|
||||||
|
@ -314,13 +321,13 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||||
bcx.set_cleanup(llretval);
|
bcx.set_cleanup(llretval);
|
||||||
let slot = self.get_personality_slot(&bcx);
|
let slot = self.get_personality_slot(&bcx);
|
||||||
bcx.store(llretval, slot);
|
bcx.store(llretval, slot);
|
||||||
bcx.br(cleanup.llbb());
|
bcx.br(cleanup_llbb);
|
||||||
bcx
|
bcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unreachable_block(&mut self) -> Block<'bcx, 'tcx> {
|
fn unreachable_block(&mut self) -> Block<'bcx, 'tcx> {
|
||||||
self.unreachable_block.unwrap_or_else(|| {
|
self.unreachable_block.unwrap_or_else(|| {
|
||||||
let bl = self.fcx.new_block("unreachable", None);
|
let bl = self.fcx.new_block("unreachable", None, None);
|
||||||
bl.build().unreachable();
|
bl.build().unreachable();
|
||||||
self.unreachable_block = Some(bl);
|
self.unreachable_block = Some(bl);
|
||||||
bl
|
bl
|
||||||
|
|
|
@ -114,12 +114,13 @@ pub fn trans_mir<'bcx, 'tcx>(bcx: BlockAndBuilder<'bcx, 'tcx>) {
|
||||||
let block_bcxs: Vec<Block<'bcx,'tcx>> =
|
let block_bcxs: Vec<Block<'bcx,'tcx>> =
|
||||||
mir_blocks.iter()
|
mir_blocks.iter()
|
||||||
.map(|&bb|{
|
.map(|&bb|{
|
||||||
let bcx = fcx.new_block(&format!("{:?}", bb), None);
|
|
||||||
// FIXME(#30941) this doesn't handle msvc-style exceptions
|
// FIXME(#30941) this doesn't handle msvc-style exceptions
|
||||||
if mir.basic_block_data(bb).is_cleanup {
|
let lpad = if mir.basic_block_data(bb).is_cleanup {
|
||||||
*bcx.lpad.borrow_mut() = Some(LandingPad::gnu())
|
Some(LandingPad::gnu())
|
||||||
}
|
} else {
|
||||||
bcx
|
None
|
||||||
|
};
|
||||||
|
fcx.new_block(&format!("{:?}", bb), None, lpad)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
|
@ -497,10 +497,12 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||||
if input_ty == tcx.types.f32 {
|
if input_ty == tcx.types.f32 {
|
||||||
let lllhs = bcx.fpext(lhs, f64t);
|
let lllhs = bcx.fpext(lhs, f64t);
|
||||||
let llrhs = bcx.fpext(rhs, f64t);
|
let llrhs = bcx.fpext(rhs, f64t);
|
||||||
let llres = bcx.call(llfn, &[lllhs, llrhs], None);
|
let bundle = bcx.lpad().and_then(|b| b.bundle());
|
||||||
|
let llres = bcx.call(llfn, &[lllhs, llrhs], bundle, None);
|
||||||
bcx.fptrunc(llres, Type::f32(bcx.ccx()))
|
bcx.fptrunc(llres, Type::f32(bcx.ccx()))
|
||||||
} else {
|
} else {
|
||||||
bcx.call(llfn, &[lhs, rhs], None)
|
let bundle = bcx.lpad().and_then(|b| b.bundle());
|
||||||
|
bcx.call(llfn, &[lhs, rhs], bundle, None)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bcx.frem(lhs, rhs)
|
bcx.frem(lhs, rhs)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue