[llvm-branch-commits] [llvm-branch] r110151 - in /llvm/branches/Apple/Pertwee: include/llvm/CodeGen/MachineSSAUpdater.h include/llvm/Transforms/Utils/SSAUpdater.h include/llvm/Transforms/Utils/SSAUpdaterImpl.h lib/CodeGen/MachineSSAUpdater.cpp lib/Transforms/Utils/SSAUpdater.cpp test/Transforms/GVN/2010-03-31-RedundantPHIs.ll

Bob Wilson bob.wilson at apple.com
Tue Aug 3 14:28:51 PDT 2010


Author: bwilson
Date: Tue Aug  3 16:28:51 2010
New Revision: 110151

URL: http://llvm.org/viewvc/llvm-project?rev=110151&view=rev
Log:
Re-revert the SSA Updater changes.  I was wrong -- the performance regression
is still an issue.

--- Reverse-merging r110138 into '.':
D    test/Transforms/GVN/2010-03-31-RedundantPHIs.ll
U    include/llvm/Transforms/Utils/SSAUpdater.h
D    include/llvm/Transforms/Utils/SSAUpdaterImpl.h
U    include/llvm/CodeGen/MachineSSAUpdater.h
U    lib/CodeGen/MachineSSAUpdater.cpp
U    lib/Transforms/Utils/SSAUpdater.cpp

Removed:
    llvm/branches/Apple/Pertwee/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
    llvm/branches/Apple/Pertwee/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll
Modified:
    llvm/branches/Apple/Pertwee/include/llvm/CodeGen/MachineSSAUpdater.h
    llvm/branches/Apple/Pertwee/include/llvm/Transforms/Utils/SSAUpdater.h
    llvm/branches/Apple/Pertwee/lib/CodeGen/MachineSSAUpdater.cpp
    llvm/branches/Apple/Pertwee/lib/Transforms/Utils/SSAUpdater.cpp

Modified: llvm/branches/Apple/Pertwee/include/llvm/CodeGen/MachineSSAUpdater.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Pertwee/include/llvm/CodeGen/MachineSSAUpdater.h?rev=110151&r1=110150&r2=110151&view=diff
==============================================================================
--- llvm/branches/Apple/Pertwee/include/llvm/CodeGen/MachineSSAUpdater.h (original)
+++ llvm/branches/Apple/Pertwee/include/llvm/CodeGen/MachineSSAUpdater.h Tue Aug  3 16:28:51 2010
@@ -23,22 +23,23 @@
   class TargetInstrInfo;
   class TargetRegisterClass;
   template<typename T> class SmallVectorImpl;
-  template<typename T> class SSAUpdaterTraits;
-  class BumpPtrAllocator;
 
 /// MachineSSAUpdater - This class updates SSA form for a set of virtual
 /// registers defined in multiple blocks.  This is used when code duplication
 /// or another unstructured transformation wants to rewrite a set of uses of one
 /// vreg with uses of a set of vregs.
 class MachineSSAUpdater {
-  friend class SSAUpdaterTraits<MachineSSAUpdater>;
-
-private:
   /// AvailableVals - This keeps track of which value to use on a per-block
   /// basis.  When we insert PHI nodes, we keep track of them here.
   //typedef DenseMap<MachineBasicBlock*, unsigned > AvailableValsTy;
   void *AV;
 
+  /// IncomingPredInfo - We use this as scratch space when doing our recursive
+  /// walk.  This should only be used in GetValueInBlockInternal, normally it
+  /// should be empty.
+  //std::vector<std::pair<MachineBasicBlock*, unsigned > > IncomingPredInfo;
+  void *IPI;
+
   /// VR - Current virtual register whose uses are being updated.
   unsigned VR;
 
@@ -105,7 +106,6 @@
 private:
   void ReplaceRegWith(unsigned OldReg, unsigned NewReg);
   unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB);
-
   void operator=(const MachineSSAUpdater&); // DO NOT IMPLEMENT
   MachineSSAUpdater(const MachineSSAUpdater&);     // DO NOT IMPLEMENT
 };

Modified: llvm/branches/Apple/Pertwee/include/llvm/Transforms/Utils/SSAUpdater.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Pertwee/include/llvm/Transforms/Utils/SSAUpdater.h?rev=110151&r1=110150&r2=110151&view=diff
==============================================================================
--- llvm/branches/Apple/Pertwee/include/llvm/Transforms/Utils/SSAUpdater.h (original)
+++ llvm/branches/Apple/Pertwee/include/llvm/Transforms/Utils/SSAUpdater.h Tue Aug  3 16:28:51 2010
@@ -19,31 +19,34 @@
   class BasicBlock;
   class Use;
   class PHINode;
-  template<typename T> class SmallVectorImpl;
-  template<typename T> class SSAUpdaterTraits;
-  class BumpPtrAllocator;
+  template<typename T>
+  class SmallVectorImpl;
 
 /// SSAUpdater - This class updates SSA form for a set of values defined in
 /// multiple blocks.  This is used when code duplication or another unstructured
 /// transformation wants to rewrite a set of uses of one value with uses of a
 /// set of values.
 class SSAUpdater {
-  friend class SSAUpdaterTraits<SSAUpdater>;
-
-private:
   /// AvailableVals - This keeps track of which value to use on a per-block
-  /// basis.  When we insert PHI nodes, we keep track of them here.
-  //typedef DenseMap<BasicBlock*, Value*> AvailableValsTy;
+  /// basis.  When we insert PHI nodes, we keep track of them here.  We use
+  /// TrackingVH's for the value of the map because we RAUW PHI nodes when we
+  /// eliminate them, and want the TrackingVH's to track this.
+  //typedef DenseMap<BasicBlock*, TrackingVH<Value> > AvailableValsTy;
   void *AV;
 
   /// PrototypeValue is an arbitrary representative value, which we derive names
   /// and a type for PHI nodes.
   Value *PrototypeValue;
 
+  /// IncomingPredInfo - We use this as scratch space when doing our recursive
+  /// walk.  This should only be used in GetValueInBlockInternal, normally it
+  /// should be empty.
+  //std::vector<std::pair<BasicBlock*, TrackingVH<Value> > > IncomingPredInfo;
+  void *IPI;
+
   /// InsertedPHIs - If this is non-null, the SSAUpdater adds all PHI nodes that
   /// it creates to the vector.
   SmallVectorImpl<PHINode*> *InsertedPHIs;
-
 public:
   /// SSAUpdater constructor.  If InsertedPHIs is specified, it will be filled
   /// in with all PHI Nodes created by rewriting.
@@ -96,7 +99,6 @@
 
 private:
   Value *GetValueAtEndOfBlockInternal(BasicBlock *BB);
-
   void operator=(const SSAUpdater&); // DO NOT IMPLEMENT
   SSAUpdater(const SSAUpdater&);     // DO NOT IMPLEMENT
 };

