[llvm-commits] CVS: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
Chris Lattner
sabre at nondot.org
Tue Feb 6 17:15:20 PST 2007
Changes in directory llvm/lib/Transforms/Utils:
PromoteMemoryToRegister.cpp updated: 1.92 -> 1.93
---
Log message:
redesign the primary datastructure used by mem2reg to eliminate an
std::map of std::vector's (ouch!). This speeds up mem2reg by 10% on 176.gcc.
---
Diffs of the changes: (+157 -104)
PromoteMemoryToRegister.cpp | 261 ++++++++++++++++++++++++++------------------
1 files changed, 157 insertions(+), 104 deletions(-)
Index: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
diff -u llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.92 llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.93
--- llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.92 Mon Feb 5 17:37:20 2007
+++ llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Tue Feb 6 19:15:04 2007
@@ -32,6 +32,23 @@
#include <algorithm>
using namespace llvm;
+// Provide DenseMapKeyInfo for all pointers.
+namespace llvm {
+template<>
+struct DenseMapKeyInfo<std::pair<BasicBlock*, unsigned> > {
+ static inline std::pair<BasicBlock*, unsigned> getEmptyKey() {
+ return std::make_pair((BasicBlock*)-1, ~0U);
+ }
+ static inline std::pair<BasicBlock*, unsigned> getTombstoneKey() {
+ return std::make_pair((BasicBlock*)-2, 0U);
+ }
+ static unsigned getHashValue(const std::pair<BasicBlock*, unsigned> &Val) {
+ return DenseMapKeyInfo<void*>::getHashValue(Val.first) + Val.second*2;
+ }
+ static bool isPod() { return true; }
+};
+}
+
/// isAllocaPromotable - Return true if this alloca is legal for promotion.
/// This is true if there are only loads and stores to the alloca.
///
@@ -74,8 +91,12 @@
/// NewPhiNodes - The PhiNodes we're adding.
///
- std::map<BasicBlock*, std::vector<PHINode*> > NewPhiNodes;
-
+ DenseMap<std::pair<BasicBlock*, unsigned>, PHINode*> NewPhiNodes;
+
+ /// PhiToAllocaMap - For each PHI node, keep track of which entry in Allocas
+ /// it corresponds to.
+ DenseMap<PHINode*, unsigned> PhiToAllocaMap;
+
/// PointerAllocaValues - If we are updating an AliasSetTracker, then for
/// each alloca that is of pointer type, we keep track of what to copyValue
/// to the inserted PHI nodes here.
@@ -322,23 +343,14 @@
for (SmallPtrSet<PHINode*, 16>::iterator I = InsertedPHINodes.begin(),
E = InsertedPHINodes.end(); I != E; ++I) {
PHINode *PN = *I;
- std::vector<PHINode*> &BBPNs = NewPhiNodes[PN->getParent()];
- BBPNs[AllocaNum] = 0;
-
- // Check to see if we just removed the last inserted PHI node from this
- // basic block. If so, remove the entry for the basic block.
- bool HasOtherPHIs = false;
- for (unsigned i = 0, e = BBPNs.size(); i != e; ++i)
- if (BBPNs[i]) {
- HasOtherPHIs = true;
- break;
- }
- if (!HasOtherPHIs)
- NewPhiNodes.erase(PN->getParent());
-
+ bool Erased=NewPhiNodes.erase(std::make_pair(PN->getParent(), AllocaNum));
+ Erased=Erased;
+ assert(Erased && "PHI already removed?");
+
if (AST && isa<PointerType>(PN->getType()))
AST->deleteValue(PN);
PN->eraseFromParent();
+ PhiToAllocaMap.erase(PN);
}
// Keep the reverse mapping of the 'Allocas' array.
@@ -407,26 +419,24 @@
while (EliminatedAPHI) {
EliminatedAPHI = false;
- for (std::map<BasicBlock*, std::vector<PHINode *> >::iterator I =
- NewPhiNodes.begin(), E = NewPhiNodes.end(); I != E; ++I) {
- std::vector<PHINode*> &PNs = I->second;
- for (unsigned i = 0, e = PNs.size(); i != e; ++i) {
- if (!PNs[i]) continue;
-
- // If this PHI node merges one value and/or undefs, get the value.
- if (Value *V = PNs[i]->hasConstantValue(true)) {
- if (!isa<Instruction>(V) ||
- properlyDominates(cast<Instruction>(V), PNs[i])) {
- if (AST && isa<PointerType>(PNs[i]->getType()))
- AST->deleteValue(PNs[i]);
- PNs[i]->replaceAllUsesWith(V);
- PNs[i]->eraseFromParent();
- PNs[i] = 0;
- EliminatedAPHI = true;
- continue;
- }
+ for (DenseMap<std::pair<BasicBlock*, unsigned>, PHINode*>::iterator I =
+ NewPhiNodes.begin(), E = NewPhiNodes.end(); I != E;) {
+ PHINode *PN = I->second;
+
+ // If this PHI node merges one value and/or undefs, get the value.
+ if (Value *V = PN->hasConstantValue(true)) {
+ if (!isa<Instruction>(V) ||
+ properlyDominates(cast<Instruction>(V), PN)) {
+ if (AST && isa<PointerType>(PN->getType()))
+ AST->deleteValue(PN);
+ PN->replaceAllUsesWith(V);
+ PN->eraseFromParent();
+ NewPhiNodes.erase(I++);
+ EliminatedAPHI = true;
+ continue;
}
}
+ ++I;
}
}
@@ -436,52 +446,58 @@
// have incoming values for all predecessors. Loop over all PHI nodes we have
// created, inserting undef values if they are missing any incoming values.
//
- for (std::map<BasicBlock*, std::vector<PHINode *> >::iterator I =
+ for (DenseMap<std::pair<BasicBlock*, unsigned>, PHINode*>::iterator I =
NewPhiNodes.begin(), E = NewPhiNodes.end(); I != E; ++I) {
+ // We want to do this once per basic block. As such, only process a block
+ // when we find the PHI that is the first entry in the block.
+ PHINode *SomePHI = I->second;
+ BasicBlock *BB = SomePHI->getParent();
+ if (&BB->front() != SomePHI)
+ continue;
- std::vector<BasicBlock*> Preds(pred_begin(I->first), pred_end(I->first));
- std::vector<PHINode*> &PNs = I->second;
- assert(!PNs.empty() && "Empty PHI node list??");
- PHINode *SomePHI = 0;
- for (unsigned i = 0, e = PNs.size(); i != e; ++i)
- if (PNs[i]) {
- SomePHI = PNs[i];
- break;
- }
+ // Count the number of preds for BB.
+ SmallVector<BasicBlock*, 16> Preds(pred_begin(BB), pred_end(BB));
// Only do work here if there the PHI nodes are missing incoming values. We
// know that all PHI nodes that were inserted in a block will have the same
- // number of incoming values, so we can just check any PHI node.
- if (SomePHI && Preds.size() != SomePHI->getNumIncomingValues()) {
- // Ok, now we know that all of the PHI nodes are missing entries for some
- // basic blocks. Start by sorting the incoming predecessors for efficient
- // access.
- std::sort(Preds.begin(), Preds.end());
-
- // Now we loop through all BB's which have entries in SomePHI and remove
- // them from the Preds list.
- for (unsigned i = 0, e = SomePHI->getNumIncomingValues(); i != e; ++i) {
- // Do a log(n) search of the Preds list for the entry we want.
- std::vector<BasicBlock*>::iterator EntIt =
- std::lower_bound(Preds.begin(), Preds.end(),
- SomePHI->getIncomingBlock(i));
- assert(EntIt != Preds.end() && *EntIt == SomePHI->getIncomingBlock(i)&&
- "PHI node has entry for a block which is not a predecessor!");
-
- // Remove the entry
- Preds.erase(EntIt);
- }
-
- // At this point, the blocks left in the preds list must have dummy
- // entries inserted into every PHI nodes for the block.
- for (unsigned i = 0, e = PNs.size(); i != e; ++i)
- if (PHINode *PN = PNs[i]) {
- Value *UndefVal = UndefValue::get(PN->getType());
- for (unsigned pred = 0, e = Preds.size(); pred != e; ++pred)
- PN->addIncoming(UndefVal, Preds[pred]);
- }
+ // number of incoming values, so we can just check any of them.
+ if (SomePHI->getNumIncomingValues() == Preds.size())
+ continue;
+
+ // Ok, now we know that all of the PHI nodes are missing entries for some
+ // basic blocks. Start by sorting the incoming predecessors for efficient
+ // access.
+ std::sort(Preds.begin(), Preds.end());
+
+ // Now we loop through all BB's which have entries in SomePHI and remove
+ // them from the Preds list.
+ for (unsigned i = 0, e = SomePHI->getNumIncomingValues(); i != e; ++i) {
+ // Do a log(n) search of the Preds list for the entry we want.
+ SmallVector<BasicBlock*, 16>::iterator EntIt =
+ std::lower_bound(Preds.begin(), Preds.end(),
+ SomePHI->getIncomingBlock(i));
+ assert(EntIt != Preds.end() && *EntIt == SomePHI->getIncomingBlock(i)&&
+ "PHI node has entry for a block which is not a predecessor!");
+
+ // Remove the entry
+ Preds.erase(EntIt);
+ }
+
+ // At this point, the blocks left in the preds list must have dummy
+ // entries inserted into every PHI nodes for the block. Update all the phi
+ // nodes in this block that we are inserting (there could be phis before
+ // mem2reg runs).
+ unsigned NumBadPreds = SomePHI->getNumIncomingValues();
+ BasicBlock::iterator BBI = BB->begin();
+ while ((SomePHI = dyn_cast<PHINode>(BBI++)) &&
+ SomePHI->getNumIncomingValues() == NumBadPreds) {
+ Value *UndefVal = UndefValue::get(SomePHI->getType());
+ for (unsigned pred = 0, e = Preds.size(); pred != e; ++pred)
+ SomePHI->addIncoming(UndefVal, Preds[pred]);
}
}
+
+ NewPhiNodes.clear();
}
// MarkDominatingPHILive - Mem2Reg wants to construct "pruned" SSA form, not
@@ -498,11 +514,11 @@
// PHI node for Alloca num. If we find it, mark the PHI node as being alive!
for (DominatorTree::Node *N = DT[BB]; N; N = N->getIDom()) {
BasicBlock *DomBB = N->getBlock();
- std::map<BasicBlock*, std::vector<PHINode*> >::iterator
- I = NewPhiNodes.find(DomBB);
- if (I != NewPhiNodes.end() && I->second[AllocaNum]) {
+ DenseMap<std::pair<BasicBlock*, unsigned>, PHINode*>::iterator
+ I = NewPhiNodes.find(std::make_pair(DomBB, AllocaNum));
+ if (I != NewPhiNodes.end()) {
// Ok, we found an inserted PHI node which dominates this value.
- PHINode *DominatingPHI = I->second[AllocaNum];
+ PHINode *DominatingPHI = I->second;
// Find out if we previously thought it was dead. If so, mark it as being
// live by removing it from the DeadPHINodes set.
@@ -636,18 +652,18 @@
unsigned &Version,
SmallPtrSet<PHINode*, 16> &InsertedPHINodes) {
// Look up the basic-block in question.
- std::vector<PHINode*> &BBPNs = NewPhiNodes[BB];
- if (BBPNs.empty()) BBPNs.resize(Allocas.size());
+ PHINode *&PN = NewPhiNodes[std::make_pair(BB, AllocaNo)];
// If the BB already has a phi node added for the i'th alloca then we're done!
- if (BBPNs[AllocaNo]) return false;
+ if (PN) return false;
// Create a PhiNode using the dereferenced type... and add the phi-node to the
// BasicBlock.
- PHINode *PN = new PHINode(Allocas[AllocaNo]->getAllocatedType(),
- Allocas[AllocaNo]->getName() + "." +
- utostr(Version++), BB->begin());
- BBPNs[AllocaNo] = PN;
+ PN = new PHINode(Allocas[AllocaNo]->getAllocatedType(),
+ Allocas[AllocaNo]->getName() + "." +
+ utostr(Version++), BB->begin());
+ PhiToAllocaMap[PN] = AllocaNo;
+
InsertedPHINodes.insert(PN);
if (AST && isa<PointerType>(PN->getType()))
@@ -663,28 +679,65 @@
//
void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
std::vector<Value*> &IncomingVals) {
-
- // If this BB needs a PHI node, update the PHI node for each variable we need
- // PHI nodes for.
- std::map<BasicBlock*, std::vector<PHINode *> >::iterator
- BBPNI = NewPhiNodes.find(BB);
- if (BBPNI != NewPhiNodes.end()) {
- std::vector<PHINode *> &BBPNs = BBPNI->second;
- for (unsigned k = 0; k != BBPNs.size(); ++k)
- if (PHINode *PN = BBPNs[k]) {
- // Add this incoming value to the PHI node.
- PN->addIncoming(IncomingVals[k], Pred);
-
- // The currently active variable for this block is now the PHI.
- IncomingVals[k] = PN;
+ // If we are inserting any phi nodes into this BB, they will already be in the
+ // block.
+ if (PHINode *APN = dyn_cast<PHINode>(BB->begin())) {
+ // Pred may have multiple edges to BB. If so, we want to add N incoming
+ // values to each PHI we are inserting on the first time we see the edge.
+ // Check to see if APN already has incoming values from Pred. This also
+ // prevents us from modifying PHI nodes that are not currently being
+ // inserted.
+ bool HasPredEntries = false;
+ for (unsigned i = 0, e = APN->getNumIncomingValues(); i != e; ++i) {
+ if (APN->getIncomingBlock(i) == Pred) {
+ HasPredEntries = true;
+ break;
}
+ }
+
+ // If we have PHI nodes to update, compute the number of edges from Pred to
+ // BB.
+ if (!HasPredEntries) {
+ TerminatorInst *PredTerm = Pred->getTerminator();
+ unsigned NumEdges = 0;
+ for (unsigned i = 0, e = PredTerm->getNumSuccessors(); i != e; ++i) {
+ if (PredTerm->getSuccessor(i) == BB)
+ ++NumEdges;
+ }
+ assert(NumEdges && "Must be at least one edge from Pred to BB!");
+
+ // Add entries for all the phis.
+ BasicBlock::iterator PNI = BB->begin();
+ do {
+ unsigned AllocaNo = PhiToAllocaMap[APN];
+
+ // Add N incoming values to the PHI node.
+ for (unsigned i = 0; i != NumEdges; ++i)
+ APN->addIncoming(IncomingVals[AllocaNo], Pred);
+
+ // The currently active variable for this block is now the PHI.
+ IncomingVals[AllocaNo] = APN;
+
+ // Get the next phi node.
+ ++PNI;
+ APN = dyn_cast<PHINode>(PNI);
+ if (APN == 0) break;
+
+ // Verify it doesn't already have entries for Pred. If it does, it is
+ // not being inserted by this mem2reg invocation.
+ HasPredEntries = false;
+ for (unsigned i = 0, e = APN->getNumIncomingValues(); i != e; ++i) {
+ if (APN->getIncomingBlock(i) == Pred) {
+ HasPredEntries = true;
+ break;
+ }
+ }
+ } while (!HasPredEntries);
+ }
}
-
- // don't revisit nodes
- if (Visited.count(BB)) return;
-
- // mark as visited
- Visited.insert(BB);
+
+ // Don't revisit blocks.
+ if (!Visited.insert(BB)) return;
for (BasicBlock::iterator II = BB->begin(); !isa<TerminatorInst>(II); ) {
Instruction *I = II++; // get the instruction, increment iterator
More information about the llvm-commits
mailing list