about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/back/lto.rs6
-rw-r--r--src/librustc/driver/session.rs3
-rw-r--r--src/librustc/lib/llvm.rs1
-rw-r--r--src/librustc/middle/trans/base.rs5
-rw-r--r--src/librustc/middle/trans/glue.rs4
-rw-r--r--src/rustllvm/PassWrapper.cpp21
6 files changed, 34 insertions, 6 deletions
diff --git a/src/librustc/back/lto.rs b/src/librustc/back/lto.rs
index 7c8c6aabd7e..3efaa387358 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 c6a6f7b5e90..00f39138f58 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -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 {
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index 7039eced976..5b6c0c2b865 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 d6fc48b52ea..045330835dc 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 3e3ba06538b..2a27a7cee3c 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 76e24faebd9..4ac341a12e4 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<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();
+                }
+            }
+        }
+    }
+}