Add support for variable argument functions!
[oota-llvm.git] / lib / Transforms / Scalar / ADCE.cpp
index 062b52ff50c0e090e688854084d937fc684596a4..f7a68e48f8cfe46a716c0dc77a2e88ab609a1e06 100644 (file)
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Type.h"
-#include "llvm/Analysis/Dominators.h"
+#include "llvm/Analysis/PostDominators.h"
 #include "llvm/iTerminators.h"
 #include "llvm/iPHINode.h"
 #include "llvm/Constant.h"
 #include "llvm/Support/CFG.h"
 #include "Support/STLExtras.h"
 #include "Support/DepthFirstIterator.h"
-#include "Support/StatisticReporter.h"
+#include "Support/Statistic.h"
 #include <algorithm>
-#include <iostream>
 using std::cerr;
 using std::vector;
 
-static Statistic<> NumBlockRemoved("adce\t\t- Number of basic blocks removed");
-static Statistic<> NumInstRemoved ("adce\t\t- Number of instructions removed");
-
 namespace {
+  Statistic<> NumBlockRemoved("adce", "Number of basic blocks removed");
+  Statistic<> NumInstRemoved ("adce", "Number of instructions removed");
 
 //===----------------------------------------------------------------------===//
 // ADCE Class
@@ -121,7 +119,7 @@ bool ADCE::dropReferencesOfDeadInstructionsInLiveBlock(BasicBlock *BB) {
   for (BasicBlock::iterator I = BB->begin(), E = --BB->end(); I != E; )
     if (!LiveSet.count(I)) {              // Is this instruction alive?
       I->dropAllReferences();             // Nope, drop references... 
-      if (PHINode *PN = dyn_cast<PHINode>(&*I)) {
+      if (PHINode *PN = dyn_cast<PHINode>(I)) {
         // We don't want to leave PHI nodes in the program that have
         // #arguments != #predecessors, so we remove them now.
         //
@@ -156,7 +154,7 @@ bool ADCE::doADCE() {
        BBI != BBE; ++BBI) {
     BasicBlock *BB = *BBI;
     for (BasicBlock::iterator II = BB->begin(), EI = BB->end(); II != EI; ) {
-      if (II->hasSideEffects() || II->getOpcode() == Instruction::Ret) {
+      if (II->mayWriteToMemory() || II->getOpcode() == Instruction::Ret) {
        markInstructionLive(II);
         ++II;  // Increment the inst iterator if the inst wasn't deleted
       } else if (isInstructionTriviallyDead(II)) {
@@ -235,11 +233,15 @@ bool ADCE::doADCE() {
       dropReferencesOfDeadInstructionsInLiveBlock(I);
     
   } else {                                   // If there are some blocks dead...
-    // Insert a new entry node to eliminate the entry node as a special case.
-    BasicBlock *NewEntry = new BasicBlock();
-    NewEntry->getInstList().push_back(new BranchInst(&Func->front()));
-    Func->getBasicBlockList().push_front(NewEntry);
-    AliveBlocks.insert(NewEntry);    // This block is always alive!
+    // If the entry node is dead, insert a new entry node to eliminate the entry
+    // node as a special case.
+    //
+    if (!AliveBlocks.count(&Func->front())) {
+      BasicBlock *NewEntry = new BasicBlock();
+      NewEntry->getInstList().push_back(new BranchInst(&Func->front()));
+      Func->getBasicBlockList().push_front(NewEntry);
+      AliveBlocks.insert(NewEntry);    // This block is always alive!
+    }
     
     // Loop over all of the alive blocks in the function.  If any successor
     // blocks are not alive, we adjust the outgoing branches to branch to the
@@ -308,15 +310,16 @@ bool ADCE::doADCE() {
               // should be identical to the incoming values for LastDead.
               //
               for (BasicBlock::iterator II = NextAlive->begin();
-                   PHINode *PN = dyn_cast<PHINode>(&*II); ++II) {
-                // Get the incoming value for LastDead...
-                int OldIdx = PN->getBasicBlockIndex(LastDead);
-                assert(OldIdx != -1 && "LastDead is not a pred of NextAlive!");
-                Value *InVal = PN->getIncomingValue(OldIdx);
-                
-                // Add an incoming value for BB now...
-                PN->addIncoming(InVal, BB);
-              }
+                   PHINode *PN = dyn_cast<PHINode>(II); ++II)
+                if (LiveSet.count(PN)) {  // Only modify live phi nodes
+                  // Get the incoming value for LastDead...
+                  int OldIdx = PN->getBasicBlockIndex(LastDead);
+                  assert(OldIdx != -1 &&"LastDead is not a pred of NextAlive!");
+                  Value *InVal = PN->getIncomingValue(OldIdx);
+                  
+                  // Add an incoming value for BB now...
+                  PN->addIncoming(InVal, BB);
+                }
             }
           }
 
@@ -329,10 +332,17 @@ bool ADCE::doADCE() {
       }
   }
 
-  // Loop over all of the basic blocks in the function, dropping references of
-  // the dead basic blocks
+  // We make changes if there are any dead blocks in the function...
+  if (unsigned NumDeadBlocks = Func->size() - AliveBlocks.size()) {
+    MadeChanges = true;
+    NumBlockRemoved += NumDeadBlocks;
+  }
+
+  // Loop over all of the basic blocks in the function, removing control flow
+  // edges to live blocks (also eliminating any entries in PHI functions in
+  // referenced blocks).
   //
-  for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB) {
+  for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB)
     if (!AliveBlocks.count(BB)) {
       // Remove all outgoing edges from this basic block and convert the
       // terminator into a return instruction.
@@ -349,16 +359,19 @@ bool ADCE::doADCE() {
         // Delete the old terminator instruction...
         BB->getInstList().pop_back();
         const Type *RetTy = Func->getReturnType();
-        Instruction *New = new ReturnInst(RetTy != Type::VoidTy ?
-                                          Constant::getNullValue(RetTy) : 0);
-        BB->getInstList().push_back(New);
+        BB->getInstList().push_back(new ReturnInst(RetTy != Type::VoidTy ?
+                                           Constant::getNullValue(RetTy) : 0));
       }
+    }
+
 
+  // Loop over all of the basic blocks in the function, dropping references of
+  // the dead basic blocks.  We must do this after the previous step to avoid
+  // dropping references to PHIs which still have entries...
+  //
+  for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB)
+    if (!AliveBlocks.count(BB))
       BB->dropAllReferences();
-      ++NumBlockRemoved;
-      MadeChanges = true;
-    }
-  }
 
   // Now loop through all of the blocks and delete the dead ones.  We can safely
   // do this now because we know that there are no references to dead blocks