[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:37:33 PDT 2010
Oops. I meant to include the following in the svn log entry. For the record, here are the changes that I reverted from the branch:
--- Reverse-merging r103407 into '.':
U lib/CodeGen/MachineSSAUpdater.cpp
--- Reverse-merging r103184 into '.':
U include/llvm/Transforms/Utils/SSAUpdaterImpl.h
--- Reverse-merging r103060 into '.':
U include/llvm/Transforms/Utils/SSAUpdater.h
D include/llvm/Transforms/Utils/SSAUpdaterImpl.h
U include/llvm/CodeGen/MachineSSAUpdater.h
G lib/CodeGen/MachineSSAUpdater.cpp
U lib/Transforms/Utils/SSAUpdater.cpp
--- Reverse-merging r102353 into '.':
G include/llvm/CodeGen/MachineSSAUpdater.h
G lib/CodeGen/MachineSSAUpdater.cpp
--- Reverse-merging r102009 into '.':
G lib/Transforms/Utils/SSAUpdater.cpp
--- Reverse-merging r101612 into '.':
D test/Transforms/GVN/2010-03-31-RedundantPHIs.ll
G include/llvm/Transforms/Utils/SSAUpdater.h
G lib/Transforms/Utils/SSAUpdater.cpp
On Jun 3, 2010, at 3:30 PM, Bob Wilson wrote:
> 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
> -}
>
>
> _______________________________________________
> llvm-branch-commits mailing list
> llvm-branch-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-branch-commits
More information about the llvm-branch-commits
mailing list