Removed: llvm/branches/Apple/Pertwee/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Pertwee/include/llvm/Transforms/Utils/SSAUpdaterImpl.h?rev=110150&view=auto
==============================================================================
--- llvm/branches/Apple/Pertwee/include/llvm/Transforms/Utils/SSAUpdaterImpl.h (original)
+++ llvm/branches/Apple/Pertwee/include/llvm/Transforms/Utils/SSAUpdaterImpl.h (removed)
@@ -1,469 +0,0 @@
-//===-- SSAUpdaterImpl.h - SSA Updater Implementation -----------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides a template that implements the core algorithm for the
-// SSAUpdater and MachineSSAUpdater.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
-#define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
-
-namespace llvm {
-
-template<typename T> class SSAUpdaterTraits;
-
-template<typename UpdaterT>
-class SSAUpdaterImpl {
-private:
-  UpdaterT *Updater;
-
-  typedef SSAUpdaterTraits<UpdaterT> Traits;
-  typedef typename Traits::BlkT BlkT;
-  typedef typename Traits::ValT ValT;
-  typedef typename Traits::PhiT PhiT;
-
-  /// BBInfo - Per-basic block information used internally by SSAUpdaterImpl.
-  /// The predecessors of each block are cached here since pred_iterator is
-  /// slow and we need to iterate over the blocks at least a few times.
-  class BBInfo {
-  public:
-    BlkT *BB;          // Back-pointer to the corresponding block.
-    ValT AvailableVal; // Value to use in this block.
-    BBInfo *DefBB;     // Block that defines the available value.
-    int BlkNum;        // Postorder number.
-    BBInfo *IDom;      // Immediate dominator.
-    unsigned NumPreds; // Number of predecessor blocks.
-    BBInfo **Preds;    // Array[NumPreds] of predecessor blocks.
-    PhiT *PHITag;      // Marker for existing PHIs that match.
-
-    BBInfo(BlkT *ThisBB, ValT V)
-      : BB(ThisBB), AvailableVal(V), DefBB(V ? this : 0), BlkNum(0), IDom(0),
-      NumPreds(0), Preds(0), PHITag(0) { }
-  };
-
-  typedef DenseMap<BlkT*, ValT> AvailableValsTy;
-  AvailableValsTy *AvailableVals;
-
-  SmallVectorImpl<PhiT*> *InsertedPHIs;
-
-  typedef SmallVectorImpl<BBInfo*> BlockListTy;
-  typedef DenseMap<BlkT*, BBInfo*> BBMapTy;
-  BBMapTy BBMap;
-  BumpPtrAllocator Allocator;
-
-public:
-  explicit SSAUpdaterImpl(UpdaterT *U, AvailableValsTy *A,
-                          SmallVectorImpl<PhiT*> *Ins) :
-    Updater(U), AvailableVals(A), InsertedPHIs(Ins) { }
-
-  /// GetValue - Check to see if AvailableVals has an entry for the specified
-  /// BB and if so, return it.  If not, construct SSA form by first
-  /// calculating the required placement of PHIs and then inserting new PHIs
-  /// where needed.
-  ValT GetValue(BlkT *BB) {
-    SmallVector<BBInfo*, 100> BlockList;
-    BBInfo *PseudoEntry = BuildBlockList(BB, &BlockList);
-
-    // Special case: bail out if BB is unreachable.
-    if (BlockList.size() == 0) {
-      ValT V = Traits::GetUndefVal(BB, Updater);
-      (*AvailableVals)[BB] = V;
-      return V;
-    }
-
-    FindDominators(&BlockList, PseudoEntry);
-    FindPHIPlacement(&BlockList);
-    FindAvailableVals(&BlockList);
-
-    return BBMap[BB]->DefBB->AvailableVal;
-  }
-
-  /// BuildBlockList - Starting from the specified basic block, traverse back
-  /// through its predecessors until reaching blocks with known values.
-  /// Create BBInfo structures for the blocks and append them to the block
-  /// list.
-  BBInfo *BuildBlockList(BlkT *BB, BlockListTy *BlockList) {
-    SmallVector<BBInfo*, 10> RootList;
-    SmallVector<BBInfo*, 64> WorkList;
-
-    BBInfo *Info = new (Allocator) BBInfo(BB, 0);
-    BBMap[BB] = Info;
-    WorkList.push_back(Info);
-
-    // Search backward from BB, creating BBInfos along the way and stopping
-    // when reaching blocks that define the value.  Record those defining
-    // blocks on the RootList.
-    SmallVector<BlkT*, 10> Preds;
-    while (!WorkList.empty()) {
-      Info = WorkList.pop_back_val();
-      Preds.clear();
-      Traits::FindPredecessorBlocks(Info->BB, &Preds);
-      Info->NumPreds = Preds.size();
-      if (Info->NumPreds == 0)
-        Info->Preds = 0;
-      else
-        Info->Preds = static_cast<BBInfo**>
-          (Allocator.Allocate(Info->NumPreds * sizeof(BBInfo*),
-                              AlignOf<BBInfo*>::Alignment));
-
-      for (unsigned p = 0; p != Info->NumPreds; ++p) {
-        BlkT *Pred = Preds[p];
-        // Check if BBMap already has a BBInfo for the predecessor block.
-        typename BBMapTy::value_type &BBMapBucket =
-          BBMap.FindAndConstruct(Pred);
-        if (BBMapBucket.second) {
-          Info->Preds[p] = BBMapBucket.second;
-          continue;
-        }
-
-        // Create a new BBInfo for the predecessor.
-        ValT PredVal = AvailableVals->lookup(Pred);
-        BBInfo *PredInfo = new (Allocator) BBInfo(Pred, PredVal);
-        BBMapBucket.second = PredInfo;
-        Info->Preds[p] = PredInfo;
-
-        if (PredInfo->AvailableVal) {
-          RootList.push_back(PredInfo);
-          continue;
-        }
-        WorkList.push_back(PredInfo);
-      }
-    }
-
-    // Now that we know what blocks are backwards-reachable from the starting
-    // block, do a forward depth-first traversal to assign postorder numbers
-    // to those blocks.
-    BBInfo *PseudoEntry = new (Allocator) BBInfo(0, 0);
-    unsigned BlkNum = 1;
-
-    // Initialize the worklist with the roots from the backward traversal.
-    while (!RootList.empty()) {
-      Info = RootList.pop_back_val();
-      Info->IDom = PseudoEntry;
-      Info->BlkNum = -1;
-      WorkList.push_back(Info);
-    }
-
-    while (!WorkList.empty()) {
-      Info = WorkList.back();
-
-      if (Info->BlkNum == -2) {
-        // All the successors have been handled; assign the postorder number.
-        Info->BlkNum = BlkNum++;
-        // If not a root, put it on the BlockList.
-        if (!Info->AvailableVal)
-          BlockList->push_back(Info);
-        WorkList.pop_back();
-        continue;
-      }
-
-      // Leave this entry on the worklist, but set its BlkNum to mark that its
-      // successors have been put on the worklist.  When it returns to the top
-      // the list, after handling its successors, it will be assigned a
-      // number.
-      Info->BlkNum = -2;
-
-      // Add unvisited successors to the work list.
-      for (typename Traits::BlkSucc_iterator SI =
-             Traits::BlkSucc_begin(Info->BB),
-             E = Traits::BlkSucc_end(Info->BB); SI != E; ++SI) {
-        BBInfo *SuccInfo = BBMap[*SI];
-        if (!SuccInfo || SuccInfo->BlkNum)
-          continue;
-        SuccInfo->BlkNum = -1;
-        WorkList.push_back(SuccInfo);
-      }
-    }
-    PseudoEntry->BlkNum = BlkNum;
-    return PseudoEntry;
-  }
-
-  /// IntersectDominators - This is the dataflow lattice "meet" operation for
-  /// finding dominators.  Given two basic blocks, it walks up the dominator
-  /// tree until it finds a common dominator of both.  It uses the postorder
-  /// number of the blocks to determine how to do that.
-  BBInfo *IntersectDominators(BBInfo *Blk1, BBInfo *Blk2) {
-    while (Blk1 != Blk2) {
-      while (Blk1->BlkNum < Blk2->BlkNum) {
-        Blk1 = Blk1->IDom;
-        if (!Blk1)
-          return Blk2;
-      }
-      while (Blk2->BlkNum < Blk1->BlkNum) {
-        Blk2 = Blk2->IDom;
-        if (!Blk2)
-          return Blk1;
-      }
-    }
-    return Blk1;
-  }
-
-  /// FindDominators - Calculate the dominator tree for the subset of the CFG
-  /// corresponding to the basic blocks on the BlockList.  This uses the
-  /// algorithm from: "A Simple, Fast Dominance Algorithm" by Cooper, Harvey
-  /// and Kennedy, published in Software--Practice and Experience, 2001,
-  /// 4:1-10.  Because the CFG subset does not include any edges leading into
-  /// blocks that define the value, the results are not the usual dominator
-  /// tree.  The CFG subset has a single pseudo-entry node with edges to a set
-  /// of root nodes for blocks that define the value.  The dominators for this
-  /// subset CFG are not the standard dominators but they are adequate for
-  /// placing PHIs within the subset CFG.
-  void FindDominators(BlockListTy *BlockList, BBInfo *PseudoEntry) {
-    bool Changed;
-    do {
-      Changed = false;
-      // Iterate over the list in reverse order, i.e., forward on CFG edges.
-      for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
-             E = BlockList->rend(); I != E; ++I) {
-        BBInfo *Info = *I;
-        BBInfo *NewIDom = 0;
-
-        // Iterate through the block's predecessors.
-        for (unsigned p = 0; p != Info->NumPreds; ++p) {
-          BBInfo *Pred = Info->Preds[p];
-
-          // Treat an unreachable predecessor as a definition with 'undef'.
-          if (Pred->BlkNum == 0) {
-            Pred->AvailableVal = Traits::GetUndefVal(Pred->BB, Updater);
-            (*AvailableVals)[Pred->BB] = Pred->AvailableVal;
-            Pred->DefBB = Pred;
-            Pred->BlkNum = PseudoEntry->BlkNum;
-            PseudoEntry->BlkNum++;
-          }
-
-          if (!NewIDom)
-            NewIDom = Pred;
-          else
-            NewIDom = IntersectDominators(NewIDom, Pred);
-        }
-
-        // Check if the IDom value has changed.
-        if (NewIDom && NewIDom != Info->IDom) {
-          Info->IDom = NewIDom;
-          Changed = true;
-        }
-      }
-    } while (Changed);
-  }
-
-  /// IsDefInDomFrontier - Search up the dominator tree from Pred to IDom for
-  /// any blocks containing definitions of the value.  If one is found, then
-  /// the successor of Pred is in the dominance frontier for the definition,
-  /// and this function returns true.
-  bool IsDefInDomFrontier(const BBInfo *Pred, const BBInfo *IDom) {
-    for (; Pred != IDom; Pred = Pred->IDom) {
-      if (Pred->DefBB == Pred)
-        return true;
-    }
-    return false;
-  }
-
-  /// FindPHIPlacement - PHIs are needed in the iterated dominance frontiers
-  /// of the known definitions.  Iteratively add PHIs in the dom frontiers
-  /// until nothing changes.  Along the way, keep track of the nearest
-  /// dominating definitions for non-PHI blocks.
-  void FindPHIPlacement(BlockListTy *BlockList) {
-    bool Changed;
-    do {
-      Changed = false;
-      // Iterate over the list in reverse order, i.e., forward on CFG edges.
-      for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
-             E = BlockList->rend(); I != E; ++I) {
-        BBInfo *Info = *I;
-
-        // If this block already needs a PHI, there is nothing to do here.
-        if (Info->DefBB == Info)
-          continue;
-
-        // Default to use the same def as the immediate dominator.
-        BBInfo *NewDefBB = Info->IDom->DefBB;
-        for (unsigned p = 0; p != Info->NumPreds; ++p) {
-          if (IsDefInDomFrontier(Info->Preds[p], Info->IDom)) {
-            // Need a PHI here.
-            NewDefBB = Info;
-            break;
-          }
-        }
-
-        // Check if anything changed.
-        if (NewDefBB != Info->DefBB) {
-          Info->DefBB = NewDefBB;
-          Changed = true;
-        }
-      }
-    } while (Changed);
-  }
-
-  /// FindAvailableVal - If this block requires a PHI, first check if an
-  /// existing PHI matches the PHI placement and reaching definitions computed
-  /// earlier, and if not, create a new PHI.  Visit all the block's
-  /// predecessors to calculate the available value for each one and fill in
-  /// the incoming values for a new PHI.
-  void FindAvailableVals(BlockListTy *BlockList) {
-    // Go through the worklist in forward order (i.e., backward through the CFG)
-    // and check if existing PHIs can be used.  If not, create empty PHIs where
-    // they are needed.
-    for (typename BlockListTy::iterator I = BlockList->begin(),
-           E = BlockList->end(); I != E; ++I) {
-      BBInfo *Info = *I;
-      // Check if there needs to be a PHI in BB.
-      if (Info->DefBB != Info)
-        continue;
-
-      // Look for an existing PHI.
-      FindExistingPHI(Info->BB, BlockList);
-      if (Info->AvailableVal)
-        continue;
-
-      ValT PHI = Traits::CreateEmptyPHI(Info->BB, Info->NumPreds, Updater);
-      Info->AvailableVal = PHI;
-      (*AvailableVals)[Info->BB] = PHI;
-    }
-
-    // Now go back through the worklist in reverse order to fill in the
-    // arguments for any new PHIs added in the forward traversal.
-    for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
-           E = BlockList->rend(); I != E; ++I) {
-      BBInfo *Info = *I;
-
-      if (Info->DefBB != Info) {
-        // Record the available value at join nodes to speed up subsequent
-        // uses of this SSAUpdater for the same value.
-        if (Info->NumPreds > 1)
-          (*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
-        continue;
-      }
-
-      // Check if this block contains a newly added PHI.
-      PhiT *PHI = Traits::ValueIsNewPHI(Info->AvailableVal, Updater);
-      if (!PHI)
-        continue;
-
-      // Iterate through the block's predecessors.
-      for (unsigned p = 0; p != Info->NumPreds; ++p) {
-        BBInfo *PredInfo = Info->Preds[p];
-        BlkT *Pred = PredInfo->BB;
-        // Skip to the nearest preceding definition.
-        if (PredInfo->DefBB != PredInfo)
-          PredInfo = PredInfo->DefBB;
-        Traits::AddPHIOperand(PHI, PredInfo->AvailableVal, Pred);
-      }
-
-      DEBUG(dbgs() << "  Inserted PHI: " << *PHI << "\n");
-
-      // If the client wants to know about all new instructions, tell it.
-      if (InsertedPHIs) InsertedPHIs->push_back(PHI);
-    }
-  }
-
-  /// FindExistingPHI - Look through the PHI nodes in a block to see if any of
-  /// them match what is needed.
-  void FindExistingPHI(BlkT *BB, BlockListTy *BlockList) {
-    for (typename BlkT::iterator BBI = BB->begin(), BBE = BB->end();
-         BBI != BBE; ++BBI) {
-      PhiT *SomePHI = Traits::InstrIsPHI(BBI);
-      if (!SomePHI)
-        break;
-      if (CheckIfPHIMatches(SomePHI)) {
-        RecordMatchingPHI(SomePHI);
-        break;
-      }
-      // Match failed: clear all the PHITag values.
-      for (typename BlockListTy::iterator I = BlockList->begin(),
-             E = BlockList->end(); I != E; ++I)
-        (*I)->PHITag = 0;
-    }
-  }
-
-  /// CheckIfPHIMatches - Check if a PHI node matches the placement and values
-  /// in the BBMap.
-  bool CheckIfPHIMatches(PhiT *PHI) {
-    SmallVector<PhiT*, 20> WorkList;
-    WorkList.push_back(PHI);
-
-    // Mark that the block containing this PHI has been visited.
-    BBMap[PHI->getParent()]->PHITag = PHI;
-
-    while (!WorkList.empty()) {
-      PHI = WorkList.pop_back_val();
-
-      // Iterate through the PHI's incoming values.
-      for (typename Traits::PHI_iterator I = Traits::PHI_begin(PHI),
-             E = Traits::PHI_end(PHI); I != E; ++I) {
-        ValT IncomingVal = I.getIncomingValue();
-        BBInfo *PredInfo = BBMap[I.getIncomingBlock()];
-        // Skip to the nearest preceding definition.
-        if (PredInfo->DefBB != PredInfo)
-          PredInfo = PredInfo->DefBB;
-
-        // Check if it matches the expected value.
-        if (PredInfo->AvailableVal) {
-          if (IncomingVal == PredInfo->AvailableVal)
-            continue;
-          return false;
-        }
-
-        // Check if the value is a PHI in the correct block.
-        PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
-        if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
-          return false;
-
-        // If this block has already been visited, check if this PHI matches.
-        if (PredInfo->PHITag) {
-          if (IncomingPHIVal == PredInfo->PHITag)
-            continue;
-          return false;
-        }
-        PredInfo->PHITag = IncomingPHIVal;
-
-        WorkList.push_back(IncomingPHIVal);
-      }
-    }
-    return true;
-  }
-
-  /// RecordMatchingPHI - For a PHI node that matches, record it and its input
-  /// PHIs in both the BBMap and the AvailableVals mapping.
-  void RecordMatchingPHI(PhiT *PHI) {
-    SmallVector<PhiT*, 20> WorkList;
-    WorkList.push_back(PHI);
-
-    // Record this PHI.
-    BlkT *BB = PHI->getParent();
-    ValT PHIVal = Traits::GetPHIValue(PHI);
-    (*AvailableVals)[BB] = PHIVal;
-    BBMap[BB]->AvailableVal = PHIVal;
-
-    while (!WorkList.empty()) {
-      PHI = WorkList.pop_back_val();
-
-      // Iterate through the PHI's incoming values.
-      for (typename Traits::PHI_iterator I = Traits::PHI_begin(PHI),
-             E = Traits::PHI_end(PHI); I != E; ++I) {
-        ValT IncomingVal = I.getIncomingValue();
-        PhiT *IncomingPHI = Traits::ValueIsPHI(IncomingVal, Updater);
-        if (!IncomingPHI) continue;
-        BB = IncomingPHI->getParent();
-        BBInfo *Info = BBMap[BB];
-        if (!Info || Info->AvailableVal)
-          continue;
-
-        // Record the PHI and add it to the worklist.
-        (*AvailableVals)[BB] = IncomingVal;
-        Info->AvailableVal = IncomingVal;
-        WorkList.push_back(IncomingPHI);
-      }
-    }
-  }
-};
-
-} // End llvm namespace
-
-#endif

