Skip to content

Commit

Permalink
auto merge of #10916 : alexcrichton/rust/nounwind, r=pcwalton
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Dec 13, 2013
2 parents ae3078c + 667d114 commit 378897a
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 6 deletions.
6 changes: 6 additions & 0 deletions src/librustc/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ pub fn run(sess: session::Session, llmod: ModuleRef,
arr.len() as libc::size_t);
}

if sess.no_landing_pads() {
unsafe {
llvm::LLVMRustMarkAllFunctionsNounwind(llmod);
}
}

// Now we have one massive module inside of llmod. Time to run the
// LTO-specific optimization passes that LLVM provides.
//
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/driver/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ impl Session_ {
pub fn lto(&self) -> bool {
self.debugging_opt(lto)
}
pub fn no_landing_pads(&self) -> bool {
self.debugging_opt(no_landing_pads)
}

// pointless function, now...
pub fn str_of(&self, id: ast::Ident) -> @str {
Expand Down
1 change: 1 addition & 0 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,7 @@ pub mod llvm {
pub fn LLVMRustRunRestrictionPass(M: ModuleRef,
syms: **c_char,
len: size_t);
pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ pub fn invoke(bcx: @mut Block, llfn: ValueRef, llargs: ~[ValueRef],
}

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

Expand Down Expand Up @@ -1254,8 +1254,7 @@ pub fn trans_block_cleanups_(bcx: @mut Block,
let _icx = push_ctxt("trans_block_cleanups");
// NB: Don't short-circuit even if this block is unreachable because
// GC-based cleanup needs to the see that the roots are live.
let no_lpads =
bcx.ccx().sess.opts.debugging_opts & session::no_landing_pads != 0;
let no_lpads = bcx.ccx().sess.no_landing_pads();
if bcx.unreachable && !no_lpads { return bcx; }
let mut bcx = bcx;
for cu in cleanups.rev_iter() {
Expand Down
4 changes: 1 addition & 3 deletions src/librustc/middle/trans/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

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

let static_glue_fn = match static_ti {
None => None,
Expand Down
21 changes: 21 additions & 0 deletions src/rustllvm/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,24 @@ LLVMRustRunRestrictionPass(LLVMModuleRef M, char **symbols, size_t len) {
passes.add(llvm::createInternalizePass(ref));
passes.run(*unwrap(M));
}

extern "C" void
LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
for (Module::iterator GV = unwrap(M)->begin(),
E = unwrap(M)->end(); GV != E; ++GV) {
GV->setDoesNotThrow();
Function *F = dyn_cast<Function>(GV);
if (F == NULL)
continue;

for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
for (BasicBlock::iterator I = B->begin(), IE = B->end();
I != IE; ++I) {
if (isa<InvokeInst>(I)) {
InvokeInst *CI = cast<InvokeInst>(I);
CI->setDoesNotThrow();
}
}
}
}
}

0 comments on commit 378897a

Please sign in to comment.