Don't drop function/call return attributes like 'nounwind'.
[oota-llvm.git] / lib / Transforms / IPO / PruneEH.cpp
index b4bcd995189cbf4de8c503c03a16c133b4674c4a..4fe139a38002d934bab0d2ec79e5f55b5d960a5a 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -25,6 +25,7 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/ParameterAttributes.h"
 #include <set>
 #include <algorithm>
 using namespace llvm;
@@ -74,11 +75,11 @@ bool PruneEH::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
       SCCMightUnwind = true;
       SCCMightReturn = true;
     } else if (F->isDeclaration()) {
-      SCCMightUnwind |= !F->isNoUnwind();
-      SCCMightReturn |= !F->isNoReturn();
+      SCCMightUnwind |= !F->doesNotThrow();
+      SCCMightReturn |= !F->doesNotReturn();
     } else {
-      bool CheckUnwind = !SCCMightUnwind && !F->isNoUnwind();
-      bool CheckReturn = !SCCMightReturn && !F->isNoReturn();
+      bool CheckUnwind = !SCCMightUnwind && !F->doesNotThrow();
+      bool CheckReturn = !SCCMightReturn && !F->doesNotReturn();
 
       if (!CheckUnwind && !CheckReturn)
         continue;
@@ -98,7 +99,7 @@ bool PruneEH::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
         if (CheckUnwind && !SCCMightUnwind)
           for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
             if (CallInst *CI = dyn_cast<CallInst>(I)) {
-              if (CI->isNoUnwind()) {
+              if (CI->doesNotThrow()) {
                 // This call cannot throw.
               } else if (Function *Callee = CI->getCalledFunction()) {
                 CallGraphNode *CalleeNode = CG[Callee];
@@ -122,17 +123,15 @@ bool PruneEH::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
   // If the SCC doesn't unwind or doesn't throw, note this fact.
   if (!SCCMightUnwind || !SCCMightReturn)
     for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
-      const ParamAttrsList *PAL = SCC[i]->getFunction()->getParamAttrs();
-      uint16_t RAttributes = PAL ? PAL->getParamAttrs(0) : 0;
+      uint16_t NewAttributes = ParamAttr::None;
 
       if (!SCCMightUnwind)
-        RAttributes |= ParamAttr::NoUnwind;
+        NewAttributes |= ParamAttr::NoUnwind;
       if (!SCCMightReturn)
-        RAttributes |= ParamAttr::NoReturn;
+        NewAttributes |= ParamAttr::NoReturn;
 
-      ParamAttrsVector modVec;
-      modVec.push_back(ParamAttrsWithIndex::get(0, RAttributes));
-      PAL = ParamAttrsList::getModified(PAL, modVec);
+      const ParamAttrsList *PAL = SCC[i]->getFunction()->getParamAttrs();
+      PAL = ParamAttrsList::includeAttrs(PAL, 0, NewAttributes);
       SCC[i]->getFunction()->setParamAttrs(PAL);
     }
 
@@ -155,7 +154,7 @@ bool PruneEH::SimplifyFunction(Function *F) {
   bool MadeChange = false;
   for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
     if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
-      if (II->isNoUnwind()) {
+      if (II->doesNotThrow()) {
         SmallVector<Value*, 8> Args(II->op_begin()+3, II->op_end());
         // Insert a call instruction before the invoke.
         CallInst *Call = new CallInst(II->getCalledValue(),
@@ -187,7 +186,7 @@ bool PruneEH::SimplifyFunction(Function *F) {
 
     for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
       if (CallInst *CI = dyn_cast<CallInst>(I++))
-        if (CI->isNoReturn() && !isa<UnreachableInst>(I)) {
+        if (CI->doesNotReturn() && !isa<UnreachableInst>(I)) {
           // This call calls a function that cannot return.  Insert an
           // unreachable instruction after it and simplify the code.  Do this
           // by splitting the BB, adding the unreachable, then deleting the