Modified: llvm/branches/Apple/Pertwee/lib/CodeGen/MachineSSAUpdater.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Pertwee/lib/CodeGen/MachineSSAUpdater.cpp?rev=110151&r1=110150&r2=110151&view=diff
==============================================================================
--- llvm/branches/Apple/Pertwee/lib/CodeGen/MachineSSAUpdater.cpp (original)
+++ llvm/branches/Apple/Pertwee/lib/CodeGen/MachineSSAUpdater.cpp Tue Aug  3 16:28:51 2010
@@ -21,28 +21,34 @@
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/AlignOf.h"
-#include "llvm/Support/Allocator.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Utils/SSAUpdaterImpl.h"
 using namespace llvm;
 
 typedef DenseMap<MachineBasicBlock*, unsigned> AvailableValsTy;
+typedef std::vector<std::pair<MachineBasicBlock*, unsigned> >
+                IncomingPredInfoTy;
+
 static AvailableValsTy &getAvailableVals(void *AV) {
   return *static_cast<AvailableValsTy*>(AV);
 }
 
+static IncomingPredInfoTy &getIncomingPredInfo(void *IPI) {
+  return *static_cast<IncomingPredInfoTy*>(IPI);
+}
+
+
 MachineSSAUpdater::MachineSSAUpdater(MachineFunction &MF,
                                      SmallVectorImpl<MachineInstr*> *NewPHI)
