diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2018-11-13 12:51:42 +0200 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2018-11-16 14:40:12 +0200 |
| commit | 35b40f51fb3fbe177745f251e2f58d928227a89a (patch) | |
| tree | 6c8c792ca6c87aed0220536549a1c7ab3a68f45e | |
| parent | 566fa4d003dd27c63a708a9e5e4e5c673a276f8d (diff) | |
| download | rust-35b40f51fb3fbe177745f251e2f58d928227a89a.tar.gz rust-35b40f51fb3fbe177745f251e2f58d928227a89a.zip | |
[eddyb/rebase cleanup] abstracted Funclet
| -rw-r--r-- | src/librustc_codegen_llvm/builder.rs | 45 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/common.rs | 49 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/interfaces/backend.rs | 1 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/interfaces/builder.rs | 13 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/interfaces/mod.rs | 1 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/intrinsic.rs | 4 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/mod.rs | 5 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/mir/block.rs | 14 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/mir/mod.rs | 13 |
9 files changed, 59 insertions, 86 deletions
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 8e6832361a6..ae0d89a5609 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -9,10 +9,10 @@ // except according to those terms. use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect}; -use llvm::{self, False, OperandBundleDef, BasicBlock}; -use common; +use llvm::{self, False, BasicBlock}; use rustc_codegen_utils::common::{IntPredicate, TypeKind, RealPredicate}; use rustc_codegen_utils; +use common::Funclet; use context::CodegenCx; use type_::Type; use type_of::LayoutLlvmExt; @@ -66,6 +66,7 @@ impl BackendTypes for Builder<'_, 'll, 'tcx> { type BasicBlock = <CodegenCx<'ll, 'tcx> as BackendTypes>::BasicBlock; type Type = <CodegenCx<'ll, 'tcx> as BackendTypes>::Type; type Context = <CodegenCx<'ll, 'tcx> as BackendTypes>::Context; + type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet; type DIScope = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIScope; } @@ -218,12 +219,14 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn invoke(&self, - llfn: &'ll Value, - args: &[&'ll Value], - then: &'ll BasicBlock, - catch: &'ll BasicBlock, - funclet: Option<&common::Funclet<&'ll Value>>) -> &'ll Value { + fn invoke( + &self, + llfn: &'ll Value, + args: &[&'ll Value], + then: &'ll BasicBlock, + catch: &'ll BasicBlock, + funclet: Option<&Funclet<'ll>>, + ) -> &'ll Value { self.count_insn("invoke"); debug!("Invoke {:?} with args ({:?})", @@ -232,7 +235,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let args = self.check_call("invoke", llfn, args); let bundle = funclet.map(|funclet| funclet.bundle()); - let bundle = bundle.map(OperandBundleDef::from_generic); let bundle = bundle.as_ref().map(|b| &*b.raw); unsafe { @@ -1123,7 +1125,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn cleanup_pad(&self, parent: Option<&'ll Value>, - args: &[&'ll Value]) -> &'ll Value { + args: &[&'ll Value]) -> Funclet<'ll> { self.count_insn("cleanuppad"); let name = const_cstr!("cleanuppad"); let ret = unsafe { @@ -1133,23 +1135,23 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { args.as_ptr(), name.as_ptr()) }; - ret.expect("LLVM does not have support for cleanuppad") + Funclet::new(ret.expect("LLVM does not have support for cleanuppad")) } fn cleanup_ret( - &self, cleanup: &'ll Value, + &self, funclet: &Funclet<'ll>, unwind: Option<&'ll BasicBlock>, ) -> &'ll Value { self.count_insn("cleanupret"); let ret = unsafe { - llvm::LLVMRustBuildCleanupRet(self.llbuilder, cleanup, unwind) + llvm::LLVMRustBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind) }; ret.expect("LLVM does not have support for cleanupret") } fn catch_pad(&self, parent: &'ll Value, - args: &[&'ll Value]) -> &'ll Value { + args: &[&'ll Value]) -> Funclet<'ll> { self.count_insn("catchpad"); let name = const_cstr!("catchpad"); let ret = unsafe { @@ -1157,13 +1159,13 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { args.len() as c_uint, args.as_ptr(), name.as_ptr()) }; - ret.expect("LLVM does not have support for catchpad") + Funclet::new(ret.expect("LLVM does not have support for catchpad")) } - fn catch_ret(&self, pad: &'ll Value, unwind: &'ll BasicBlock) -> &'ll Value { + fn catch_ret(&self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value { self.count_insn("catchret"); let ret = unsafe { - llvm::LLVMRustBuildCatchRet(self.llbuilder, pad, unwind) + llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) }; ret.expect("LLVM does not have support for catchret") } @@ -1356,8 +1358,12 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None); } - fn call(&self, llfn: &'ll Value, args: &[&'ll Value], - funclet: Option<&common::Funclet<&'ll Value>>) -> &'ll Value { + fn call( + &self, + llfn: &'ll Value, + args: &[&'ll Value], + funclet: Option<&Funclet<'ll>>, + ) -> &'ll Value { self.count_insn("call"); debug!("Call {:?} with args ({:?})", @@ -1366,7 +1372,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let args = self.check_call("call", llfn, args); let bundle = funclet.map(|funclet| funclet.bundle()); - let bundle = bundle.map(OperandBundleDef::from_generic); let bundle = bundle.as_ref().map(|b| &*b.raw); unsafe { diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 8bc20ddd6b1..13e71b8ab04 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -12,7 +12,7 @@ //! Code that is useful in various codegen modules. -use llvm::{self, True, False, Bool, BasicBlock}; +use llvm::{self, True, False, Bool, BasicBlock, OperandBundleDef}; use rustc::hir::def_id::DefId; use rustc::middle::lang_items::LangItem; use abi; @@ -23,7 +23,7 @@ use type_of::LayoutLlvmExt; use value::Value; use interfaces::*; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{Ty, TyCtxt}; use rustc::ty::layout::{HasDataLayout, LayoutOf, self, TyLayout, Size}; use rustc::mir::interpret::{Scalar, AllocType, Allocation}; use rustc::hir; @@ -35,36 +35,10 @@ use libc::{c_uint, c_char}; use syntax::symbol::LocalInternedString; use syntax::ast::Mutability; -use syntax_pos::{Span, DUMMY_SP}; +use syntax_pos::Span; pub use context::CodegenCx; -pub fn type_needs_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.needs_drop(tcx, ty::ParamEnv::reveal_all()) -} - -pub fn type_is_sized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::reveal_all()) -} - -pub fn type_is_freeze<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.is_freeze(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP) -} - -pub struct OperandBundleDef<'a, V> { - pub name: &'a str, - pub val: V -} - -impl<'a, V> OperandBundleDef<'a, V> { - pub fn new(name: &'a str, val: V) -> Self { - OperandBundleDef { - name, - val - } - } -} - /* * A note on nomenclature of linking: "extern", "foreign", and "upcall". * @@ -105,24 +79,24 @@ impl<'a, V> OperandBundleDef<'a, V> { /// 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 Funclet<'a, V> { - cleanuppad: V, - operand: OperandBundleDef<'a, V>, +pub struct Funclet<'ll> { + cleanuppad: &'ll Value, + operand: OperandBundleDef<'ll>, } -impl<'a, V: CodegenObject> Funclet<'a, V> { - pub fn new(cleanuppad: V) -> Self { +impl Funclet<'ll> { + pub fn new(cleanuppad: &'ll Value) -> Self { Funclet { cleanuppad, - operand: OperandBundleDef::new("funclet", cleanuppad), + operand: OperandBundleDef::new("funclet", &[cleanuppad]), } } - pub fn cleanuppad(&self) -> V { + pub fn cleanuppad(&self) -> &'ll Value { self.cleanuppad } - pub fn bundle(&self) -> &OperandBundleDef<'a, V> { + pub fn bundle(&self) -> &OperandBundleDef<'ll> { &self.operand } } @@ -132,6 +106,7 @@ impl BackendTypes for CodegenCx<'ll, 'tcx> { type BasicBlock = &'ll BasicBlock; type Type = &'ll Type; type Context = &'ll llvm::Context; + type Funclet = Funclet<'ll>; type DIScope = &'ll llvm::debuginfo::DIScope; } diff --git a/src/librustc_codegen_llvm/interfaces/backend.rs b/src/librustc_codegen_llvm/interfaces/backend.rs index c6b78150b5f..d21e39769af 100644 --- a/src/librustc_codegen_llvm/interfaces/backend.rs +++ b/src/librustc_codegen_llvm/interfaces/backend.rs @@ -28,6 +28,7 @@ pub trait BackendTypes { type BasicBlock: Copy; type Type: CodegenObject; type Context; + type Funclet; type DIScope: Copy; } diff --git a/src/librustc_codegen_llvm/interfaces/builder.rs b/src/librustc_codegen_llvm/interfaces/builder.rs index 54e0baff381..61e60d55e09 100644 --- a/src/librustc_codegen_llvm/interfaces/builder.rs +++ b/src/librustc_codegen_llvm/interfaces/builder.rs @@ -15,7 +15,6 @@ use super::intrinsic::IntrinsicCallMethods; use super::type_::ArgTypeMethods; use super::HasCodegen; use builder::MemFlags; -use common::*; use libc::c_char; use mir::operand::OperandRef; use mir::place::PlaceRef; @@ -58,7 +57,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: args: &[Self::Value], then: Self::BasicBlock, catch: Self::BasicBlock, - funclet: Option<&Funclet<Self::Value>>, + funclet: Option<&Self::Funclet>, ) -> Self::Value; fn unreachable(&self); fn add(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; @@ -213,10 +212,10 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: fn add_clause(&self, landing_pad: Self::Value, clause: Self::Value); fn set_cleanup(&self, landing_pad: Self::Value); fn resume(&self, exn: Self::Value) -> Self::Value; - fn cleanup_pad(&self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Value; - fn cleanup_ret(&self, cleanup: Self::Value, unwind: Option<Self::BasicBlock>) -> Self::Value; - fn catch_pad(&self, parent: Self::Value, args: &[Self::Value]) -> Self::Value; - fn catch_ret(&self, pad: Self::Value, unwind: Self::BasicBlock) -> Self::Value; + fn cleanup_pad(&self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Funclet; + fn cleanup_ret(&self, funclet: &Self::Funclet, unwind: Option<Self::BasicBlock>) -> Self::Value; + fn catch_pad(&self, parent: Self::Value, args: &[Self::Value]) -> Self::Funclet; + fn catch_ret(&self, funclet: &Self::Funclet, unwind: Self::BasicBlock) -> Self::Value; fn catch_switch( &self, parent: Option<Self::Value>, @@ -276,7 +275,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: &self, llfn: Self::Value, args: &[Self::Value], - funclet: Option<&Funclet<Self::Value>>, + funclet: Option<&Self::Funclet>, ) -> Self::Value; fn zext(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; diff --git a/src/librustc_codegen_llvm/interfaces/mod.rs b/src/librustc_codegen_llvm/interfaces/mod.rs index e0ce05d0a84..f1040020aff 100644 --- a/src/librustc_codegen_llvm/interfaces/mod.rs +++ b/src/librustc_codegen_llvm/interfaces/mod.rs @@ -72,6 +72,7 @@ pub trait HasCodegen<'tcx>: Backend<'tcx> { BasicBlock = Self::BasicBlock, Type = Self::Type, Context = Self::Context, + Funclet = Self::Funclet, DIScope = Self::DIScope, >; } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 708e43ef85d..07b5017e4c8 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -894,7 +894,7 @@ fn codegen_msvc_try( Some(did) => cx.get_static(did), None => bug!("msvc_try_filter not defined"), }; - let tok = catchpad.catch_pad(cs, &[tydesc, cx.const_i32(0), slot]); + let funclet = catchpad.catch_pad(cs, &[tydesc, cx.const_i32(0), slot]); let addr = catchpad.load(slot, ptr_align); let i64_align = bx.tcx().data_layout.i64_align; @@ -904,7 +904,7 @@ fn codegen_msvc_try( let local_ptr = catchpad.bitcast(local_ptr, i64p); catchpad.store(arg1, local_ptr, i64_align); catchpad.store(arg2, catchpad.inbounds_gep(local_ptr, &[val1]), i64_align); - catchpad.catch_ret(tok, caught.llbb()); + catchpad.catch_ret(&funclet, caught.llbb()); caught.ret(cx.const_i32(1)); }); diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index 1d90f8be46d..fbd5192a63f 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -28,7 +28,6 @@ use std::ffi::CStr; use std::cell::RefCell; use libc::{self, c_uint, c_char, size_t}; use rustc_data_structures::small_c_str::SmallCStr; -use common; pub mod archive_ro; pub mod diagnostic; @@ -272,10 +271,6 @@ impl OperandBundleDef<'a> { }; OperandBundleDef { raw: def } } - - pub fn from_generic(bundle: &common::OperandBundleDef<'a, &'a Value>) -> Self { - Self::new(bundle.name, &[bundle.val]) - } } impl Drop for OperandBundleDef<'a> { diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs index 1d3ebebd997..02d532f8c0d 100644 --- a/src/librustc_codegen_llvm/mir/block.rs +++ b/src/librustc_codegen_llvm/mir/block.rs @@ -17,7 +17,7 @@ use abi::{Abi, FnType, PassMode}; use rustc_target::abi::call::ArgType; use base; use builder::MemFlags; -use common::{self, Funclet}; +use common; use rustc_codegen_utils::common::IntPredicate; use meth; use monomorphize; @@ -67,7 +67,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { funclet_bb: Option<mir::BasicBlock> ) -> impl for<'b> Fn( &'b FunctionCx<'a, 'tcx, Bx>, - ) -> Option<&'b Funclet<'static, Bx::Value>> { + ) -> Option<&'b Bx::Funclet> { move |this| { match funclet_bb { Some(funclet_bb) => this.funclets[funclet_bb].as_ref(), @@ -77,8 +77,6 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } let funclet = funclet_closure_factory(funclet_bb); - let cleanup_pad = |this: &Self| funclet(this).map(|lp| lp.cleanuppad()); - let lltarget = |this: &mut Self, target: mir::BasicBlock| { let lltarget = this.blocks[target]; let target_funclet = this.cleanup_kinds[target].funclet_bb(target); @@ -106,7 +104,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { debug!("llblock: creating cleanup trampoline for {:?}", target); let name = &format!("{:?}_cleanup_trampoline_{:?}", bb, target); let trampoline = this.new_block(name); - trampoline.cleanup_ret(cleanup_pad(this).unwrap(), Some(lltarget)); + trampoline.cleanup_ret(funclet(this).unwrap(), Some(lltarget)); trampoline.llbb() } else { lltarget @@ -119,7 +117,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if is_cleanupret { // micro-optimization: generate a `ret` rather than a jump // to a trampoline. - bx.cleanup_ret(cleanup_pad(this).unwrap(), Some(lltarget)); + bx.cleanup_ret(funclet(this).unwrap(), Some(lltarget)); } else { bx.br(lltarget); } @@ -175,8 +173,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.set_debug_loc(&bx, terminator.source_info); match terminator.kind { mir::TerminatorKind::Resume => { - if let Some(cleanup_pad) = cleanup_pad(self) { - bx.cleanup_ret(cleanup_pad, None); + if let Some(funclet) = funclet(self) { + bx.cleanup_ret(funclet, None); } else { let slot = self.get_personality_slot(&bx); let lp0 = bx.load_operand(slot.project_field(&bx, 0)).immediate(); diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs index 4e55964bd00..c7e2a5d2af3 100644 --- a/src/librustc_codegen_llvm/mir/mod.rs +++ b/src/librustc_codegen_llvm/mir/mod.rs @@ -18,7 +18,6 @@ use rustc::ty::subst::Substs; use rustc::session::config::DebugInfo; use base; use debuginfo::{self, VariableAccess, VariableKind, FunctionDebugContext}; -use common::Funclet; use monomorphize::Instance; use abi::{FnType, PassMode}; use interfaces::*; @@ -70,7 +69,7 @@ pub struct FunctionCx<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> { /// When targeting MSVC, this stores the cleanup info for each funclet /// BB. This is initialized as we compute the funclets' head block in RPO. - funclets: IndexVec<mir::BasicBlock, Option<Funclet<'static, Bx::Value>>>, + funclets: IndexVec<mir::BasicBlock, Option<Bx::Funclet>>, /// This stores the landing-pad block for a given BB, computed lazily on GNU /// and eagerly on MSVC. @@ -372,7 +371,7 @@ fn create_funclets<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( cleanup_kinds: &IndexVec<mir::BasicBlock, CleanupKind>, block_bxs: &IndexVec<mir::BasicBlock, Bx::BasicBlock>) -> (IndexVec<mir::BasicBlock, Option<Bx::BasicBlock>>, - IndexVec<mir::BasicBlock, Option<Funclet<'static, Bx::Value>>>) + IndexVec<mir::BasicBlock, Option<Bx::Funclet>>) { block_bxs.iter_enumerated().zip(cleanup_kinds).map(|((bb, &llbb), cleanup_kind)| { match *cleanup_kind { @@ -380,7 +379,7 @@ fn create_funclets<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( _ => return (None, None) } - let cleanup; + let funclet; let ret_llbb; match mir[bb].terminator.as_ref().map(|t| &t.kind) { // This is a basic block that we're aborting the program for, @@ -417,18 +416,18 @@ fn create_funclets<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // represents that this is a catch-all block. let null = bx.cx().const_null(bx.cx().type_i8p()); let sixty_four = bx.cx().const_i32(64); - cleanup = cp_bx.catch_pad(cs, &[null, sixty_four, null]); + funclet = cp_bx.catch_pad(cs, &[null, sixty_four, null]); cp_bx.br(llbb); } _ => { let cleanup_bx = bx.build_sibling_block(&format!("funclet_{:?}", bb)); ret_llbb = cleanup_bx.llbb(); - cleanup = cleanup_bx.cleanup_pad(None, &[]); + funclet = cleanup_bx.cleanup_pad(None, &[]); cleanup_bx.br(llbb); } }; - (Some(ret_llbb), Some(Funclet::new(cleanup))) + (Some(ret_llbb), Some(funclet)) }).unzip() } |
