mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-25 03:30:37 +00:00
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:
parent
0f710d7a5a
commit
13ba3ca69f
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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)));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user