[llvm-branch-commits] [llvm-branch] r105425 - in /llvm/branches/Apple/Troughton: 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
Thu Jun 3 15:30:57 PDT 2010
Author: bwilson
Date: Thu Jun 3 17:30:57 2010
New Revision: 105425
URL: http://llvm.org/viewvc/llvm-project?rev=105425&view=rev
Log:
Back out my SSAUpdater changes from the Troughton branch, since they expose
some performance problems due to the lack of live range splitting.
Removed:
llvm/branches/Apple/Troughton/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
llvm/branches/Apple/Troughton/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll
Modified:
llvm/branches/Apple/Troughton/include/llvm/CodeGen/MachineSSAUpdater.h
llvm/branches/Apple/Troughton/include/llvm/Transforms/Utils/SSAUpdater.h
llvm/branches/Apple/Troughton/lib/CodeGen/MachineSSAUpdater.cpp
llvm/branches/Apple/Troughton/lib/Transforms/Utils/SSAUpdater.cpp
Modified: llvm/branches/Apple/Troughton/include/llvm/CodeGen/MachineSSAUpdater.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/include/llvm/CodeGen/MachineSSAUpdater.h?rev=105425&r1=105424&r2=105425&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/include/llvm/CodeGen/MachineSSAUpdater.h (original)
+++ llvm/branches/Apple/Troughton/include/llvm/CodeGen/MachineSSAUpdater.h Thu Jun 3 17:30:57 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/Troughton/include/llvm/Transforms/Utils/SSAUpdater.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/include/llvm/Transforms/Utils/SSAUpdater.h?rev=105425&r1=105424&r2=105425&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/include/llvm/Transforms/Utils/SSAUpdater.h (original)
+++ llvm/branches/Apple/Troughton/include/llvm/Transforms/Utils/SSAUpdater.h Thu Jun 3 17:30:57 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/Troughton/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/include/llvm/Transforms/Utils/SSAUpdaterImpl.h?rev=105424&view=auto
==============================================================================
--- llvm/branches/Apple/Troughton/include/llvm/Transforms/Utils/SSAUpdaterImpl.h (original)
+++ llvm/branches/Apple/Troughton/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/Troughton/lib/CodeGen/MachineSSAUpdater.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/lib/CodeGen/MachineSSAUpdater.cpp?rev=105425&r1=105424&r2=105425&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/lib/CodeGen/MachineSSAUpdater.cpp (original)
+++ llvm/branches/Apple/Troughton/lib/CodeGen/MachineSSAUpdater.cpp Thu Jun 3 17:30:57 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/Troughton/lib/Transforms/Utils/SSAUpdater.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/lib/Transforms/Utils/SSAUpdater.cpp?rev=105425&r1=105424&r2=105425&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/lib/Transforms/Utils/SSAUpdater.cpp (original)
+++ llvm/branches/Apple/Troughton/lib/Transforms/Utils/SSAUpdater.cpp Thu Jun 3 17:30:57 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/Troughton/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll?rev=105424&view=auto
==============================================================================
--- llvm/branches/Apple/Troughton/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll (original)
+++ llvm/branches/Apple/Troughton/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