Do a simple instcombine xforms to delete llvm.stackrestore cases.
authorChris Lattner <sabre@nondot.org>
Fri, 13 Jan 2006 21:28:09 +0000 (21:28 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 13 Jan 2006 21:28:09 +0000 (21:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25294 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index b326220499d109e0de2060664bb0cb754920f790..cbfb81bf05ac5a6f7b3144845c58e1a3e8b8c03e 100644 (file)
@@ -4671,6 +4671,39 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
         SPI->replaceAllUsesWith(PrevSPI);
         return EraseInstFromFunction(CI);
       }
+  } else {
+    switch (II->getIntrinsicID()) {
+    default: break;
+    case Intrinsic::stackrestore: {
+      // If the save is right next to the restore, remove the restore.  This can
+      // happen when variable allocas are DCE'd.
+      if (IntrinsicInst *SS = dyn_cast<IntrinsicInst>(II->getOperand(1))) {
+        if (SS->getIntrinsicID() == Intrinsic::stacksave) {
+          BasicBlock::iterator BI = SS;
+          if (&*++BI == II)
+            return EraseInstFromFunction(CI);
+        }
+      }
+      
+      // If the stack restore is in a return/unwind block and if there are no
+      // allocas or calls between the restore and the return, nuke the restore.
+      TerminatorInst *TI = II->getParent()->getTerminator();
+      if (isa<ReturnInst>(TI) || isa<UnwindInst>(TI)) {
+        BasicBlock::iterator BI = II;
+        bool CannotRemove = false;
+        for (++BI; &*BI != TI; ++BI) {
+          if (isa<AllocaInst>(BI) ||
+              (isa<CallInst>(BI) && !isa<IntrinsicInst>(BI))) {
+            CannotRemove = true;
+            break;
+          }
+        }
+        if (!CannotRemove)
+          return EraseInstFromFunction(CI);
+      }
+      break;
+    }
+    }
   }
 
   return visitCallSite(II);