Rename LandingPad to Funclet
Changes internal storage to direct field values instead of Options, since both fields are always either set or not set.
This commit is contained in:
parent
8f3d824cc7
commit
86b2bdb435
|
@ -762,7 +762,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
|||
param_substs: param_substs,
|
||||
span: None,
|
||||
//block_arena: block_arena,
|
||||
lpad_arena: TypedArena::new(),
|
||||
funclet_arena: TypedArena::new(),
|
||||
ccx: ccx,
|
||||
debug_context: debug_context,
|
||||
scopes: RefCell::new(Vec::new()),
|
||||
|
|
|
@ -119,7 +119,7 @@ pub use self::EarlyExitLabel::*;
|
|||
use llvm::{BasicBlockRef, ValueRef};
|
||||
use base::{self, Lifetime};
|
||||
use common;
|
||||
use common::{BlockAndBuilder, FunctionContext, LandingPad};
|
||||
use common::{BlockAndBuilder, FunctionContext, Funclet};
|
||||
use debuginfo::{DebugLoc};
|
||||
use glue;
|
||||
use type_::Type;
|
||||
|
@ -343,7 +343,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
|||
|
||||
let mut bcx = bcx;
|
||||
for cleanup in scope.cleanups.iter().rev() {
|
||||
bcx = cleanup.trans(bcx);
|
||||
bcx = cleanup.trans(bcx.funclet(), bcx);
|
||||
}
|
||||
bcx
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
|||
bcx.call(
|
||||
bcx.fcx().eh_unwind_resume().reify(bcx.ccx()),
|
||||
&[exc_ptr],
|
||||
bcx.lpad().and_then(|b| b.bundle()));
|
||||
bcx.funclet().map(|b| b.bundle()));
|
||||
}
|
||||
}
|
||||
UnwindKind::CleanupPad(_) => {
|
||||
|
@ -495,7 +495,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
|||
let mut bcx_out = bcx_in;
|
||||
let len = scope.cleanups.len();
|
||||
for cleanup in scope.cleanups.iter().rev().take(len - skip) {
|
||||
bcx_out = cleanup.trans(bcx_out);
|
||||
bcx_out = cleanup.trans(bcx_out.funclet(), bcx_out);
|
||||
}
|
||||
skip = 0;
|
||||
exit_label.branch(&bcx_out, prev_llbb);
|
||||
|
@ -645,7 +645,7 @@ impl EarlyExitLabel {
|
|||
/// for the same kind of early exit label that `self` is.
|
||||
///
|
||||
/// This function will appropriately configure `bcx` based on the kind of
|
||||
/// label this is. For UnwindExit labels, the `lpad` field of the block will
|
||||
/// label this is. For UnwindExit labels, the `funclet` field of the block will
|
||||
/// be set to `Some`, and for MSVC exceptions this function will generate a
|
||||
/// `cleanuppad` instruction at the start of the block so it may be jumped
|
||||
/// to in the future (e.g. so this block can be cached as an early exit).
|
||||
|
@ -656,11 +656,11 @@ impl EarlyExitLabel {
|
|||
match *self {
|
||||
UnwindExit(UnwindKind::CleanupPad(..)) => {
|
||||
let pad = bcx.cleanup_pad(None, &[]);
|
||||
bcx.set_lpad_ref(Some(bcx.fcx().lpad_arena.alloc(LandingPad::msvc(pad))));
|
||||
bcx.set_funclet(Funclet::msvc(pad));
|
||||
UnwindExit(UnwindKind::CleanupPad(pad))
|
||||
}
|
||||
UnwindExit(UnwindKind::LandingPad) => {
|
||||
bcx.set_lpad_ref(Some(bcx.fcx().lpad_arena.alloc(LandingPad::gnu())));
|
||||
bcx.set_funclet(Funclet::gnu());
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
@ -689,18 +689,20 @@ pub struct DropValue<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> DropValue<'tcx> {
|
||||
fn trans<'blk>(&self, bcx: BlockAndBuilder<'blk, 'tcx>) -> BlockAndBuilder<'blk, 'tcx> {
|
||||
fn trans<'blk>(
|
||||
&self,
|
||||
funclet: Option<&'blk Funclet>,
|
||||
bcx: BlockAndBuilder<'blk, 'tcx>,
|
||||
) -> BlockAndBuilder<'blk, 'tcx> {
|
||||
if self.is_immediate {
|
||||
let vp = base::alloc_ty(&bcx, self.ty, "");
|
||||
Lifetime::Start.call(&bcx, vp);
|
||||
base::store_ty(&bcx, self.val, vp, self.ty);
|
||||
let lpad = bcx.lpad();
|
||||
let bcx = glue::call_drop_glue(bcx, vp, self.ty, self.skip_dtor, lpad);
|
||||
let bcx = glue::call_drop_glue(bcx, vp, self.ty, self.skip_dtor, funclet);
|
||||
Lifetime::End.call(&bcx, vp);
|
||||
bcx
|
||||
} else {
|
||||
let lpad = bcx.lpad();
|
||||
glue::call_drop_glue(bcx, self.val, self.ty, self.skip_dtor, lpad)
|
||||
glue::call_drop_glue(bcx, self.val, self.ty, self.skip_dtor, funclet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
|
|||
//pub block_arena: &'a TypedArena<BlockS<'a, 'tcx>>,
|
||||
|
||||
// The arena that landing pads are allocated from.
|
||||
pub lpad_arena: TypedArena<LandingPad>,
|
||||
pub funclet_arena: TypedArena<Funclet>,
|
||||
|
||||
// This function's enclosing crate context.
|
||||
pub ccx: &'a CrateContext<'a, 'tcx>,
|
||||
|
@ -483,7 +483,7 @@ pub struct BlockAndBuilder<'blk, 'tcx: 'blk> {
|
|||
|
||||
// If this block part of a landing pad, then this is `Some` indicating what
|
||||
// kind of landing pad its in, otherwise this is none.
|
||||
lpad: Cell<Option<&'blk LandingPad>>,
|
||||
funclet: Cell<Option<&'blk Funclet>>,
|
||||
|
||||
// The function context for the function to which this block is
|
||||
// attached.
|
||||
|
@ -499,7 +499,7 @@ impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> {
|
|||
owned_builder.builder.position_at_end(llbb);
|
||||
BlockAndBuilder {
|
||||
llbb: llbb,
|
||||
lpad: Cell::new(None),
|
||||
funclet: Cell::new(None),
|
||||
fcx: fcx,
|
||||
owned_builder: owned_builder,
|
||||
}
|
||||
|
@ -535,17 +535,17 @@ impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> {
|
|||
self.fcx.mir()
|
||||
}
|
||||
|
||||
pub fn set_lpad(&self, lpad: Option<LandingPad>) {
|
||||
self.set_lpad_ref(lpad.map(|p| &*self.fcx().lpad_arena.alloc(p)))
|
||||
pub fn set_funclet(&self, funclet: Option<Funclet>) {
|
||||
self.set_funclet_ref(funclet.map(|p| &*self.fcx().funclet_arena.alloc(p)))
|
||||
}
|
||||
|
||||
pub fn set_lpad_ref(&self, lpad: Option<&'blk LandingPad>) {
|
||||
pub fn set_funclet_ref(&self, funclet: Option<&'blk Funclet>) {
|
||||
// FIXME: use an IVar?
|
||||
self.lpad.set(lpad);
|
||||
self.funclet.set(funclet);
|
||||
}
|
||||
|
||||
pub fn lpad(&self) -> Option<&'blk LandingPad> {
|
||||
self.lpad.get()
|
||||
pub fn funclet(&self) -> Option<&'blk Funclet> {
|
||||
self.funclet.get()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -570,39 +570,37 @@ impl<'blk, 'tcx> Deref for BlockAndBuilder<'blk, 'tcx> {
|
|||
/// When inside of a landing pad, each function call in LLVM IR needs to be
|
||||
/// annotated with which landing pad it's a part of. This is accomplished via
|
||||
/// the `OperandBundleDef` value created for MSVC landing pads.
|
||||
pub struct LandingPad {
|
||||
cleanuppad: Option<ValueRef>,
|
||||
operand: Option<OperandBundleDef>,
|
||||
pub struct Funclet {
|
||||
cleanuppad: ValueRef,
|
||||
operand: OperandBundleDef,
|
||||
}
|
||||
|
||||
impl LandingPad {
|
||||
pub fn gnu() -> LandingPad {
|
||||
LandingPad { cleanuppad: None, operand: None }
|
||||
impl Funclet {
|
||||
pub fn gnu() -> Option<Funclet> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn msvc(cleanuppad: ValueRef) -> LandingPad {
|
||||
LandingPad {
|
||||
cleanuppad: Some(cleanuppad),
|
||||
operand: Some(OperandBundleDef::new("funclet", &[cleanuppad])),
|
||||
}
|
||||
pub fn msvc(cleanuppad: ValueRef) -> Option<Funclet> {
|
||||
Some(Funclet {
|
||||
cleanuppad: cleanuppad,
|
||||
operand: OperandBundleDef::new("funclet", &[cleanuppad]),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn bundle(&self) -> Option<&OperandBundleDef> {
|
||||
self.operand.as_ref()
|
||||
}
|
||||
|
||||
pub fn cleanuppad(&self) -> Option<ValueRef> {
|
||||
pub fn cleanuppad(&self) -> ValueRef {
|
||||
self.cleanuppad
|
||||
}
|
||||
|
||||
pub fn bundle(&self) -> &OperandBundleDef {
|
||||
&self.operand
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for LandingPad {
|
||||
fn clone(&self) -> LandingPad {
|
||||
LandingPad {
|
||||
impl Clone for Funclet {
|
||||
fn clone(&self) -> Funclet {
|
||||
Funclet {
|
||||
cleanuppad: self.cleanuppad,
|
||||
operand: self.cleanuppad.map(|p| {
|
||||
OperandBundleDef::new("funclet", &[p])
|
||||
}),
|
||||
operand: OperandBundleDef::new("funclet", &[self.cleanuppad]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ pub fn call_drop_glue<'blk, 'tcx>(
|
|||
v: ValueRef,
|
||||
t: Ty<'tcx>,
|
||||
skip_dtor: bool,
|
||||
lpad: Option<&'blk LandingPad>,
|
||||
funclet: Option<&'blk Funclet>,
|
||||
) -> BlockAndBuilder<'blk, 'tcx> {
|
||||
// NB: v is an *alias* of type t here, not a direct value.
|
||||
debug!("call_drop_glue(t={:?}, skip_dtor={})", t, skip_dtor);
|
||||
|
@ -154,7 +154,7 @@ pub fn call_drop_glue<'blk, 'tcx>(
|
|||
};
|
||||
|
||||
// No drop-hint ==> call standard drop glue
|
||||
bcx.call(glue, &[ptr], lpad.and_then(|b| b.bundle()));
|
||||
bcx.call(glue, &[ptr], funclet.map(|b| b.bundle()));
|
||||
}
|
||||
bcx
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use abi::{Abi, FnType, ArgType};
|
|||
use adt;
|
||||
use base::{self, Lifetime};
|
||||
use callee::{Callee, CalleeData, Fn, Intrinsic, NamedTupleConstructor, Virtual};
|
||||
use common::{self, BlockAndBuilder, LandingPad};
|
||||
use common::{self, BlockAndBuilder, Funclet};
|
||||
use common::{C_bool, C_str_slice, C_struct, C_u32, C_undef};
|
||||
use consts;
|
||||
use debuginfo::DebugLoc;
|
||||
|
@ -44,20 +44,20 @@ use std::ptr;
|
|||
|
||||
impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||
pub fn trans_block(&mut self, bb: mir::BasicBlock,
|
||||
lpads: &IndexVec<mir::BasicBlock, Option<LandingPad>>) {
|
||||
funclets: &IndexVec<mir::BasicBlock, Option<Funclet>>) {
|
||||
let mut bcx = self.build_block(bb);
|
||||
let data = &CellRef::clone(&self.mir)[bb];
|
||||
|
||||
debug!("trans_block({:?}={:?})", bb, data);
|
||||
|
||||
let lpad = match self.cleanup_kinds[bb] {
|
||||
CleanupKind::Internal { funclet } => lpads[funclet].as_ref(),
|
||||
_ => lpads[bb].as_ref(),
|
||||
let funclet = match self.cleanup_kinds[bb] {
|
||||
CleanupKind::Internal { funclet } => funclets[funclet].as_ref(),
|
||||
_ => funclets[bb].as_ref(),
|
||||
};
|
||||
|
||||
// Create the cleanup bundle, if needed.
|
||||
let cleanup_pad = lpad.and_then(|lp| lp.cleanuppad());
|
||||
let cleanup_bundle = lpad.and_then(|l| l.bundle());
|
||||
let cleanup_pad = funclet.map(|lp| lp.cleanuppad());
|
||||
let cleanup_bundle = funclet.map(|l| l.bundle());
|
||||
|
||||
let funclet_br = |this: &Self, bcx: BlockAndBuilder, bb: mir::BasicBlock| {
|
||||
let lltarget = this.blocks[bb];
|
||||
|
@ -866,28 +866,28 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
|||
}
|
||||
|
||||
pub fn init_cpad(&mut self, bb: mir::BasicBlock,
|
||||
lpads: &mut IndexVec<mir::BasicBlock, Option<LandingPad>>) {
|
||||
funclets: &mut IndexVec<mir::BasicBlock, Option<Funclet>>) {
|
||||
let bcx = self.build_block(bb);
|
||||
let data = &self.mir[bb];
|
||||
debug!("init_cpad({:?})", data);
|
||||
|
||||
match self.cleanup_kinds[bb] {
|
||||
CleanupKind::NotCleanup => {
|
||||
lpads[bb] = None;
|
||||
funclets[bb] = None;
|
||||
}
|
||||
_ if !base::wants_msvc_seh(bcx.sess()) => {
|
||||
lpads[bb] = Some(LandingPad::gnu());
|
||||
funclets[bb] = Funclet::gnu();
|
||||
}
|
||||
CleanupKind::Internal { funclet: _ } => {
|
||||
// FIXME: is this needed?
|
||||
bcx.set_personality_fn(self.fcx.eh_personality());
|
||||
lpads[bb] = None;
|
||||
funclets[bb] = None;
|
||||
}
|
||||
CleanupKind::Funclet => {
|
||||
bcx.set_personality_fn(self.fcx.eh_personality());
|
||||
DebugLoc::None.apply_to_bcx(&bcx);
|
||||
let cleanup_pad = bcx.cleanup_pad(None, &[]);
|
||||
lpads[bb] = Some(LandingPad::msvc(cleanup_pad));
|
||||
funclets[bb] = Funclet::msvc(cleanup_pad);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use rustc::mir;
|
|||
use rustc::mir::tcx::LvalueTy;
|
||||
use session::config::FullDebugInfo;
|
||||
use base;
|
||||
use common::{self, BlockAndBuilder, CrateContext, FunctionContext, C_null, LandingPad};
|
||||
use common::{self, BlockAndBuilder, CrateContext, FunctionContext, C_null, Funclet};
|
||||
use debuginfo::{self, declare_local, DebugLoc, VariableAccess, VariableKind, FunctionDebugContext};
|
||||
use type_of;
|
||||
|
||||
|
@ -285,19 +285,19 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
|
|||
|
||||
let mut rpo = traversal::reverse_postorder(&mir);
|
||||
|
||||
let mut lpads: IndexVec<mir::BasicBlock, Option<LandingPad>> =
|
||||
let mut funclets: IndexVec<mir::BasicBlock, Option<Funclet>> =
|
||||
IndexVec::from_elem(None, mir.basic_blocks());
|
||||
|
||||
// Prepare each block for translation.
|
||||
for (bb, _) in rpo.by_ref() {
|
||||
mircx.init_cpad(bb, &mut lpads);
|
||||
mircx.init_cpad(bb, &mut funclets);
|
||||
}
|
||||
rpo.reset();
|
||||
|
||||
// Translate the body of each block using reverse postorder
|
||||
for (bb, _) in rpo {
|
||||
visited.insert(bb.index());
|
||||
mircx.trans_block(bb, &lpads);
|
||||
mircx.trans_block(bb, &funclets);
|
||||
}
|
||||
|
||||
// Remove blocks that haven't been visited, or have no
|
||||
|
|
Loading…
Reference in New Issue