Do a very simple pass over every function we emit to infer whether we can
mark it nounwind based on whether it contains any non-nounwind calls.
<rdar://problem/8087431>



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110163 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 396ab4e..35664af 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -311,6 +311,19 @@
   EmitStmt(FD->getBody());
 }
 
+/// Tries to mark the given function nounwind based on the
+/// non-existence of any throwing calls within it.  We believe this is
+/// lightweight enough to do at -O0.
+static void TryMarkNoThrow(llvm::Function *F) {
+  for (llvm::Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
+    for (llvm::BasicBlock::iterator
+           BI = FI->begin(), BE = FI->end(); BI != BE; ++BI)
+      if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(&*BI))
+        if (!Call->doesNotThrow())
+          return;
+  F->setDoesNotThrow(true);
+}
+
 void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) {
   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
   
@@ -369,6 +382,11 @@
 
   // Emit the standard function epilogue.
   FinishFunction(BodyRange.getEnd());
+
+  // If we haven't marked the function nothrow through other means, do
+  // a quick pass now to see if we can.
+  if (!CurFn->doesNotThrow())
+    TryMarkNoThrow(CurFn);
 }
 
 /// ContainsLabel - Return true if the statement contains a label in it.  If