Skip to content

Commit a811f60

Browse files
Simplify get_landing_pad by inlining UnwindKind.
1 parent 654131c commit a811f60

File tree

1 file changed

+22
-72
lines changed

1 file changed

+22
-72
lines changed

src/librustc_trans/cleanup.rs

Lines changed: 22 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
//! completing evaluation successfully without panic).
2020
2121
use llvm::{BasicBlockRef, ValueRef};
22-
use base::{self, Lifetime};
23-
use common;
22+
use base;
2423
use common::{BlockAndBuilder, FunctionContext, Funclet};
2524
use glue;
2625
use type_::Type;
@@ -55,90 +54,41 @@ impl<'tcx> DropValue<'tcx> {
5554
/// This should only be called once per function, as it creates an alloca for the landingpad.
5655
fn get_landing_pad<'a>(&self, fcx: &FunctionContext<'a, 'tcx>) -> BasicBlockRef {
5756
debug!("get_landing_pad");
57+
let bcx = fcx.build_new_block("cleanup_unwind");
58+
let llpersonality = bcx.ccx.eh_personality();
59+
bcx.set_personality_fn(llpersonality);
5860

59-
let mut pad_bcx = fcx.build_new_block("unwind_custom_");
60-
61-
let llpersonality = pad_bcx.ccx.eh_personality();
62-
63-
let resume_bcx = fcx.build_new_block("resume");
64-
let val = if base::wants_msvc_seh(fcx.ccx.sess()) {
65-
// A cleanup pad requires a personality function to be specified, so
66-
// we do that here explicitly (happens implicitly below through
67-
// creation of the landingpad instruction). We then create a
68-
// cleanuppad instruction which has no filters to run cleanup on all
69-
// exceptions.
70-
pad_bcx.set_personality_fn(llpersonality);
71-
let llretval = pad_bcx.cleanup_pad(None, &[]);
72-
resume_bcx.cleanup_ret(resume_bcx.cleanup_pad(None, &[]), None);
73-
UnwindKind::CleanupPad(llretval)
61+
if base::wants_msvc_seh(fcx.ccx.sess()) {
62+
// Insert cleanup instructions into the cleanup block
63+
let funclet = Some(Funclet::new(bcx.cleanup_pad(None, &[])));
64+
self.trans(funclet.as_ref(), &bcx);
65+
66+
bcx.cleanup_ret(bcx.cleanup_pad(None, &[]), None);
7467
} else {
7568
// The landing pad return type (the type being propagated). Not sure
7669
// what this represents but it's determined by the personality
7770
// function and this is what the EH proposal example uses.
7871
let llretty = Type::struct_(fcx.ccx, &[Type::i8p(fcx.ccx), Type::i32(fcx.ccx)], false);
7972

8073
// The only landing pad clause will be 'cleanup'
81-
let llretval = pad_bcx.landing_pad(llretty, llpersonality, 1, pad_bcx.fcx().llfn);
74+
let llretval = bcx.landing_pad(llretty, llpersonality, 1, bcx.fcx().llfn);
8275

8376
// The landing pad block is a cleanup
84-
pad_bcx.set_cleanup(llretval);
85-
86-
let addr = pad_bcx.fcx().alloca(common::val_ty(llretval), "");
87-
Lifetime::Start.call(&pad_bcx, addr);
88-
pad_bcx.store(llretval, addr);
89-
let lp = resume_bcx.load(addr);
90-
Lifetime::End.call(&resume_bcx, addr);
91-
if !resume_bcx.sess().target.target.options.custom_unwind_resume {
92-
resume_bcx.resume(lp);
93-
} else {
94-
let exc_ptr = resume_bcx.extract_value(lp, 0);
95-
resume_bcx.call(fcx.eh_unwind_resume().reify(fcx.ccx), &[exc_ptr], None);
96-
resume_bcx.unreachable();
97-
}
98-
UnwindKind::LandingPad
99-
};
77+
bcx.set_cleanup(llretval);
10078

101-
let mut cleanup = fcx.build_new_block("clean_custom_");
79+
// Insert cleanup instructions into the cleanup block
80+
self.trans(None, &bcx);
10281

103-
// Insert cleanup instructions into the cleanup block
104-
let funclet = match val {
105-
UnwindKind::CleanupPad(_) => Some(Funclet::new(cleanup.cleanup_pad(None, &[]))),
106-
UnwindKind::LandingPad => None,
107-
};
108-
self.trans(funclet.as_ref(), &cleanup);
109-
110-
// Insert instruction into cleanup block to branch to the exit
111-
val.branch(&mut cleanup, resume_bcx.llbb());
112-
113-
// Branch into the cleanup block
114-
val.branch(&mut pad_bcx, cleanup.llbb());
115-
116-
pad_bcx.llbb()
117-
}
118-
}
119-
120-
#[derive(Copy, Clone, Debug)]
121-
enum UnwindKind {
122-
LandingPad,
123-
CleanupPad(ValueRef),
124-
}
125-
126-
impl UnwindKind {
127-
/// Generates a branch going from `bcx` to `to_llbb` where `self` is
128-
/// the exit label attached to the start of `bcx`.
129-
///
130-
/// Transitions from an exit label to other exit labels depend on the type
131-
/// of label. For example with MSVC exceptions unwind exit labels will use
132-
/// the `cleanupret` instruction instead of the `br` instruction.
133-
fn branch(&self, bcx: &BlockAndBuilder, to_llbb: BasicBlockRef) {
134-
match *self {
135-
UnwindKind::CleanupPad(pad) => {
136-
bcx.cleanup_ret(pad, Some(to_llbb));
137-
}
138-
UnwindKind::LandingPad => {
139-
bcx.br(to_llbb);
82+
if !bcx.sess().target.target.options.custom_unwind_resume {
83+
bcx.resume(llretval);
84+
} else {
85+
let exc_ptr = bcx.extract_value(llretval, 0);
86+
bcx.call(fcx.eh_unwind_resume().reify(fcx.ccx), &[exc_ptr], None);
87+
bcx.unreachable();
14088
}
14189
}
90+
91+
bcx.llbb()
14292
}
14393
}
14494

0 commit comments

Comments
 (0)