diff --git a/src/librustc/back/lto.rs b/src/librustc/back/lto.rs index 7c8c6aabd7eab..3efaa387358d0 100644 --- a/src/librustc/back/lto.rs +++ b/src/librustc/back/lto.rs @@ -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. // diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 30d5b7780cf92..79c939f6b7e78 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -348,6 +348,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 { diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 7039eced9769f..5b6c0c2b86586 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1747,6 +1747,7 @@ pub mod llvm { pub fn LLVMRustRunRestrictionPass(M: ModuleRef, syms: **c_char, len: size_t); + pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef); } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index b95f4affc847e..f3eb51a9f46f0 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -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; } @@ -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() { diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index b7c518109963b..3c0ffac7b4dbe 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -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}; @@ -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, diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 76e24faebd93b..4ac341a12e42a 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -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(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(I)) { + InvokeInst *CI = cast(I); + CI->setDoesNotThrow(); + } + } + } + } +}