Skip to content

Commit 378897a

Browse files
committed
auto merge of #10916 : alexcrichton/rust/nounwind, r=pcwalton
When performing LTO, the rust compiler has an opportunity to completely strip all landing pads in all dependent libraries. I've modified the LTO pass to recognize the -Z no-landing-pads option when also running an LTO pass to flag everything in LLVM as nothrow. I've verified that this prevents any and all invoke instructions from being emitted. I believe that this is one of our best options for moving forward with accomodating use-cases where unwinding doesn't really make sense. This will allow libraries to be built with landing pads by default but allow usage of them in contexts where landing pads aren't necessary.
2 parents ae3078c + 667d114 commit 378897a

File tree

6 files changed

+34
-6
lines changed

6 files changed

+34
-6
lines changed

Diff for: src/librustc/back/lto.rs

+6
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ pub fn run(sess: session::Session, llmod: ModuleRef,
6868
arr.len() as libc::size_t);
6969
}
7070

71+
if sess.no_landing_pads() {
72+
unsafe {
73+
llvm::LLVMRustMarkAllFunctionsNounwind(llmod);
74+
}
75+
}
76+
7177
// Now we have one massive module inside of llmod. Time to run the
7278
// LTO-specific optimization passes that LLVM provides.
7379
//

Diff for: src/librustc/driver/session.rs

+3
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ impl Session_ {
347347
pub fn lto(&self) -> bool {
348348
self.debugging_opt(lto)
349349
}
350+
pub fn no_landing_pads(&self) -> bool {
351+
self.debugging_opt(no_landing_pads)
352+
}
350353

351354
// pointless function, now...
352355
pub fn str_of(&self, id: ast::Ident) -> @str {

Diff for: src/librustc/lib/llvm.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,7 @@ pub mod llvm {
17471747
pub fn LLVMRustRunRestrictionPass(M: ModuleRef,
17481748
syms: **c_char,
17491749
len: size_t);
1750+
pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
17501751
}
17511752
}
17521753

Diff for: src/librustc/middle/trans/base.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ pub fn invoke(bcx: @mut Block, llfn: ValueRef, llargs: ~[ValueRef],
915915
}
916916

917917
pub fn need_invoke(bcx: @mut Block) -> bool {
918-
if (bcx.ccx().sess.opts.debugging_opts & session::no_landing_pads != 0) {
918+
if bcx.ccx().sess.no_landing_pads() {
919919
return false;
920920
}
921921

@@ -1254,8 +1254,7 @@ pub fn trans_block_cleanups_(bcx: @mut Block,
12541254
let _icx = push_ctxt("trans_block_cleanups");
12551255
// NB: Don't short-circuit even if this block is unreachable because
12561256
// GC-based cleanup needs to the see that the roots are live.
1257-
let no_lpads =
1258-
bcx.ccx().sess.opts.debugging_opts & session::no_landing_pads != 0;
1257+
let no_lpads = bcx.ccx().sess.no_landing_pads();
12591258
if bcx.unreachable && !no_lpads { return bcx; }
12601259
let mut bcx = bcx;
12611260
for cu in cleanups.rev_iter() {

Diff for: src/librustc/middle/trans/glue.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
use back::abi;
1717
use back::link::*;
18-
use driver::session;
1918
use lib;
2019
use lib::llvm::{llvm, ValueRef, True};
2120
use middle::lang_items::{FreeFnLangItem, ExchangeFreeFnLangItem};
@@ -274,8 +273,7 @@ pub fn call_tydesc_glue_full(bcx: @mut Block,
274273
let ccx = bcx.ccx();
275274
// NB: Don't short-circuit even if this block is unreachable because
276275
// GC-based cleanup needs to the see that the roots are live.
277-
let no_lpads = ccx.sess.opts.debugging_opts & session::no_landing_pads != 0;
278-
if bcx.unreachable && !no_lpads { return; }
276+
if bcx.unreachable && !ccx.sess.no_landing_pads() { return; }
279277

280278
let static_glue_fn = match static_ti {
281279
None => None,

Diff for: src/rustllvm/PassWrapper.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,24 @@ LLVMRustRunRestrictionPass(LLVMModuleRef M, char **symbols, size_t len) {
219219
passes.add(llvm::createInternalizePass(ref));
220220
passes.run(*unwrap(M));
221221
}
222+
223+
extern "C" void
224+
LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
225+
for (Module::iterator GV = unwrap(M)->begin(),
226+
E = unwrap(M)->end(); GV != E; ++GV) {
227+
GV->setDoesNotThrow();
228+
Function *F = dyn_cast<Function>(GV);
229+
if (F == NULL)
230+
continue;
231+
232+
for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
233+
for (BasicBlock::iterator I = B->begin(), IE = B->end();
234+
I != IE; ++I) {
235+
if (isa<InvokeInst>(I)) {
236+
InvokeInst *CI = cast<InvokeInst>(I);
237+
CI->setDoesNotThrow();
238+
}
239+
}
240+
}
241+
}
242+
}

0 commit comments

Comments
 (0)