Revamp PredIteratorCache interface to be cleaner.

Summary:
This lets us use range based for loops.

Reviewers: chandlerc

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D9169

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235416 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Berlin 2015-04-21 21:11:50 +00:00
parent 0f710d7a5a
commit 13ba3ca69f
5 changed files with 69 additions and 62 deletions

View File

@ -19,6 +19,7 @@
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/BasicBlock.h" #include "llvm/IR/BasicBlock.h"
#include "llvm/IR/PredIteratorCache.h"
#include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
@ -325,7 +326,7 @@ namespace llvm {
AliasAnalysis *AA; AliasAnalysis *AA;
DominatorTree *DT; DominatorTree *DT;
AssumptionCache *AC; AssumptionCache *AC;
std::unique_ptr<PredIteratorCache> PredCache; PredIteratorCache PredCache;
public: public:
MemoryDependenceAnalysis(); MemoryDependenceAnalysis();

View File

@ -14,6 +14,7 @@
#ifndef LLVM_IR_PREDITERATORCACHE_H #ifndef LLVM_IR_PREDITERATORCACHE_H
#define LLVM_IR_PREDITERATORCACHE_H #define LLVM_IR_PREDITERATORCACHE_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/IR/CFG.h" #include "llvm/IR/CFG.h"
@ -21,50 +22,58 @@
namespace llvm { namespace llvm {
/// PredIteratorCache - This class is an extremely trivial cache for /// PredIteratorCache - This class is an extremely trivial cache for
/// predecessor iterator queries. This is useful for code that repeatedly /// predecessor iterator queries. This is useful for code that repeatedly
/// wants the predecessor list for the same blocks. /// wants the predecessor list for the same blocks.
class PredIteratorCache { class PredIteratorCache {
/// BlockToPredsMap - Pointer to null-terminated list. /// BlockToPredsMap - Pointer to null-terminated list.
DenseMap<BasicBlock*, BasicBlock**> BlockToPredsMap; DenseMap<BasicBlock *, BasicBlock **> BlockToPredsMap;
DenseMap<BasicBlock*, unsigned> BlockToPredCountMap; DenseMap<BasicBlock *, unsigned> BlockToPredCountMap;
/// Memory - This is the space that holds cached preds. /// Memory - This is the space that holds cached preds.
BumpPtrAllocator Memory; BumpPtrAllocator Memory;
public:
/// GetPreds - Get a cached list for the null-terminated predecessor list of private:
/// the specified block. This can be used in a loop like this: /// GetPreds - Get a cached list for the null-terminated predecessor list of
/// for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) /// the specified block. This can be used in a loop like this:
/// use(*PI); /// for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI)
/// instead of: /// use(*PI);
/// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) /// instead of:
BasicBlock **GetPreds(BasicBlock *BB) { /// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
BasicBlock **&Entry = BlockToPredsMap[BB]; BasicBlock **GetPreds(BasicBlock *BB) {
if (Entry) return Entry; BasicBlock **&Entry = BlockToPredsMap[BB];
if (Entry)
SmallVector<BasicBlock*, 32> PredCache(pred_begin(BB), pred_end(BB));
PredCache.push_back(nullptr); // null terminator.
BlockToPredCountMap[BB] = PredCache.size()-1;
Entry = Memory.Allocate<BasicBlock*>(PredCache.size());
std::copy(PredCache.begin(), PredCache.end(), Entry);
return Entry; return Entry;
}
unsigned GetNumPreds(BasicBlock *BB) {
GetPreds(BB);
return BlockToPredCountMap[BB];
}
/// clear - Remove all information. SmallVector<BasicBlock *, 32> PredCache(pred_begin(BB), pred_end(BB));
void clear() { PredCache.push_back(nullptr); // null terminator.
BlockToPredsMap.clear();
BlockToPredCountMap.clear(); BlockToPredCountMap[BB] = PredCache.size() - 1;
Memory.Reset();
} Entry = Memory.Allocate<BasicBlock *>(PredCache.size());
}; std::copy(PredCache.begin(), PredCache.end(), Entry);
return Entry;
}
unsigned GetNumPreds(BasicBlock *BB) {
GetPreds(BB);
return BlockToPredCountMap[BB];
}
public:
size_t size(BasicBlock *BB) { return GetNumPreds(BB); }
ArrayRef<BasicBlock *> get(BasicBlock *BB) {
return makeArrayRef(GetPreds(BB), GetNumPreds(BB));
}
/// clear - Remove all information.
void clear() {
BlockToPredsMap.clear();
BlockToPredCountMap.clear();
Memory.Reset();
}
};
} // end namespace llvm } // end namespace llvm
#endif #endif

View File

@ -65,7 +65,7 @@ INITIALIZE_PASS_END(MemoryDependenceAnalysis, "memdep",
"Memory Dependence Analysis", false, true) "Memory Dependence Analysis", false, true)
MemoryDependenceAnalysis::MemoryDependenceAnalysis() MemoryDependenceAnalysis::MemoryDependenceAnalysis()
: FunctionPass(ID), PredCache() { : FunctionPass(ID) {
initializeMemoryDependenceAnalysisPass(*PassRegistry::getPassRegistry()); initializeMemoryDependenceAnalysisPass(*PassRegistry::getPassRegistry());
} }
MemoryDependenceAnalysis::~MemoryDependenceAnalysis() { MemoryDependenceAnalysis::~MemoryDependenceAnalysis() {
@ -79,7 +79,7 @@ void MemoryDependenceAnalysis::releaseMemory() {
ReverseLocalDeps.clear(); ReverseLocalDeps.clear();
ReverseNonLocalDeps.clear(); ReverseNonLocalDeps.clear();
ReverseNonLocalPtrDeps.clear(); ReverseNonLocalPtrDeps.clear();
PredCache->clear(); PredCache.clear();
} }
/// getAnalysisUsage - Does not modify anything. It uses Alias Analysis. /// getAnalysisUsage - Does not modify anything. It uses Alias Analysis.
@ -96,8 +96,6 @@ bool MemoryDependenceAnalysis::runOnFunction(Function &F) {
DominatorTreeWrapperPass *DTWP = DominatorTreeWrapperPass *DTWP =
getAnalysisIfAvailable<DominatorTreeWrapperPass>(); getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DT = DTWP ? &DTWP->getDomTree() : nullptr; DT = DTWP ? &DTWP->getDomTree() : nullptr;
if (!PredCache)
PredCache.reset(new PredIteratorCache());
return false; return false;
} }
@ -770,8 +768,8 @@ MemoryDependenceAnalysis::getNonLocalCallDependency(CallSite QueryCS) {
} else { } else {
// Seed DirtyBlocks with each of the preds of QueryInst's block. // Seed DirtyBlocks with each of the preds of QueryInst's block.
BasicBlock *QueryBB = QueryCS.getInstruction()->getParent(); BasicBlock *QueryBB = QueryCS.getInstruction()->getParent();
for (BasicBlock **PI = PredCache->GetPreds(QueryBB); *PI; ++PI) for (BasicBlock *Pred : PredCache.get(QueryBB))
DirtyBlocks.push_back(*PI); DirtyBlocks.push_back(Pred);
++NumUncacheNonLocal; ++NumUncacheNonLocal;
} }
@ -856,8 +854,8 @@ MemoryDependenceAnalysis::getNonLocalCallDependency(CallSite QueryCS) {
// If the block *is* completely transparent to the load, we need to check // If the block *is* completely transparent to the load, we need to check
// the predecessors of this block. Add them to our worklist. // the predecessors of this block. Add them to our worklist.
for (BasicBlock **PI = PredCache->GetPreds(DirtyBB); *PI; ++PI) for (BasicBlock *Pred : PredCache.get(DirtyBB))
DirtyBlocks.push_back(*PI); DirtyBlocks.push_back(Pred);
} }
} }
@ -1232,13 +1230,13 @@ getNonLocalPointerDepFromBB(Instruction *QueryInst,
if (!Pointer.NeedsPHITranslationFromBlock(BB)) { if (!Pointer.NeedsPHITranslationFromBlock(BB)) {
SkipFirstBlock = false; SkipFirstBlock = false;
SmallVector<BasicBlock*, 16> NewBlocks; SmallVector<BasicBlock*, 16> NewBlocks;
for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) { for (BasicBlock *Pred : PredCache.get(BB)) {
// Verify that we haven't looked at this block yet. // Verify that we haven't looked at this block yet.
std::pair<DenseMap<BasicBlock*,Value*>::iterator, bool> std::pair<DenseMap<BasicBlock*,Value*>::iterator, bool>
InsertRes = Visited.insert(std::make_pair(*PI, Pointer.getAddr())); InsertRes = Visited.insert(std::make_pair(Pred, Pointer.getAddr()));
if (InsertRes.second) { if (InsertRes.second) {
// First time we've looked at *PI. // First time we've looked at *PI.
NewBlocks.push_back(*PI); NewBlocks.push_back(Pred);
continue; continue;
} }
@ -1274,8 +1272,7 @@ getNonLocalPointerDepFromBB(Instruction *QueryInst,
Cache = nullptr; Cache = nullptr;
PredList.clear(); PredList.clear();
for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) { for (BasicBlock *Pred : PredCache.get(BB)) {
BasicBlock *Pred = *PI;
PredList.push_back(std::make_pair(Pred, Pointer)); PredList.push_back(std::make_pair(Pred, Pointer));
// Get the PHI translated pointer in this predecessor. This can fail if // Get the PHI translated pointer in this predecessor. This can fail if
@ -1465,7 +1462,7 @@ void MemoryDependenceAnalysis::invalidateCachedPointerInfo(Value *Ptr) {
/// This needs to be done when the CFG changes, e.g., due to splitting /// This needs to be done when the CFG changes, e.g., due to splitting
/// critical edges. /// critical edges.
void MemoryDependenceAnalysis::invalidateCachedPredecessors() { void MemoryDependenceAnalysis::invalidateCachedPredecessors() {
PredCache->clear(); PredCache.clear();
} }
/// removeInstruction - Remove an instruction from the dependence analysis, /// removeInstruction - Remove an instruction from the dependence analysis,

View File

@ -704,10 +704,10 @@ namespace {
// We need to create an LCSSA PHI node for the incoming value and // We need to create an LCSSA PHI node for the incoming value and
// store that. // store that.
PHINode *PN = PHINode::Create( PHINode *PN = PHINode::Create(
I->getType(), PredCache.GetNumPreds(BB), I->getType(), PredCache.size(BB),
I->getName() + ".lcssa", BB->begin()); I->getName() + ".lcssa", BB->begin());
for (BasicBlock **PI = PredCache.GetPreds(BB); *PI; ++PI) for (BasicBlock *Pred : PredCache.get(BB))
PN->addIncoming(I, *PI); PN->addIncoming(I, Pred);
return PN; return PN;
} }
return V; return V;

View File

@ -112,17 +112,17 @@ static bool processInstruction(Loop &L, Instruction &Inst, DominatorTree &DT,
if (SSAUpdate.HasValueForBlock(ExitBB)) if (SSAUpdate.HasValueForBlock(ExitBB))
continue; continue;
PHINode *PN = PHINode::Create(Inst.getType(), PredCache.GetNumPreds(ExitBB), PHINode *PN = PHINode::Create(Inst.getType(), PredCache.size(ExitBB),
Inst.getName() + ".lcssa", ExitBB->begin()); Inst.getName() + ".lcssa", ExitBB->begin());
// Add inputs from inside the loop for this PHI. // Add inputs from inside the loop for this PHI.
for (BasicBlock **PI = PredCache.GetPreds(ExitBB); *PI; ++PI) { for (BasicBlock *Pred : PredCache.get(ExitBB)) {
PN->addIncoming(&Inst, *PI); PN->addIncoming(&Inst, Pred);
// If the exit block has a predecessor not within the loop, arrange for // If the exit block has a predecessor not within the loop, arrange for
// the incoming value use corresponding to that predecessor to be // the incoming value use corresponding to that predecessor to be
// rewritten in terms of a different LCSSA PHI. // rewritten in terms of a different LCSSA PHI.
if (!L.contains(*PI)) if (!L.contains(Pred))
UsesToRewrite.push_back( UsesToRewrite.push_back(
&PN->getOperandUse(PN->getOperandNumForIncomingValue( &PN->getOperandUse(PN->getOperandNumForIncomingValue(
PN->getNumIncomingValues() - 1))); PN->getNumIncomingValues() - 1)));