Skip to content

Commit cef6aee

Browse files
committed
Don’t generate landing-pads if -Z no-landing-pads
1 parent 20ec53a commit cef6aee

File tree

5 files changed

+58
-30
lines changed

5 files changed

+58
-30
lines changed

src/librustc/mir/repr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ impl Debug for BasicBlock {
192192
pub struct BasicBlockData<'tcx> {
193193
pub statements: Vec<Statement<'tcx>>,
194194
pub terminator: Option<Terminator<'tcx>>,
195+
pub is_cleanup: bool,
195196
}
196197

197198
#[derive(RustcEncodable, RustcDecodable)]
@@ -341,6 +342,7 @@ impl<'tcx> BasicBlockData<'tcx> {
341342
BasicBlockData {
342343
statements: vec![],
343344
terminator: terminator,
345+
is_cleanup: false,
344346
}
345347
}
346348

src/librustc_mir/build/scope.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
251251
continue;
252252
} else {
253253
let new_block = self.cfg.start_new_block();
254+
self.cfg.block_data_mut(new_block).is_cleanup = true;
254255
self.cfg.terminate(new_block, terminator);
255256
terminator = Terminator::Goto { target: new_block };
256257
for &(kind, span, ref lvalue) in scope.drops.iter().rev() {

src/librustc_trans/trans/base.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -958,22 +958,28 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
958958
sess.target.target.options.is_like_msvc && sess.target.target.arch == "x86"
959959
}
960960

961-
pub fn need_invoke(bcx: Block) -> bool {
961+
pub fn avoid_invoke(bcx: Block) -> bool {
962962
// FIXME(#25869) currently SEH-based unwinding is pretty buggy in LLVM and
963963
// is being overhauled as this is being written. Until that
964964
// time such that upstream LLVM's implementation is more solid
965965
// and we start binding it we need to skip invokes for any
966966
// target which wants SEH-based unwinding.
967967
if bcx.sess().no_landing_pads() || wants_msvc_seh(bcx.sess()) {
968-
return false;
968+
true
969+
} else if bcx.is_lpad {
970+
// Avoid using invoke if we are already inside a landing pad.
971+
true
972+
} else {
973+
false
969974
}
975+
}
970976

971-
// Avoid using invoke if we are already inside a landing pad.
972-
if bcx.is_lpad {
973-
return false;
977+
pub fn need_invoke(bcx: Block) -> bool {
978+
if avoid_invoke(bcx) {
979+
false
980+
} else {
981+
bcx.fcx.needs_invoke()
974982
}
975-
976-
bcx.fcx.needs_invoke()
977983
}
978984

979985
pub fn load_if_immediate<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, t: Ty<'tcx>) -> ValueRef {

src/librustc_trans/trans/mir/block.rs

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -128,19 +128,9 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
128128

129129
let debugloc = DebugLoc::None;
130130
let attrs = attributes::from_fn_type(bcx.ccx(), callee.ty);
131-
match *targets {
132-
mir::CallTargets::Return(ret) => {
133-
let llret = build::Call(bcx,
134-
callee.immediate(),
135-
&llargs[..],
136-
Some(attrs),
137-
debugloc);
138-
if !return_outptr && !common::type_is_zero_size(bcx.ccx(), ret_ty) {
139-
base::store_ty(bcx, llret, call_dest.llval, ret_ty);
140-
}
141-
build::Br(bcx, self.llblock(ret), debugloc)
142-
}
143-
mir::CallTargets::WithCleanup((ret, cleanup)) => {
131+
match (*targets, base::avoid_invoke(bcx)) {
132+
(mir::CallTargets::WithCleanup((ret, cleanup)), false) => {
133+
let cleanup = self.bcx(cleanup);
144134
let landingpad = self.make_landing_pad(cleanup);
145135
build::Invoke(bcx,
146136
callee.immediate(),
@@ -153,6 +143,26 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
153143
// FIXME: What do we do here?
154144
unimplemented!()
155145
}
146+
},
147+
(t, _) => {
148+
let ret = match t {
149+
mir::CallTargets::Return(ret) => ret,
150+
mir::CallTargets::WithCleanup((ret, _)) => {
151+
// make a landing pad regardless (so it sets the personality slot.
152+
let block = self.unreachable_block();
153+
self.make_landing_pad(block);
154+
ret
155+
}
156+
};
157+
let llret = build::Call(bcx,
158+
callee.immediate(),
159+
&llargs[..],
160+
Some(attrs),
161+
debugloc);
162+
if !return_outptr && !common::type_is_zero_size(bcx.ccx(), ret_ty) {
163+
base::store_ty(bcx, llret, call_dest.llval, ret_ty);
164+
}
165+
build::Br(bcx, self.llblock(ret), debugloc)
156166
}
157167
}
158168
},
@@ -171,12 +181,9 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
171181
}
172182
let debugloc = DebugLoc::None;
173183
let attrs = attributes::from_fn_type(bcx.ccx(), callee.ty);
174-
match *cleanup {
175-
None => {
176-
build::Call(bcx, callee.immediate(), &llargs[..], Some(attrs), debugloc);
177-
build::Unreachable(bcx);
178-
}
179-
Some(cleanup) => {
184+
match (*cleanup, base::avoid_invoke(bcx)) {
185+
(Some(cleanup), false) => {
186+
let cleanup = self.bcx(cleanup);
180187
let landingpad = self.make_landing_pad(cleanup);
181188
let unreachable = self.unreachable_block();
182189
build::Invoke(bcx,
@@ -187,13 +194,22 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
187194
Some(attrs),
188195
debugloc);
189196
}
197+
(t, _) => {
198+
if t.is_some() {
199+
// make a landing pad regardless, so it sets the personality slot.
200+
let block = self.unreachable_block();
201+
self.make_landing_pad(block);
202+
}
203+
build::Call(bcx, callee.immediate(), &llargs[..], Some(attrs), debugloc);
204+
build::Unreachable(bcx);
205+
}
190206
}
191207
}
192208
}
193209
}
194210

195-
fn make_landing_pad(&mut self, cleanup: mir::BasicBlock) -> Block<'bcx, 'tcx> {
196-
let bcx = self.bcx(cleanup).fcx.new_block(true, "cleanup", None);
211+
fn make_landing_pad(&mut self, cleanup: Block<'bcx, 'tcx>) -> Block<'bcx, 'tcx> {
212+
let bcx = cleanup.fcx.new_block(true, "cleanup", None);
197213
let ccx = bcx.ccx();
198214
let llpersonality = bcx.fcx.eh_personality();
199215
let llretty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)], false);
@@ -208,7 +224,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
208224
build::Store(bcx, llretval, personalityslot)
209225
}
210226
};
211-
build::Br(bcx, self.llblock(cleanup), DebugLoc::None);
227+
build::Br(bcx, cleanup.llbb, DebugLoc::None);
212228
bcx
213229
}
214230

src/librustc_trans/trans/mir/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,10 @@ pub fn trans_mir<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>) {
113113
// Allocate a `Block` for every basic block
114114
let block_bcxs: Vec<Block<'bcx,'tcx>> =
115115
mir_blocks.iter()
116-
.map(|&bb| fcx.new_block(false, &format!("{:?}", bb), None))
116+
.map(|&bb|{
117+
let is_cleanup = mir.basic_block_data(bb).is_cleanup;
118+
fcx.new_block(is_cleanup, &format!("{:?}", bb), None)
119+
})
117120
.collect();
118121

119122
// Branch to the START block

0 commit comments

Comments
 (0)