#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
#define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ValueHandle.h"
+
namespace llvm {
+class CastInst;
+class PHINode;
template<typename T> class SSAUpdaterTraits;
template<typename UpdaterT>
/// where needed.
ValT GetValue(BlkT *BB) {
SmallVector<BBInfo*, 100> BlockList;
- BuildBlockList(BB, &BlockList);
+ BBInfo *PseudoEntry = BuildBlockList(BB, &BlockList);
// Special case: bail out if BB is unreachable.
if (BlockList.size() == 0) {
return V;
}
- FindDominators(&BlockList);
+ FindDominators(&BlockList, PseudoEntry);
FindPHIPlacement(&BlockList);
FindAvailableVals(&BlockList);
/// through its predecessors until reaching blocks with known values.
/// Create BBInfo structures for the blocks and append them to the block
/// list.
- void BuildBlockList(BlkT *BB, BlockListTy *BlockList) {
+ BBInfo *BuildBlockList(BlkT *BB, BlockListTy *BlockList) {
SmallVector<BBInfo*, 10> RootList;
SmallVector<BBInfo*, 64> WorkList;
Preds.clear();
Traits::FindPredecessorBlocks(Info->BB, &Preds);
Info->NumPreds = Preds.size();
- Info->Preds = static_cast<BBInfo**>
- (Allocator.Allocate(Info->NumPreds * sizeof(BBInfo*),
- AlignOf<BBInfo*>::Alignment));
-
- // Treat an unreachable predecessor as a definition with 'undef'.
- if (Info->NumPreds == 0) {
- Info->AvailableVal = Traits::GetUndefVal(Info->BB, Updater);
- Info->DefBB = Info;
- RootList.push_back(Info);
- continue;
- }
+ 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];
}
}
PseudoEntry->BlkNum = BlkNum;
+ return PseudoEntry;
}
/// IntersectDominators - This is the dataflow lattice "meet" operation for
/// 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) {
+ void FindDominators(BlockListTy *BlockList, BBInfo *PseudoEntry) {
bool Changed;
do {
Changed = false;
for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
E = BlockList->rend(); I != E; ++I) {
BBInfo *Info = *I;
+ BBInfo *NewIDom = 0;
- // Start with the first predecessor.
- assert(Info->NumPreds > 0 && "unreachable block");
- BBInfo *NewIDom = Info->Preds[0];
-
- // Iterate through the block's other predecessors.
- for (unsigned p = 1; p != Info->NumPreds; ++p) {
+ // Iterate through the block's predecessors.
+ for (unsigned p = 0; p != Info->NumPreds; ++p) {
BBInfo *Pred = Info->Preds[p];
- NewIDom = IntersectDominators(NewIDom, Pred);
+
+ // 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 != Info->IDom) {
+ if (NewIDom && NewIDom != Info->IDom) {
Info->IDom = NewIDom;
Changed = true;
}
if (!SomePHI)
break;
if (CheckIfPHIMatches(SomePHI)) {
- RecordMatchingPHI(SomePHI);
+ RecordMatchingPHIs(BlockList);
break;
}
// Match failed: clear all the PHITag values.
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);
+ /// RecordMatchingPHIs - For each PHI node that matches, record it in both
+ /// the BBMap and the AvailableVals mapping.
+ void RecordMatchingPHIs(BlockListTy *BlockList) {
+ for (typename BlockListTy::iterator I = BlockList->begin(),
+ E = BlockList->end(); I != E; ++I)
+ if (PhiT *PHI = (*I)->PHITag) {
+ BlkT *BB = PHI->getParent();
+ ValT PHIVal = Traits::GetPHIValue(PHI);
+ (*AvailableVals)[BB] = PHIVal;
+ BBMap[BB]->AvailableVal = PHIVal;
}
- }
}
};