-  : AV(0), InsertedPHIs(NewPHI) {
+  : AV(0), IPI(0), InsertedPHIs(NewPHI) {
   TII = MF.getTarget().getInstrInfo();
   MRI = &MF.getRegInfo();
 }
 
 MachineSSAUpdater::~MachineSSAUpdater() {
   delete &getAvailableVals(AV);
+  delete &getIncomingPredInfo(IPI);
 }
 
 /// Initialize - Reset this object to get ready for a new set of SSA
@@ -53,6 +59,11 @@
   else
     getAvailableVals(AV).clear();
 
+  if (IPI == 0)
+    IPI = new IncomingPredInfoTy();
+  else
+    getIncomingPredInfo(IPI).clear();
+
   VR = V;
   VRC = MRI->getRegClass(VR);
 }
@@ -112,12 +123,11 @@
 MachineInstr *InsertNewDef(unsigned Opcode,
                            MachineBasicBlock *BB, MachineBasicBlock::iterator I,
                            const TargetRegisterClass *RC,
-                           MachineRegisterInfo *MRI,
-                           const TargetInstrInfo *TII) {
+                           MachineRegisterInfo *MRI, const TargetInstrInfo *TII) {
   unsigned NewVR = MRI->createVirtualRegister(RC);
   return BuildMI(*BB, I, DebugLoc(), TII->get(Opcode), NewVR);
 }
-
+                          
 /// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that
 /// is live in the middle of the specified block.
 ///
@@ -140,7 +150,7 @@
 unsigned MachineSSAUpdater::GetValueInMiddleOfBlock(MachineBasicBlock *BB) {
   // If there is no definition of the renamed variable in this block, just use
   // GetValueAtEndOfBlock to do our work.
-  if (!HasValueForBlock(BB))
+  if (!getAvailableVals(AV).count(BB))
     return GetValueAtEndOfBlockInternal(BB);
 
   // If there are no predecessors, just return undef.
@@ -242,131 +252,143 @@
       I->second = NewReg;
 }
 
