Skip to content

Commit 35b40f5

Browse files
committed
[eddyb/rebase cleanup] abstracted Funclet
1 parent 566fa4d commit 35b40f5

File tree

9 files changed

+59
-86
lines changed

9 files changed

+59
-86
lines changed

src/librustc_codegen_llvm/builder.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
// except according to those terms.
1010

1111
use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
12-
use llvm::{self, False, OperandBundleDef, BasicBlock};
13-
use common;
12+
use llvm::{self, False, BasicBlock};
1413
use rustc_codegen_utils::common::{IntPredicate, TypeKind, RealPredicate};
1514
use rustc_codegen_utils;
15+
use common::Funclet;
1616
use context::CodegenCx;
1717
use type_::Type;
1818
use type_of::LayoutLlvmExt;
@@ -66,6 +66,7 @@ impl BackendTypes for Builder<'_, 'll, 'tcx> {
6666
type BasicBlock = <CodegenCx<'ll, 'tcx> as BackendTypes>::BasicBlock;
6767
type Type = <CodegenCx<'ll, 'tcx> as BackendTypes>::Type;
6868
type Context = <CodegenCx<'ll, 'tcx> as BackendTypes>::Context;
69+
type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet;
6970

7071
type DIScope = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIScope;
7172
}
@@ -218,12 +219,14 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
218219
}
219220
}
220221

