mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-30 19:55:11 +00:00
Split critical edges as needed for load PRE.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96378 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
adb6f22671
commit
484d4a30c0
@ -249,7 +249,7 @@ namespace llvm {
|
|||||||
SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
|
SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
|
||||||
ReverseDepMapType ReverseLocalDeps;
|
ReverseDepMapType ReverseLocalDeps;
|
||||||
|
|
||||||
// A reverse mapping form dependencies to the non-local dependees.
|
// A reverse mapping from dependencies to the non-local dependees.
|
||||||
ReverseDepMapType ReverseNonLocalDeps;
|
ReverseDepMapType ReverseNonLocalDeps;
|
||||||
|
|
||||||
/// Current AA implementation, just a cache.
|
/// Current AA implementation, just a cache.
|
||||||
@ -312,6 +312,11 @@ namespace llvm {
|
|||||||
/// value and replaces the other value with ptr. This can make Ptr available
|
/// value and replaces the other value with ptr. This can make Ptr available
|
||||||
/// in more places that cached info does not necessarily keep.
|
/// in more places that cached info does not necessarily keep.
|
||||||
void invalidateCachedPointerInfo(Value *Ptr);
|
void invalidateCachedPointerInfo(Value *Ptr);
|
||||||
|
|
||||||
|
/// invalidateCachedPredecessors - Clear the PredIteratorCache info.
|
||||||
|
/// This needs to be done when the CFG changes, e.g., due to splitting
|
||||||
|
/// critical edges.
|
||||||
|
void invalidateCachedPredecessors();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemDepResult getPointerDependencyFrom(Value *Pointer, uint64_t MemSize,
|
MemDepResult getPointerDependencyFrom(Value *Pointer, uint64_t MemSize,
|
||||||
|
@ -1016,6 +1016,13 @@ void MemoryDependenceAnalysis::invalidateCachedPointerInfo(Value *Ptr) {
|
|||||||
RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr, true));
|
RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// invalidateCachedPredecessors - Clear the PredIteratorCache info.
|
||||||
|
/// This needs to be done when the CFG changes, e.g., due to splitting
|
||||||
|
/// critical edges.
|
||||||
|
void MemoryDependenceAnalysis::invalidateCachedPredecessors() {
|
||||||
|
PredCache->clear();
|
||||||
|
}
|
||||||
|
|
||||||
/// removeInstruction - Remove an instruction from the dependence analysis,
|
/// removeInstruction - Remove an instruction from the dependence analysis,
|
||||||
/// updating the dependence of instructions that previously depended on it.
|
/// updating the dependence of instructions that previously depended on it.
|
||||||
/// This method attempts to keep the cache coherent using the reverse map.
|
/// This method attempts to keep the cache coherent using the reverse map.
|
||||||
|
@ -674,6 +674,9 @@ namespace {
|
|||||||
ValueTable VN;
|
ValueTable VN;
|
||||||
DenseMap<BasicBlock*, ValueNumberScope*> localAvail;
|
DenseMap<BasicBlock*, ValueNumberScope*> localAvail;
|
||||||
|
|
||||||
|
// List of critical edges to be split between iterations.
|
||||||
|
SmallVector<std::pair<TerminatorInst*, unsigned>, 4> toSplit;
|
||||||
|
|
||||||
// This transformation requires dominator postdominator info
|
// This transformation requires dominator postdominator info
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.addRequired<DominatorTree>();
|
AU.addRequired<DominatorTree>();
|
||||||
@ -701,6 +704,7 @@ namespace {
|
|||||||
Value *lookupNumber(BasicBlock *BB, uint32_t num);
|
Value *lookupNumber(BasicBlock *BB, uint32_t num);
|
||||||
void cleanupGlobalSets();
|
void cleanupGlobalSets();
|
||||||
void verifyRemoved(const Instruction *I) const;
|
void verifyRemoved(const Instruction *I) const;
|
||||||
|
bool splitCriticalEdges();
|
||||||
};
|
};
|
||||||
|
|
||||||
char GVN::ID = 0;
|
char GVN::ID = 0;
|
||||||
@ -1583,10 +1587,15 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
PredLoads[Pred] = 0;
|
PredLoads[Pred] = 0;
|
||||||
// We don't currently handle critical edges :(
|
|
||||||
if (Pred->getTerminator()->getNumSuccessors() != 1) {
|
if (Pred->getTerminator()->getNumSuccessors() != 1) {
|
||||||
DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF CRITICAL EDGE '"
|
if (isa<IndirectBrInst>(Pred->getTerminator())) {
|
||||||
<< Pred->getName() << "': " << *LI << '\n');
|
DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '"
|
||||||
|
<< Pred->getName() << "': " << *LI << '\n');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unsigned SuccNum = SuccessorNumber(Pred, LoadBB);
|
||||||
|
toSplit.push_back(std::make_pair(Pred->getTerminator(), SuccNum));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2004,6 +2013,8 @@ bool GVN::runOnFunction(Function& F) {
|
|||||||
while (ShouldContinue) {
|
while (ShouldContinue) {
|
||||||
DEBUG(dbgs() << "GVN iteration: " << Iteration << "\n");
|
DEBUG(dbgs() << "GVN iteration: " << Iteration << "\n");
|
||||||
ShouldContinue = iterateOnFunction(F);
|
ShouldContinue = iterateOnFunction(F);
|
||||||
|
if (splitCriticalEdges())
|
||||||
|
ShouldContinue = true;
|
||||||
Changed |= ShouldContinue;
|
Changed |= ShouldContinue;
|
||||||
++Iteration;
|
++Iteration;
|
||||||
}
|
}
|
||||||
@ -2070,7 +2081,6 @@ bool GVN::processBlock(BasicBlock *BB) {
|
|||||||
/// control flow patterns and attempts to perform simple PRE at the join point.
|
/// control flow patterns and attempts to perform simple PRE at the join point.
|
||||||
bool GVN::performPRE(Function &F) {
|
bool GVN::performPRE(Function &F) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
SmallVector<std::pair<TerminatorInst*, unsigned>, 4> toSplit;
|
|
||||||
DenseMap<BasicBlock*, Value*> predMap;
|
DenseMap<BasicBlock*, Value*> predMap;
|
||||||
for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()),
|
for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()),
|
||||||
DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) {
|
DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) {
|
||||||
@ -2209,11 +2219,23 @@ bool GVN::performPRE(Function &F) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SmallVector<std::pair<TerminatorInst*, unsigned>, 4>::iterator
|
if (splitCriticalEdges())
|
||||||
I = toSplit.begin(), E = toSplit.end(); I != E; ++I)
|
Changed = true;
|
||||||
SplitCriticalEdge(I->first, I->second, this);
|
|
||||||
|
|
||||||
return Changed || toSplit.size();
|
return Changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// splitCriticalEdges - Split critical edges found during the previous
|
||||||
|
/// iteration that may enable further optimization.
|
||||||
|
bool GVN::splitCriticalEdges() {
|
||||||
|
if (toSplit.empty())
|
||||||
|
return false;
|
||||||
|
do {
|
||||||
|
std::pair<TerminatorInst*, unsigned> Edge = toSplit.pop_back_val();
|
||||||
|
SplitCriticalEdge(Edge.first, Edge.second, this);
|
||||||
|
} while (!toSplit.empty());
|
||||||
|
MD->invalidateCachedPredecessors();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// iterateOnFunction - Executes one iteration of GVN
|
/// iterateOnFunction - Executes one iteration of GVN
|
||||||
|
Loading…
Reference in New Issue
Block a user