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:
Mark-Simulacrum 2016-12-12 06:48:39 -07:00 committed by Mark Simulacrum
parent 8f3d824cc7
commit 86b2bdb435
6 changed files with 62 additions and 62 deletions

View File

@ -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()),

View File

@ -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)
}
}
}

View File

@ -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]),
}
}
}

View File

@ -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
}

View File

@ -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);
}
};
}

View File

@ -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