Adding ability to demote phi to stack.
authorTanya Lattner <tonic@nondot.org>
Wed, 11 Jul 2007 18:41:34 +0000 (18:41 +0000)
committerTanya Lattner <tonic@nondot.org>
Wed, 11 Jul 2007 18:41:34 +0000 (18:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@39744 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Utils/Local.h
lib/Transforms/Utils/DemoteRegToStack.cpp

index 350f20d8ff6aa71b8d63c28195ffa6d1f659c4b7..c2b95dbdf7b4f5d4b67b0c6635fe0ed83539e03f 100644 (file)
@@ -80,6 +80,11 @@ bool SimplifyCFG(BasicBlock *BB);
 ///
 AllocaInst *DemoteRegToStack(Instruction &X, bool VolatileLoads = false);
 
+/// DemotePHIToStack - This function takes a virtual register computed by a phi
+/// node and replaces it with a slot in the stack frame, allocated via alloca.
+/// The phi node is deleted and it returns the pointer to the alloca inserted. 
+AllocaInst *DemotePHIToStack(PHINode *P);
+
 } // End llvm namespace
 
 #endif
index 3eadfa7694af64f46ccc84bfcf1f450a2fbbc3de..df332b289d0d4aa4a2c97f46c65d40963fdc3272 100644 (file)
@@ -93,3 +93,41 @@ AllocaInst* llvm::DemoteRegToStack(Instruction &I, bool VolatileLoads) {
 
   return Slot;
 }
+
+
+/// DemotePHIToStack - This function takes a virtual register computed by a phi
+/// node and replaces it with a slot in the stack frame, allocated via alloca.
+/// The phi node is deleted and it returns the pointer to the alloca inserted.
+AllocaInst* llvm::DemotePHIToStack(PHINode *P) {
+  if (P->use_empty()) {
+    P->eraseFromParent();    
+    return 0;                
+  }
+  
+  // Create a stack slot to hold the value.
+  Function *F = P->getParent()->getParent();
+  AllocaInst *Slot = new AllocaInst(P->getType(), 0, P->getName(),
+                                    F->getEntryBlock().begin());
+  
+  // Iterate over each operand, insert store in each predecessor.
+  for (unsigned i = 0, e = P->getNumIncomingValues(); i < e; ++i) {
+    if (InvokeInst *II = dyn_cast<InvokeInst>(P->getIncomingValue(i))) {
+      assert(II->getParent() != P->getIncomingBlock(i) && 
+             "Invoke edge not supported yet");
+    }
+    new StoreInst(P->getIncomingValue(i), Slot, 
+                  P->getIncomingBlock(i)->getTerminator());
+  }
+  
+  // Insert load in place of the phi and replace all uses.
+  BasicBlock::iterator InsertPt;
+  for (InsertPt = P->getParent()->getInstList().begin(); 
+       isa<PHINode>(InsertPt); ++InsertPt);
+  Value *V = new LoadInst(Slot, P->getName()+".reload", P);
+  P->replaceAllUsesWith(V);
+  
+  // Delete phi.
+  P->eraseFromParent();
+  
+  return Slot;
+}