221-
fn invoke(&self,
222-
llfn: &'ll Value,
223-
args: &[&'ll Value],
224-
then: &'ll BasicBlock,
225-
catch: &'ll BasicBlock,
226-
funclet: Option<&common::Funclet<&'ll Value>>) -> &'ll Value {
222+
fn invoke(
223+
&self,
224+
llfn: &'ll Value,
225+
args: &[&'ll Value],
226+
then: &'ll BasicBlock,
227+
catch: &'ll BasicBlock,
228+
funclet: Option<&Funclet<'ll>>,
229+
) -> &'ll Value {
227230
self.count_insn("invoke");
228231

229232
debug!("Invoke {:?} with args ({:?})",
@@ -232,7 +235,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
232235

233236
let args = self.check_call("invoke", llfn, args);
234237
let bundle = funclet.map(|funclet| funclet.bundle());
235-
let bundle = bundle.map(OperandBundleDef::from_generic);
236238
let bundle = bundle.as_ref().map(|b| &*b.raw);
237239

238240
unsafe {
@@ -1123,7 +1125,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11231125

11241126
fn cleanup_pad(&self,
11251127
parent: Option<&'ll Value>,
1126-
args: &[&'ll Value]) -> &'ll Value {
1128+
args: &[&'ll Value]) -> Funclet<'ll> {
11271129
self.count_insn("cleanuppad");
11281130
let name = const_cstr!("cleanuppad");
11291131
let ret = unsafe {
@@ -1133,37 +1135,37 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11331135
args.as_ptr(),
11341136
name.as_ptr())
11351137
};
1136-
ret.expect("LLVM does not have support for cleanuppad")
1138+
Funclet::new(ret.expect("LLVM does not have support for cleanuppad"))
11371139
}
11381140

11391141
fn cleanup_ret(
1140-
&self, cleanup: &'ll Value,
1142+
&self, funclet: &Funclet<'ll>,
11411143
unwind: Option<&'ll BasicBlock>,
11421144
) -> &'ll Value {
11431145
self.count_insn("cleanupret");
11441146
let ret = unsafe {
1145-
llvm::LLVMRustBuildCleanupRet(self.llbuilder, cleanup, unwind)
1147+
llvm::LLVMRustBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind)
11461148
};
11471149
ret.expect("LLVM does not have support for cleanupret")
11481150
}
11491151

11501152
fn catch_pad(&self,
11511153
parent: &'ll Value,
1152-
args: &[&'ll Value]) -> &'ll Value {
1154+
args: &[&'ll Value]) -> Funclet<'ll> {
11531155
self.count_insn("catchpad");
11541156
let name = const_cstr!("catchpad");
11551157
let ret = unsafe {
11561158
llvm::LLVMRustBuildCatchPad(self.llbuilder, parent,
11571159
args.len() as c_uint, args.as_ptr(),
11581160
name.as_ptr())
11591161
};
1160-
ret.expect("LLVM does not have support for catchpad")
1162+
Funclet::new(ret.expect("LLVM does not have support for catchpad"))
11611163
}
11621164

1163-
fn catch_ret(&self, pad: &'ll Value, unwind: &'ll BasicBlock) -> &'ll Value {
1165+
fn catch_ret(&self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value {
11641166
self.count_insn("catchret");
11651167
let ret = unsafe {
1166-
llvm::LLVMRustBuildCatchRet(self.llbuilder, pad, unwind)
1168+
llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind)
11671169
};
11681170
ret.expect("LLVM does not have support for catchret")
11691171
}
@@ -1356,8 +1358,12 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
13561358
self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None);
13571359
}
13581360

1359-
fn call(&self, llfn: &'ll Value, args: &[&'ll Value],
1360-
funclet: Option<&common::Funclet<&'ll Value>>) -> &'ll Value {
1361+
fn call(
1362+
&self,
1363+
llfn: &'ll Value,
1364+
args: &[&'ll Value],
1365+
funclet: Option<&Funclet<'ll>>,
1366+
) -> &'ll Value {
13611367
self.count_insn("call");
13621368

13631369
debug!("Call {:?} with args ({:?})",
@@ -1366,7 +1372,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
13661372

13671373
let args = self.check_call("call", llfn, args);
13681374
let bundle = funclet.map(|funclet| funclet.bundle());
1369-
let bundle = bundle.map(OperandBundleDef::from_generic);
13701375
let bundle = bundle.as_ref().map(|b| &*b.raw);
13711376

13721377
unsafe {

src/librustc_codegen_llvm/common.rs

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
//! Code that is useful in various codegen modules.
1414
15-
use llvm::{self, True, False, Bool, BasicBlock};
15+
use llvm::{self, True, False, Bool, BasicBlock, OperandBundleDef};
1616
use rustc::hir::def_id::DefId;
1717
use rustc::middle::lang_items::LangItem;
1818
use abi;
@@ -23,7 +23,7 @@ use type_of::LayoutLlvmExt;
2323
use value::Value;
2424
use interfaces::*;
2525

26-
use rustc::ty::{self, Ty, TyCtxt};
26+
use rustc::ty::{Ty, TyCtxt};
2727
use rustc::ty::layout::{HasDataLayout, LayoutOf, self, TyLayout, Size};
2828
use rustc::mir::interpret::{Scalar, AllocType, Allocation};
2929
use rustc::hir;
@@ -35,36 +35,10 @@ use libc::{c_uint, c_char};
3535

3636
use syntax::symbol::LocalInternedString;
3737
use syntax::ast::Mutability;
38-
use syntax_pos::{Span, DUMMY_SP};
38+
use syntax_pos::Span;
3939

4040
pub use context::CodegenCx;
4141

42-
pub fn type_needs_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {
43-
ty.needs_drop(tcx, ty::ParamEnv::reveal_all())
44-
}
45-
46-
pub fn type_is_sized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {
47-
ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::reveal_all())
48-
}
49-
50-
pub fn type_is_freeze<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {
51-
ty.is_freeze(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP)
52-
}
53-
54-
pub struct OperandBundleDef<'a, V> {
55-
pub name: &'a str,
56-
pub val: V
57-
}
58-
59-
impl<'a, V> OperandBundleDef<'a, V> {
60-
pub fn new(name: &'a str, val: V) -> Self {
61-
OperandBundleDef {
62-
name,
63-
val
64-
}
65-
}
66-
}
67-
6842
/*
6943
* A note on nomenclature of linking: "extern", "foreign", and "upcall".
7044
*
@@ -105,24 +79,24 @@ impl<'a, V> OperandBundleDef<'a, V> {
10579
/// When inside of a landing pad, each function call in LLVM IR needs to be
10680
/// annotated with which landing pad it's a part of. This is accomplished via
10781
/// the `OperandBundleDef` value created for MSVC landing pads.
108-
pub struct Funclet<'a, V> {
109-
cleanuppad: V,
110-
operand: OperandBundleDef<'a, V>,
82+
pub struct Funclet<'ll> {
83+
cleanuppad: &'ll Value,
84+
operand: OperandBundleDef<'ll>,
11185
}
11286

113-
impl<'a, V: CodegenObject> Funclet<'a, V> {
114-
pub fn new(cleanuppad: V) -> Self {
87+
impl Funclet<'ll> {
88+
pub fn new(cleanuppad: &'ll Value) -> Self {
11589
Funclet {
11690
cleanuppad,
117-
operand: OperandBundleDef::new("funclet", cleanuppad),
91+
operand: OperandBundleDef::new("funclet", &[cleanuppad]),
11892
}
11993
}
12094

121-
pub fn cleanuppad(&self) -> V {
95+
pub fn cleanuppad(&self) -> &'ll Value {
12296
self.cleanuppad
12397
}
12498

125-
pub fn bundle(&self) -> &OperandBundleDef<'a, V> {
99+
pub fn bundle(&self) -> &OperandBundleDef<'ll> {
126100
&self.operand
127101
}
128102
}
@@ -132,6 +106,7 @@ impl BackendTypes for CodegenCx<'ll, 'tcx> {
132106
type BasicBlock = &'ll BasicBlock;
133107
type Type = &'ll Type;
134108
type Context = &'ll llvm::Context;
109+
type Funclet = Funclet<'ll>;
135110

136111
type DIScope = &'ll llvm::debuginfo::DIScope;
137112
}

src/librustc_codegen_llvm/interfaces/backend.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub trait BackendTypes {
2828
type BasicBlock: Copy;
2929
type Type: CodegenObject;
3030
type Context;
31+
type Funclet;
3132

3233
type DIScope: Copy;
3334
}

src/librustc_codegen_llvm/interfaces/builder.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use super::intrinsic::IntrinsicCallMethods;
1515
use super::type_::ArgTypeMethods;
1616
use super::HasCodegen;
1717
use builder::MemFlags;
18-
use common::*;
1918
use libc::c_char;
2019
use mir::operand::OperandRef;
2120
use mir::place::PlaceRef;
@@ -58,7 +57,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
5857
args: &[Self::Value],
5958
then: Self::BasicBlock,
6059
catch: Self::BasicBlock,
61-
funclet: Option<&Funclet<Self::Value>>,
60+
funclet: Option<&Self::Funclet>,
6261
) -> Self::Value;
6362
fn unreachable(&self);
6463
fn add(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
@@ -213,10 +212,10 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
213212
fn add_clause(&self, landing_pad: Self::Value, clause: Self::Value);
214213
fn set_cleanup(&self, landing_pad: Self::Value);
215214
fn resume(&self, exn: Self::Value) -> Self::Value;
216-
fn cleanup_pad(&self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Value;
217-
fn cleanup_ret(&self, cleanup: Self::Value, unwind: Option<Self::BasicBlock>) -> Self::Value;
218-
fn catch_pad(&self, parent: Self::Value, args: &[Self::Value]) -> Self::Value;
219-
fn catch_ret(&self, pad: Self::Value, unwind: Self::BasicBlock) -> Self::Value;
215+
fn cleanup_pad(&self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Funclet;
216+
fn cleanup_ret(&self, funclet: &Self::Funclet, unwind: Option<Self::BasicBlock>) -> Self::Value;
217+
fn catch_pad(&self, parent: Self::Value, args: &[Self::Value]) -> Self::Funclet;
218+
fn catch_ret(&self, funclet: &Self::Funclet, unwind: Self::BasicBlock) -> Self::Value;
220219
fn catch_switch(
221220
&self,
222221
parent: Option<Self::Value>,
@@ -276,7 +275,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
276275
&self,
277276
llfn: Self::Value,
278277
args: &[Self::Value],
279-
funclet: Option<&Funclet<Self::Value>>,
278+
funclet: Option<&Self::Funclet>,
280279
) -> Self::Value;
281280
fn zext(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
282281

src/librustc_codegen_llvm/interfaces/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub trait HasCodegen<'tcx>: Backend<'tcx> {
7272
BasicBlock = Self::BasicBlock,
7373
Type = Self::Type,
7474
Context = Self::Context,
75+
Funclet = Self::Funclet,
7576
DIScope = Self::DIScope,
7677
>;
7778
}

src/librustc_codegen_llvm/intrinsic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ fn codegen_msvc_try(
894894
Some(did) => cx.get_static(did),
895895
None => bug!("msvc_try_filter not defined"),
896896
};
897-
let tok = catchpad.catch_pad(cs, &[tydesc, cx.const_i32(0), slot]);
897+
let funclet = catchpad.catch_pad(cs, &[tydesc, cx.const_i32(0), slot]);
898898
let addr = catchpad.load(slot, ptr_align);
899899

900900
let i64_align = bx.tcx().data_layout.i64_align;
@@ -904,7 +904,7 @@ fn codegen_msvc_try(
904904
let local_ptr = catchpad.bitcast(local_ptr, i64p);
905905
catchpad.store(arg1, local_ptr, i64_align);
906906
catchpad.store(arg2, catchpad.inbounds_gep(local_ptr, &[val1]), i64_align);
907-
catchpad.catch_ret(tok, caught.llbb());
907+
catchpad.catch_ret(&funclet, caught.llbb());
908908

909909
caught.ret(cx.const_i32(1));
910910
});

src/librustc_codegen_llvm/llvm/mod.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use std::ffi::CStr;
2828
use std::cell::RefCell;
2929
use libc::{self, c_uint, c_char, size_t};
3030
use rustc_data_structures::small_c_str::SmallCStr;
31-
use common;
3231

3332
pub mod archive_ro;
3433
pub mod diagnostic;
@@ -272,10 +271,6 @@ impl OperandBundleDef<'a> {
272271
};
273272
OperandBundleDef { raw: def }
274273
}
275-
276-
pub fn from_generic(bundle: &common::OperandBundleDef<'a, &'a Value>) -> Self {
277-
Self::new(bundle.name, &[bundle.val])
278-
}
279274
}
280275

281276
impl Drop for OperandBundleDef<'a> {

src/librustc_codegen_llvm/mir/block.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use abi::{Abi, FnType, PassMode};
1717
use rustc_target::abi::call::ArgType;
1818
use base;
1919
use builder::MemFlags;
20-
use common::{self, Funclet};
20+
use common;
2121
use rustc_codegen_utils::common::IntPredicate;
2222
use meth;
2323
use monomorphize;
@@ -67,7 +67,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
6767
funclet_bb: Option<mir::BasicBlock>
6868
) -> impl for<'b> Fn(
6969
&'b FunctionCx<'a, 'tcx, Bx>,
70-
) -> Option<&'b Funclet<'static, Bx::Value>> {
70+
) -> Option<&'b Bx::Funclet> {
7171
move |this| {
7272
match funclet_bb {
7373
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> {
7777
}
7878
let funclet = funclet_closure_factory(funclet_bb);
7979

80-
let cleanup_pad = |this: &Self| funclet(this).map(|lp| lp.cleanuppad());
81-
8280
let lltarget = |this: &mut Self, target: mir::BasicBlock| {
8381
let lltarget = this.blocks[target];
8482
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> {
106104
debug!("llblock: creating cleanup trampoline for {:?}", target);
107105
let name = &format!("{:?}_cleanup_trampoline_{:?}", bb, target);
108106
let trampoline = this.new_block(name);
109-
trampoline.cleanup_ret(cleanup_pad(this).unwrap(), Some(lltarget));
107+
trampoline.cleanup_ret(funclet(this).unwrap(), Some(lltarget));
110108
trampoline.llbb()
111109
} else {
112110
lltarget
@@ -119,7 +117,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
119117
if is_cleanupret {
120118
// micro-optimization: generate a `ret` rather than a jump
121119
// to a trampoline.
122-
bx.cleanup_ret(cleanup_pad(this).unwrap(), Some(lltarget));
120+
bx.cleanup_ret(funclet(this).unwrap(), Some(lltarget));
123121
} else {
124122
bx.br(lltarget);
125123
}
@@ -175,8 +173,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
175173
self.set_debug_loc(&bx, terminator.source_info);
176174
match terminator.kind {
177175
mir::TerminatorKind::Resume => {
178-
if let Some(cleanup_pad) = cleanup_pad(self) {
179-
bx.cleanup_ret(cleanup_pad, None);
176+
if let Some(funclet) = funclet(self) {
177+
bx.cleanup_ret(funclet, None);
180178
} else {
181179
let slot = self.get_personality_slot(&bx);
182180
let lp0 = bx.load_operand(slot.project_field(&bx, 0)).immediate();

0 commit comments

Comments
 (0)