[llvm-commits] [llvm] r44695 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/GVN.cpp
Owen Anderson
resistor at mac.com
Fri Dec 7 17:37:09 PST 2007
Author: resistor
Date: Fri Dec 7 19:37:09 2007
New Revision: 44695
URL: http://llvm.org/viewvc/llvm-project?rev=44695&view=rev
Log:
Fix several cache coherence bugs in MemDep/GVN that were found. Also add some (disabled) debugging code
to make such problems easier to diagnose in the future, written by Duncan Sands.
Modified:
llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h
llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
llvm/trunk/lib/Transforms/Scalar/GVN.cpp
Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=44695&r1=44694&r2=44695&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Dec 7 19:37:09 2007
@@ -52,6 +52,8 @@
reverseDepMapType reverseDepNonLocal;
public:
+ void ping(Instruction* D);
+
// Special marker indicating that the query has no dependency
// in the specified block.
static Instruction* const NonLocal;
Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=44695&r1=44694&r2=44695&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Dec 7 19:37:09 2007
@@ -40,6 +40,31 @@
static RegisterPass<MemoryDependenceAnalysis> X("memdep",
"Memory Dependence Analysis");
+void MemoryDependenceAnalysis::ping(Instruction *D) {
+ for (depMapType::iterator I = depGraphLocal.begin(), E = depGraphLocal.end();
+ I != E; ++I) {
+ assert(I->first != D);
+ assert(I->second.first != D);
+ }
+
+ for (nonLocalDepMapType::iterator I = depGraphNonLocal.begin(), E = depGraphNonLocal.end();
+ I != E; ++I) {
+ assert(I->first != D);
+ }
+
+ for (reverseDepMapType::iterator I = reverseDep.begin(), E = reverseDep.end();
+ I != E; ++I)
+ for (SmallPtrSet<Instruction*, 4>::iterator II = I->second.begin(), EE = I->second.end();
+ II != EE; ++II)
+ assert(*II != D);
+
+ for (reverseDepMapType::iterator I = reverseDepNonLocal.begin(), E = reverseDepNonLocal.end();
+ I != E; ++I)
+ for (SmallPtrSet<Instruction*, 4>::iterator II = I->second.begin(), EE = I->second.end();
+ II != EE; ++II)
+ assert(*II != D);
+}
+
/// getAnalysisUsage - Does not modify anything. It uses Alias Analysis.
///
void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
@@ -54,6 +79,8 @@
Instruction* start,
BasicBlock* block) {
+ std::pair<Instruction*, bool>& cachedResult =
+ depGraphLocal[C.getInstruction()];
AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
TargetData& TD = getAnalysis<TargetData>();
BasicBlock::iterator blockBegin = C.getInstruction()->getParent()->begin();
@@ -100,8 +127,8 @@
if (result != AliasAnalysis::DoesNotAccessMemory &&
result != AliasAnalysis::OnlyReadsMemory) {
if (!start && !block) {
- depGraphLocal.insert(std::make_pair(C.getInstruction(),
- std::make_pair(QI, true)));
+ cachedResult.first = QI;
+ cachedResult.second = true;
reverseDep[QI].insert(C.getInstruction());
}
return QI;
@@ -113,8 +140,8 @@
if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) {
if (!start && !block) {
- depGraphLocal.insert(std::make_pair(C.getInstruction(),
- std::make_pair(QI, true)));
+ cachedResult.first = QI;
+ cachedResult.second = true;
reverseDep[QI].insert(C.getInstruction());
}
return QI;
@@ -122,8 +149,8 @@
}
// No dependence found
- depGraphLocal.insert(std::make_pair(C.getInstruction(),
- std::make_pair(NonLocal, true)));
+ cachedResult.first = NonLocal;
+ cachedResult.second = true;
reverseDep[NonLocal].insert(C.getInstruction());
return NonLocal;
}
@@ -265,13 +292,15 @@
BasicBlock::iterator QI = query;
// Check for a cached result
- std::pair<Instruction*, bool> cachedResult = depGraphLocal[query];
+ std::pair<Instruction*, bool>& cachedResult = depGraphLocal[query];
// If we have a _confirmed_ cached entry, return it
- if (cachedResult.second)
- return cachedResult.first;
- else if (cachedResult.first && cachedResult.first != NonLocal)
- // If we have an unconfirmed cached entry, we can start our search from there
- QI = cachedResult.first;
+ if (!block && !start) {
+ if (cachedResult.second)
+ return cachedResult.first;
+ else if (cachedResult.first && cachedResult.first != NonLocal)
+ // If we have an unconfirmed cached entry, we can start our search from there
+ QI = cachedResult.first;
+ }
if (start)
QI = start;
@@ -322,7 +351,8 @@
// All volatile loads/stores depend on each other
if (queryIsVolatile && S->isVolatile()) {
if (!start && !block) {
- depGraphLocal.insert(std::make_pair(query, std::make_pair(S, true)));
+ cachedResult.first = S;
+ cachedResult.second = true;
reverseDep[S].insert(query);
}
@@ -335,7 +365,8 @@
// All volatile loads/stores depend on each other
if (queryIsVolatile && L->isVolatile()) {
if (!start && !block) {
- depGraphLocal.insert(std::make_pair(query, std::make_pair(L, true)));
+ cachedResult.first = L;
+ cachedResult.second = true;
reverseDep[L].insert(query);
}
@@ -370,8 +401,8 @@
continue;
if (!start && !block) {
- depGraphLocal.insert(std::make_pair(query,
- std::make_pair(QI, true)));
+ cachedResult.first = QI;
+ cachedResult.second = true;
reverseDep[QI].insert(query);
}
@@ -393,8 +424,8 @@
continue;
if (!start && !block) {
- depGraphLocal.insert(std::make_pair(query,
- std::make_pair(QI, true)));
+ cachedResult.first = QI;
+ cachedResult.second = true;
reverseDep[QI].insert(query);
}
@@ -405,8 +436,8 @@
// If we found nothing, return the non-local flag
if (!start && !block) {
- depGraphLocal.insert(std::make_pair(query,
- std::make_pair(NonLocal, true)));
+ cachedResult.first = NonLocal;
+ cachedResult.second = true;
reverseDep[NonLocal].insert(query);
}
@@ -420,6 +451,14 @@
// Figure out the new dep for things that currently depend on rem
Instruction* newDep = NonLocal;
+ reverseDep[depGraphLocal[rem].first].erase(rem);
+
+ for (DenseMap<BasicBlock*, Value*>::iterator DI =
+ depGraphNonLocal[rem].begin(), DE = depGraphNonLocal[rem].end();
+ DI != DE; ++DI)
+ if (DI->second != None)
+ reverseDepNonLocal[DI->second].erase(rem);
+
depMapType::iterator depGraphEntry = depGraphLocal.find(rem);
if (depGraphEntry != depGraphLocal.end()) {
@@ -449,10 +488,11 @@
// Mark it as unconfirmed as long as it is not the non-local flag
depGraphLocal[*I] = std::make_pair(newDep, !newDep);
}
-
- reverseDep.erase(rem);
}
+ depGraphLocal.erase(rem);
+ reverseDep.erase(rem);
+
if (reverseDepNonLocal.count(rem)) {
SmallPtrSet<Instruction*, 4>& set = reverseDepNonLocal[rem];
for (SmallPtrSet<Instruction*, 4>::iterator I = set.begin(), E = set.end();
@@ -463,8 +503,12 @@
if (DI->second == rem)
DI->second = Dirty;
- reverseDepNonLocal.erase(rem);
}
+
+ reverseDepNonLocal.erase(rem);
+ nonLocalDepMapType::iterator I = depGraphNonLocal.find(rem);
+ if (I != depGraphNonLocal.end())
+ depGraphNonLocal.erase(I);
getAnalysis<AliasAnalysis>().deleteValue(rem);
}
Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=44695&r1=44694&r2=44695&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Dec 7 19:37:09 2007
@@ -1062,6 +1062,10 @@
}
}
+ // Remove it!
+ MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
+ MD.removeInstruction(I);
+
VN.erase(I);
I->replaceAllUsesWith(repl);
toErase.push_back(I);
@@ -1128,11 +1132,11 @@
// Avoid iterator invalidation
++BI;
-
+
for (SmallVector<Instruction*, 4>::iterator I = toErase.begin(),
E = toErase.end(); I != E; ++I)
(*I)->eraseFromParent();
-
+
toErase.clear();
}
}
More information about the llvm-commits
mailing list