about summary refs log tree commit diff
path: root/src/rustllvm/PassWrapper.cpp
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-12-10 23:27:15 -0800
committerAlex Crichton <alex@alexcrichton.com>2013-12-11 09:18:20 -0800
commit667d114f47ae658894c496dbf07a8d29c737c877 (patch)
tree98293d03e7862f8e3283937777ccdd7e5b0464e9 /src/rustllvm/PassWrapper.cpp
parentb8b16ae0996074861693f0f76d5d937fafe6a37e (diff)
downloadrust-667d114f47ae658894c496dbf07a8d29c737c877.tar.gz
rust-667d114f47ae658894c496dbf07a8d29c737c877.zip
Disable all unwinding on -Z no-landing-pads LTO
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.

cc #10780
Diffstat (limited to 'src/rustllvm/PassWrapper.cpp')
-rw-r--r--src/rustllvm/PassWrapper.cpp21
1 files changed, 21 insertions, 0 deletions
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();
+                }
+            }
+        }
+    }
+}