-/// MachinePHIiter - Iterator for PHI operands.  This is used for the
-/// PHI_iterator in the SSAUpdaterImpl template.
-namespace {
-  class MachinePHIiter {
-  private:
-    MachineInstr *PHI;
-    unsigned idx;
- 
-  public:
-    explicit MachinePHIiter(MachineInstr *P) // begin iterator
-      : PHI(P), idx(1) {}
-    MachinePHIiter(MachineInstr *P, bool) // end iterator
-      : PHI(P), idx(PHI->getNumOperands()) {}
-
-    MachinePHIiter &operator++() { idx += 2; return *this; } 
-    bool operator==(const MachinePHIiter& x) const { return idx == x.idx; }
-    bool operator!=(const MachinePHIiter& x) const { return !operator==(x); }
-    unsigned getIncomingValue() { return PHI->getOperand(idx).getReg(); }
-    MachineBasicBlock *getIncomingBlock() {
-      return PHI->getOperand(idx+1).getMBB();
-    }
-  };
-}
+/// GetValueAtEndOfBlockInternal - Check to see if AvailableVals has an entry
+/// for the specified BB and if so, return it.  If not, construct SSA form by
+/// walking predecessors inserting PHI nodes as needed until we get to a block
+/// where the value is available.
+///
+unsigned MachineSSAUpdater::GetValueAtEndOfBlockInternal(MachineBasicBlock *BB){
+  AvailableValsTy &AvailableVals = getAvailableVals(AV);
 
-/// SSAUpdaterTraits<MachineSSAUpdater> - Traits for the SSAUpdaterImpl
-/// template, specialized for MachineSSAUpdater.
-namespace llvm {
-template<>
-class SSAUpdaterTraits<MachineSSAUpdater> {
-public:
-  typedef MachineBasicBlock BlkT;
-  typedef unsigned ValT;
-  typedef MachineInstr PhiT;
-
-  typedef MachineBasicBlock::succ_iterator BlkSucc_iterator;
-  static BlkSucc_iterator BlkSucc_begin(BlkT *BB) { return BB->succ_begin(); }
-  static BlkSucc_iterator BlkSucc_end(BlkT *BB) { return BB->succ_end(); }
-
-  typedef MachinePHIiter PHI_iterator;
-  static inline PHI_iterator PHI_begin(PhiT *PHI) { return PHI_iterator(PHI); }
-  static inline PHI_iterator PHI_end(PhiT *PHI) {
-    return PHI_iterator(PHI, true);
-  }
-
-  /// FindPredecessorBlocks - Put the predecessors of BB into the Preds
-  /// vector.
-  static void FindPredecessorBlocks(MachineBasicBlock *BB,
-                                    SmallVectorImpl<MachineBasicBlock*> *Preds){
-    for (MachineBasicBlock::pred_iterator PI = BB->pred_begin(),
-           E = BB->pred_end(); PI != E; ++PI)
-      Preds->push_back(*PI);
-  }
-
-  /// GetUndefVal - Create an IMPLICIT_DEF instruction with a new register.
-  /// Add it into the specified block and return the register.
-  static unsigned GetUndefVal(MachineBasicBlock *BB,
-                              MachineSSAUpdater *Updater) {
+  // Query AvailableVals by doing an insertion of null.
+  std::pair<AvailableValsTy::iterator, bool> InsertRes =
+    AvailableVals.insert(std::make_pair(BB, 0));
+
+  // Handle the case when the insertion fails because we have already seen BB.
+  if (!InsertRes.second) {
+    // If the insertion failed, there are two cases.  The first case is that the
+    // value is already available for the specified block.  If we get this, just
+    // return the value.
+    if (InsertRes.first->second != 0)
+      return InsertRes.first->second;
+
+    // Otherwise, if the value we find is null, then this is the value is not
+    // known but it is being computed elsewhere in our recursion.  This means
+    // that we have a cycle.  Handle this by inserting a PHI node and returning
+    // it.  When we get back to the first instance of the recursion we will fill
+    // in the PHI node.
+    MachineBasicBlock::iterator Loc = BB->empty() ? BB->end() : BB->front();
+    MachineInstr *NewPHI = InsertNewDef(TargetOpcode::PHI, BB, Loc,
+                                        VRC, MRI,TII);
+    unsigned NewVR = NewPHI->getOperand(0).getReg();
+    InsertRes.first->second = NewVR;
+    return NewVR;
+  }
+
+  // If there are no predecessors, then we must have found an unreachable block
+  // just return 'undef'.  Since there are no predecessors, InsertRes must not
+  // be invalidated.
+  if (BB->pred_empty()) {
     // Insert an implicit_def to represent an undef value.
     MachineInstr *NewDef = InsertNewDef(TargetOpcode::IMPLICIT_DEF,
                                         BB, BB->getFirstTerminator(),
-                                        Updater->VRC, Updater->MRI,
-                                        Updater->TII);
-    return NewDef->getOperand(0).getReg();
+                                        VRC, MRI, TII);
+    return InsertRes.first->second = NewDef->getOperand(0).getReg();
   }
 
-  /// CreateEmptyPHI - Create a PHI instruction that defines a new register.
-  /// Add it into the specified block and return the register.
-  static unsigned CreateEmptyPHI(MachineBasicBlock *BB, unsigned NumPreds,
-                                 MachineSSAUpdater *Updater) {
-    MachineBasicBlock::iterator Loc = BB->empty() ? BB->end() : BB->front();
-    MachineInstr *PHI = InsertNewDef(TargetOpcode::PHI, BB, Loc,
-                                     Updater->VRC, Updater->MRI,
-                                     Updater->TII);
-    return PHI->getOperand(0).getReg();
-  }
-
-  /// AddPHIOperand - Add the specified value as an operand of the PHI for
-  /// the specified predecessor block.
-  static void AddPHIOperand(MachineInstr *PHI, unsigned Val,
-                            MachineBasicBlock *Pred) {
-    PHI->addOperand(MachineOperand::CreateReg(Val, false));
-    PHI->addOperand(MachineOperand::CreateMBB(Pred));
-  }
-
-  /// InstrIsPHI - Check if an instruction is a PHI.
-  ///
-  static MachineInstr *InstrIsPHI(MachineInstr *I) {
-    if (I && I->isPHI())
-      return I;
-    return 0;
-  }
+  // Okay, the value isn't in the map and we just inserted a null in the entry
+  // to indicate that we're processing the block.  Since we have no idea what
+  // value is in this block, we have to recurse through our predecessors.
+  //
+  // While we're walking our predecessors, we keep track of them in a vector,
+  // then insert a PHI node in the end if we actually need one.  We could use a
+  // smallvector here, but that would take a lot of stack space for every level
+  // of the recursion, just use IncomingPredInfo as an explicit stack.
+  IncomingPredInfoTy &IncomingPredInfo = getIncomingPredInfo(IPI);
+  unsigned FirstPredInfoEntry = IncomingPredInfo.size();
+
+  // As we're walking the predecessors, keep track of whether they are all
+  // producing the same value.  If so, this value will capture it, if not, it
+  // will get reset to null.  We distinguish the no-predecessor case explicitly
+  // below.
+  unsigned SingularValue = 0;
+  bool isFirstPred = true;
+  for (MachineBasicBlock::pred_iterator PI = BB->pred_begin(),
+         E = BB->pred_end(); PI != E; ++PI) {
+    MachineBasicBlock *PredBB = *PI;
+    unsigned PredVal = GetValueAtEndOfBlockInternal(PredBB);
+    IncomingPredInfo.push_back(std::make_pair(PredBB, PredVal));
 
-  /// ValueIsPHI - Check if the instruction that defines the specified register
-  /// is a PHI instruction.
-  static MachineInstr *ValueIsPHI(unsigned Val, MachineSSAUpdater *Updater) {
-    return InstrIsPHI(Updater->MRI->getVRegDef(Val));
+    // Compute SingularValue.
+    if (isFirstPred) {
+      SingularValue = PredVal;
+      isFirstPred = false;
+    } else if (PredVal != SingularValue)
+      SingularValue = 0;
   }
 
-  /// ValueIsNewPHI - Like ValueIsPHI but also check if the PHI has no source
-  /// operands, i.e., it was just added.
-  static MachineInstr *ValueIsNewPHI(unsigned Val, MachineSSAUpdater *Updater) {
-    MachineInstr *PHI = ValueIsPHI(Val, Updater);
-    if (PHI && PHI->getNumOperands() <= 1)
-      return PHI;
-    return 0;
+  /// Look up BB's entry in AvailableVals.  'InsertRes' may be invalidated.  If
+  /// this block is involved in a loop, a no-entry PHI node will have been
+  /// inserted as InsertedVal.  Otherwise, we'll still have the null we inserted
+  /// above.
+  unsigned &InsertedVal = AvailableVals[BB];
+
+  // If all the predecessor values are the same then we don't need to insert a
+  // PHI.  This is the simple and common case.
+  if (SingularValue) {
+    // If a PHI node got inserted, replace it with the singlar value and delete
+    // it.
+    if (InsertedVal) {
+      MachineInstr *OldVal = MRI->getVRegDef(InsertedVal);
+      // Be careful about dead loops.  These RAUW's also update InsertedVal.
+      assert(InsertedVal != SingularValue && "Dead loop?");
+      ReplaceRegWith(InsertedVal, SingularValue);
+      OldVal->eraseFromParent();
+    }
+
+    InsertedVal = SingularValue;
+
+    // Drop the entries we added in IncomingPredInfo to restore the stack.
+    IncomingPredInfo.erase(IncomingPredInfo.begin()+FirstPredInfoEntry,
+                           IncomingPredInfo.end());
+    return InsertedVal;
   }
 
-  /// GetPHIValue - For the specified PHI instruction, return the register
-  /// that it defines.
-  static unsigned GetPHIValue(MachineInstr *PHI) {
-    return PHI->getOperand(0).getReg();
+
+  // Otherwise, we do need a PHI: insert one now if we don't already have one.
+  MachineInstr *InsertedPHI;
+  if (InsertedVal == 0) {
+    MachineBasicBlock::iterator Loc = BB->empty() ? BB->end() : BB->front();
+    InsertedPHI = InsertNewDef(TargetOpcode::PHI, BB, Loc,
+                               VRC, MRI, TII);
+    InsertedVal = InsertedPHI->getOperand(0).getReg();
+  } else {
+    InsertedPHI = MRI->getVRegDef(InsertedVal);
   }
-};
 
-} // End llvm namespace
+  // Fill in all the predecessors of the PHI.
+  MachineInstrBuilder MIB(InsertedPHI);
+  for (IncomingPredInfoTy::iterator I =
+         IncomingPredInfo.begin()+FirstPredInfoEntry,
+         E = IncomingPredInfo.end(); I != E; ++I)
+    MIB.addReg(I->second).addMBB(I->first);
+
+  // Drop the entries we added in IncomingPredInfo to restore the stack.
+  IncomingPredInfo.erase(IncomingPredInfo.begin()+FirstPredInfoEntry,
+                         IncomingPredInfo.end());
 
-/// GetValueAtEndOfBlockInternal - Check to see if AvailableVals has an entry
-/// for the specified BB and if so, return it.  If not, construct SSA form by
-/// first calculating the required placement of PHIs and then inserting new
-/// PHIs where needed.
-unsigned MachineSSAUpdater::GetValueAtEndOfBlockInternal(MachineBasicBlock *BB){
-  AvailableValsTy &AvailableVals = getAvailableVals(AV);
-  if (unsigned V = AvailableVals[BB])
-    return V;
+  // See if the PHI node can be merged to a single value.  This can happen in
+  // loop cases when we get a PHI of itself and one other value.
+  if (unsigned ConstVal = InsertedPHI->isConstantValuePHI()) {
+    MRI->replaceRegWith(InsertedVal, ConstVal);
+    InsertedPHI->eraseFromParent();
+    InsertedVal = ConstVal;
+  } else {
+    DEBUG(dbgs() << "  Inserted PHI: " << *InsertedPHI << "\n");
+
+    // If the client wants to know about all new instructions, tell it.
+    if (InsertedPHIs) InsertedPHIs->push_back(InsertedPHI);
+  }
 
-  SSAUpdaterImpl<MachineSSAUpdater> Impl(this, &AvailableVals, InsertedPHIs);
-  return Impl.GetValue(BB);
+  return InsertedVal;
 }

Modified: llvm/branches/Apple/Pertwee/lib/Transforms/Utils/SSAUpdater.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Pertwee/lib/Transforms/Utils/SSAUpdater.cpp?rev=110151&r1=110150&r2=110151&view=diff
==============================================================================
--- llvm/branches/Apple/Pertwee/lib/Transforms/Utils/SSAUpdater.cpp (original)
+++ llvm/branches/Apple/Pertwee/lib/Transforms/Utils/SSAUpdater.cpp Tue Aug  3 16:28:51 2010
@@ -11,28 +11,34 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "ssaupdater"
+#include "llvm/Transforms/Utils/SSAUpdater.h"
 #include "llvm/Instructions.h"
 #include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/AlignOf.h"
-#include "llvm/Support/Allocator.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/ValueHandle.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Utils/SSAUpdater.h"
-#include "llvm/Transforms/Utils/SSAUpdaterImpl.h"
 using namespace llvm;
 
-typedef DenseMap<BasicBlock*, Value*> AvailableValsTy;
+typedef DenseMap<BasicBlock*, TrackingVH<Value> > AvailableValsTy;
+typedef std::vector<std::pair<BasicBlock*, TrackingVH<Value> > >
+                IncomingPredInfoTy;
+
 static AvailableValsTy &getAvailableVals(void *AV) {
   return *static_cast<AvailableValsTy*>(AV);
 }
 
+static IncomingPredInfoTy &getIncomingPredInfo(void *IPI) {
+  return *static_cast<IncomingPredInfoTy*>(IPI);
+}
+
+
 SSAUpdater::SSAUpdater(SmallVectorImpl<PHINode*> *NewPHI)
-  : AV(0), PrototypeValue(0), InsertedPHIs(NewPHI) {}
+  : AV(0), PrototypeValue(0), IPI(0), InsertedPHIs(NewPHI) {}
 
 SSAUpdater::~SSAUpdater() {
   delete &getAvailableVals(AV);
+  delete &getIncomingPredInfo(IPI);
 }
 
 /// Initialize - Reset this object to get ready for a new set of SSA
@@ -42,6 +48,11 @@
     AV = new AvailableValsTy();
   else
     getAvailableVals(AV).clear();
+
+  if (IPI == 0)
+    IPI = new IncomingPredInfoTy();
+  else
+    getIncomingPredInfo(IPI).clear();
   PrototypeValue = ProtoValue;
 }
 
@@ -62,7 +73,7 @@
 
 /// IsEquivalentPHI - Check if PHI has the same incoming value as specified
 /// in ValueMapping for each predecessor block.
-static bool IsEquivalentPHI(PHINode *PHI,
+static bool IsEquivalentPHI(PHINode *PHI, 
                             DenseMap<BasicBlock*, Value*> &ValueMapping) {
   unsigned PHINumValues = PHI->getNumIncomingValues();
   if (PHINumValues != ValueMapping.size())
@@ -78,10 +89,38 @@
   return true;
 }
 
+/// GetExistingPHI - Check if BB already contains a phi node that is equivalent
+/// to the specified mapping from predecessor blocks to incoming values.
+static Value *GetExistingPHI(BasicBlock *BB,
+                             DenseMap<BasicBlock*, Value*> &ValueMapping) {
+  PHINode *SomePHI;
+  for (BasicBlock::iterator It = BB->begin();
+       (SomePHI = dyn_cast<PHINode>(It)); ++It) {
+    if (IsEquivalentPHI(SomePHI, ValueMapping))
+      return SomePHI;
+  }
+  return 0;
+}
+
+/// GetExistingPHI - Check if BB already contains an equivalent phi node.
+/// The InputIt type must be an iterator over std::pair<BasicBlock*, Value*>
+/// objects that specify the mapping from predecessor blocks to incoming values.
+template<typename InputIt>
+static Value *GetExistingPHI(BasicBlock *BB, const InputIt &I,
+                             const InputIt &E) {
+  // Avoid create the mapping if BB has no phi nodes at all.
+  if (!isa<PHINode>(BB->begin()))
+    return 0;
+  DenseMap<BasicBlock*, Value*> ValueMapping(I, E);
+  return GetExistingPHI(BB, ValueMapping);
+}
+
 /// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
 /// live at the end of the specified block.
 Value *SSAUpdater::GetValueAtEndOfBlock(BasicBlock *BB) {
+  assert(getIncomingPredInfo(IPI).empty() && "Unexpected Internal State");
   Value *Res = GetValueAtEndOfBlockInternal(BB);
+  assert(getIncomingPredInfo(IPI).empty() && "Unexpected Internal State");
   return Res;
 }
 
@@ -107,7 +146,7 @@
 Value *SSAUpdater::GetValueInMiddleOfBlock(BasicBlock *BB) {
   // If there is no definition of the renamed variable in this block, just use
   // GetValueAtEndOfBlock to do our work.
-  if (!HasValueForBlock(BB))
+  if (!getAvailableVals(AV).count(BB))
     return GetValueAtEndOfBlock(BB);
 
   // Otherwise, we have the hard case.  Get the live-in values for each
@@ -154,18 +193,10 @@
   if (SingularValue != 0)
     return SingularValue;
 
-  // Otherwise, we do need a PHI: check to see if we already have one available
-  // in this block that produces the right value.
-  if (isa<PHINode>(BB->begin())) {
-    DenseMap<BasicBlock*, Value*> ValueMapping(PredValues.begin(),
-                                               PredValues.end());
-    PHINode *SomePHI;
-    for (BasicBlock::iterator It = BB->begin();
-         (SomePHI = dyn_cast<PHINode>(It)); ++It) {
-      if (IsEquivalentPHI(SomePHI, ValueMapping))
-        return SomePHI;
-    }
-  }
+  // Otherwise, we do need a PHI.
+  if (Value *ExistingPHI = GetExistingPHI(BB, PredValues.begin(),
+                                          PredValues.end()))
+    return ExistingPHI;
 
   // Ok, we have no way out, insert a new one now.
   PHINode *InsertedPHI = PHINode::Create(PrototypeValue->getType(),
@@ -195,7 +226,7 @@
 /// which use their value in the corresponding predecessor.
 void SSAUpdater::RewriteUse(Use &U) {
   Instruction *User = cast<Instruction>(U.getUser());
-
+  
   Value *V;
   if (PHINode *UserPN = dyn_cast<PHINode>(User))
     V = GetValueAtEndOfBlock(UserPN->getIncomingBlock(U));
@@ -205,126 +236,161 @@
   U.set(V);
 }
 
-/// PHIiter - Iterator for PHI operands.  This is used for the PHI_iterator
-/// in the SSAUpdaterImpl template.
-namespace {
-  class PHIiter {
-  private:
-    PHINode *PHI;
-    unsigned idx;
-
-  public:
-    explicit PHIiter(PHINode *P) // begin iterator
-      : PHI(P), idx(0) {}
-    PHIiter(PHINode *P, bool) // end iterator
-      : PHI(P), idx(PHI->getNumIncomingValues()) {}
-
-    PHIiter &operator++() { ++idx; return *this; } 
-    bool operator==(const PHIiter& x) const { return idx == x.idx; }
-    bool operator!=(const PHIiter& x) const { return !operator==(x); }
-    Value *getIncomingValue() { return PHI->getIncomingValue(idx); }
-    BasicBlock *getIncomingBlock() { return PHI->getIncomingBlock(idx); }
-  };
-}
-
-/// SSAUpdaterTraits<SSAUpdater> - Traits for the SSAUpdaterImpl template,
-/// specialized for SSAUpdater.
-namespace llvm {
-template<>
-class SSAUpdaterTraits<SSAUpdater> {
-public:
-  typedef BasicBlock BlkT;
-  typedef Value *ValT;
-  typedef PHINode PhiT;
-
-  typedef succ_iterator BlkSucc_iterator;
-  static BlkSucc_iterator BlkSucc_begin(BlkT *BB) { return succ_begin(BB); }
-  static BlkSucc_iterator BlkSucc_end(BlkT *BB) { return succ_end(BB); }
-
-  typedef PHIiter PHI_iterator;
-  static inline PHI_iterator PHI_begin(PhiT *PHI) { return PHI_iterator(PHI); }
-  static inline PHI_iterator PHI_end(PhiT *PHI) {
-    return PHI_iterator(PHI, true);
-  }
 
-  /// FindPredecessorBlocks - Put the predecessors of Info->BB into the Preds
-  /// vector, set Info->NumPreds, and allocate space in Info->Preds.
-  static void FindPredecessorBlocks(BasicBlock *BB,
-                                    SmallVectorImpl<BasicBlock*> *Preds) {
-    // We can get our predecessor info by walking the pred_iterator list,
-    // but it is relatively slow.  If we already have PHI nodes in this
-    // block, walk one of them to get the predecessor list instead.
-    if (PHINode *SomePhi = dyn_cast<PHINode>(BB->begin())) {
-      for (unsigned PI = 0, E = SomePhi->getNumIncomingValues(); PI != E; ++PI)
-        Preds->push_back(SomePhi->getIncomingBlock(PI));
-    } else {
-      for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
-        Preds->push_back(*PI);
-    }
-  }
+/// GetValueAtEndOfBlockInternal - Check to see if AvailableVals has an entry
+/// for the specified BB and if so, return it.  If not, construct SSA form by
+/// walking predecessors inserting PHI nodes as needed until we get to a block
+/// where the value is available.
+///
+Value *SSAUpdater::GetValueAtEndOfBlockInternal(BasicBlock *BB) {
+  AvailableValsTy &AvailableVals = getAvailableVals(AV);
 
-  /// GetUndefVal - Get an undefined value of the same type as the value
-  /// being handled.
-  static Value *GetUndefVal(BasicBlock *BB, SSAUpdater *Updater) {
-    return UndefValue::get(Updater->PrototypeValue->getType());
-  }
+  // Query AvailableVals by doing an insertion of null.
+  std::pair<AvailableValsTy::iterator, bool> InsertRes =
+    AvailableVals.insert(std::make_pair(BB, TrackingVH<Value>()));
+
+  // Handle the case when the insertion fails because we have already seen BB.
+  if (!InsertRes.second) {
+    // If the insertion failed, there are two cases.  The first case is that the
+    // value is already available for the specified block.  If we get this, just
+    // return the value.
+    if (InsertRes.first->second != 0)
+      return InsertRes.first->second;
+
+    // Otherwise, if the value we find is null, then this is the value is not
+    // known but it is being computed elsewhere in our recursion.  This means
+    // that we have a cycle.  Handle this by inserting a PHI node and returning
+    // it.  When we get back to the first instance of the recursion we will fill
+    // in the PHI node.
+    return InsertRes.first->second =
+      PHINode::Create(PrototypeValue->getType(), PrototypeValue->getName(),
+                      &BB->front());
+  }
+
+  // Okay, the value isn't in the map and we just inserted a null in the entry
+  // to indicate that we're processing the block.  Since we have no idea what
+  // value is in this block, we have to recurse through our predecessors.
+  //
+  // While we're walking our predecessors, we keep track of them in a vector,
+  // then insert a PHI node in the end if we actually need one.  We could use a
+  // smallvector here, but that would take a lot of stack space for every level
+  // of the recursion, just use IncomingPredInfo as an explicit stack.
+  IncomingPredInfoTy &IncomingPredInfo = getIncomingPredInfo(IPI);
+  unsigned FirstPredInfoEntry = IncomingPredInfo.size();
+
+  // As we're walking the predecessors, keep track of whether they are all
+  // producing the same value.  If so, this value will capture it, if not, it
+  // will get reset to null.  We distinguish the no-predecessor case explicitly
+  // below.
+  TrackingVH<Value> ExistingValue;
 
-  /// CreateEmptyPHI - Create a new PHI instruction in the specified block.
-  /// Reserve space for the operands but do not fill them in yet.
-  static Value *CreateEmptyPHI(BasicBlock *BB, unsigned NumPreds,
-                               SSAUpdater *Updater) {
-    PHINode *PHI = PHINode::Create(Updater->PrototypeValue->getType(),
-                                   Updater->PrototypeValue->getName(),
-                                   &BB->front());
-    PHI->reserveOperandSpace(NumPreds);
-    return PHI;
-  }
+  // We can get our predecessor info by walking the pred_iterator list, but it
+  // is relatively slow.  If we already have PHI nodes in this block, walk one
+  // of them to get the predecessor list instead.
+  if (PHINode *SomePhi = dyn_cast<PHINode>(BB->begin())) {
+    for (unsigned i = 0, e = SomePhi->getNumIncomingValues(); i != e; ++i) {
+      BasicBlock *PredBB = SomePhi->getIncomingBlock(i);
+      Value *PredVal = GetValueAtEndOfBlockInternal(PredBB);
+      IncomingPredInfo.push_back(std::make_pair(PredBB, PredVal));
 
-  /// AddPHIOperand - Add the specified value as an operand of the PHI for
-  /// the specified predecessor block.
-  static void AddPHIOperand(PHINode *PHI, Value *Val, BasicBlock *Pred) {
-    PHI->addIncoming(Val, Pred);
-  }
+      // Set ExistingValue to singular value from all predecessors so far.
+      if (i == 0)
+        ExistingValue = PredVal;
+      else if (PredVal != ExistingValue)
+        ExistingValue = 0;
+    }
+  } else {
+    bool isFirstPred = true;
+    for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
+      BasicBlock *PredBB = *PI;
+      Value *PredVal = GetValueAtEndOfBlockInternal(PredBB);
+      IncomingPredInfo.push_back(std::make_pair(PredBB, PredVal));
 
-  /// InstrIsPHI - Check if an instruction is a PHI.
-  ///
-  static PHINode *InstrIsPHI(Instruction *I) {
-    return dyn_cast<PHINode>(I);
+      // Set ExistingValue to singular value from all predecessors so far.
+      if (isFirstPred) {
+        ExistingValue = PredVal;
+        isFirstPred = false;
+      } else if (PredVal != ExistingValue)
+        ExistingValue = 0;
+    }
   }
 
-  /// ValueIsPHI - Check if a value is a PHI.
-  ///
-  static PHINode *ValueIsPHI(Value *Val, SSAUpdater *Updater) {
-    return dyn_cast<PHINode>(Val);
-  }
+  // If there are no predecessors, then we must have found an unreachable block
+  // just return 'undef'.  Since there are no predecessors, InsertRes must not
+  // be invalidated.
+  if (IncomingPredInfo.size() == FirstPredInfoEntry)
+    return InsertRes.first->second = UndefValue::get(PrototypeValue->getType());
+
+  /// Look up BB's entry in AvailableVals.  'InsertRes' may be invalidated.  If
+  /// this block is involved in a loop, a no-entry PHI node will have been
+  /// inserted as InsertedVal.  Otherwise, we'll still have the null we inserted
+  /// above.
+  TrackingVH<Value> &InsertedVal = AvailableVals[BB];
+
+  // If the predecessor values are not all the same, then check to see if there
+  // is an existing PHI that can be used.
+  if (!ExistingValue)
+    ExistingValue = GetExistingPHI(BB,
+                                   IncomingPredInfo.begin()+FirstPredInfoEntry,
+                                   IncomingPredInfo.end());
+
+  // If there is an existing value we can use, then we don't need to insert a
+  // PHI.  This is the simple and common case.
+  if (ExistingValue) {
+    // If a PHI node got inserted, replace it with the existing value and delete
+    // it.
+    if (InsertedVal) {
+      PHINode *OldVal = cast<PHINode>(InsertedVal);
+      // Be careful about dead loops.  These RAUW's also update InsertedVal.
+      if (InsertedVal != ExistingValue)
+        OldVal->replaceAllUsesWith(ExistingValue);
+      else
+        OldVal->replaceAllUsesWith(UndefValue::get(InsertedVal->getType()));
+      OldVal->eraseFromParent();
+    } else {
+      InsertedVal = ExistingValue;
+    }
 
-  /// ValueIsNewPHI - Like ValueIsPHI but also check if the PHI has no source
-  /// operands, i.e., it was just added.
-  static PHINode *ValueIsNewPHI(Value *Val, SSAUpdater *Updater) {
-    PHINode *PHI = ValueIsPHI(Val, Updater);
-    if (PHI && PHI->getNumIncomingValues() == 0)
-      return PHI;
-    return 0;
-  }
+    // Either path through the 'if' should have set InsertedVal -> ExistingVal.
+    assert((InsertedVal == ExistingValue || isa<UndefValue>(InsertedVal)) &&
+           "RAUW didn't change InsertedVal to be ExistingValue");
+
+    // Drop the entries we added in IncomingPredInfo to restore the stack.
+    IncomingPredInfo.erase(IncomingPredInfo.begin()+FirstPredInfoEntry,
+                           IncomingPredInfo.end());
+    return ExistingValue;
+  }
+
+  // Otherwise, we do need a PHI: insert one now if we don't already have one.
+  if (InsertedVal == 0)
+    InsertedVal = PHINode::Create(PrototypeValue->getType(),
+                                  PrototypeValue->getName(), &BB->front());
 
-  /// GetPHIValue - For the specified PHI instruction, return the value
-  /// that it defines.
-  static Value *GetPHIValue(PHINode *PHI) {
-    return PHI;
-  }
-};
+  PHINode *InsertedPHI = cast<PHINode>(InsertedVal);
+  InsertedPHI->reserveOperandSpace(IncomingPredInfo.size()-FirstPredInfoEntry);
 
-} // End llvm namespace
+  // Fill in all the predecessors of the PHI.
+  for (IncomingPredInfoTy::iterator I =
+         IncomingPredInfo.begin()+FirstPredInfoEntry,
+       E = IncomingPredInfo.end(); I != E; ++I)
+    InsertedPHI->addIncoming(I->second, I->first);
+
+  // Drop the entries we added in IncomingPredInfo to restore the stack.
+  IncomingPredInfo.erase(IncomingPredInfo.begin()+FirstPredInfoEntry,
+                         IncomingPredInfo.end());
 
-/// GetValueAtEndOfBlockInternal - Check to see if AvailableVals has an entry
-/// for the specified BB and if so, return it.  If not, construct SSA form by
-/// first calculating the required placement of PHIs and then inserting new
-/// PHIs where needed.
-Value *SSAUpdater::GetValueAtEndOfBlockInternal(BasicBlock *BB) {
-  AvailableValsTy &AvailableVals = getAvailableVals(AV);
-  if (Value *V = AvailableVals[BB])
-    return V;
+  // See if the PHI node can be merged to a single value.  This can happen in
+  // loop cases when we get a PHI of itself and one other value.
+  if (Value *ConstVal = InsertedPHI->hasConstantValue()) {
+    InsertedPHI->replaceAllUsesWith(ConstVal);
+    InsertedPHI->eraseFromParent();
+    InsertedVal = ConstVal;
+  } else {
+    DEBUG(dbgs() << "  Inserted PHI: " << *InsertedPHI << "\n");
+
+    // If the client wants to know about all new instructions, tell it.
+    if (InsertedPHIs) InsertedPHIs->push_back(InsertedPHI);
+  }
 
-  SSAUpdaterImpl<SSAUpdater> Impl(this, &AvailableVals, InsertedPHIs);
-  return Impl.GetValue(BB);
+  return InsertedVal;
 }

Removed: llvm/branches/Apple/Pertwee/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Pertwee/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll?rev=110150&view=auto
==============================================================================
--- llvm/branches/Apple/Pertwee/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll (original)
+++ llvm/branches/Apple/Pertwee/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll (removed)
@@ -1,46 +0,0 @@
-; RUN: opt < %s -gvn -enable-full-load-pre -S | FileCheck %s
-
-define i8* @cat(i8* %s1, ...) nounwind {
-entry:
-  br i1 undef, label %bb, label %bb3
-
-bb:                                               ; preds = %entry
-  unreachable
-
-bb3:                                              ; preds = %entry
-  store i8* undef, i8** undef, align 4
-  br i1 undef, label %bb5, label %bb6
-
-bb5:                                              ; preds = %bb3
-  unreachable
-
-bb6:                                              ; preds = %bb3
-  br label %bb12
-
-bb8:                                              ; preds = %bb12
-  br i1 undef, label %bb9, label %bb10
-
-bb9:                                              ; preds = %bb8
-  %0 = load i8** undef, align 4                   ; <i8*> [#uses=0]
-  %1 = load i8** undef, align 4                   ; <i8*> [#uses=0]
-  br label %bb11
-
-bb10:                                             ; preds = %bb8
-  br label %bb11
-
-bb11:                                             ; preds = %bb10, %bb9
-; CHECK: bb11:
-; CHECK: phi
-; CHECK-NOT: phi
-  br label %bb12
-
-bb12:                                             ; preds = %bb11, %bb6
-; CHECK: bb12:
-; CHECK: phi
-; CHECK-NOT: phi
-  br i1 undef, label %bb8, label %bb13
-
-bb13:                                             ; preds = %bb12
-; CHECK: bb13:
-  ret i8* undef
-}





More information about the llvm-branch-commits mailing list