aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h9
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp16
-rw-r--r--lib/Transforms/Scalar/GVN.cpp18
3 files changed, 41 insertions, 2 deletions
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index ceed0ab544..8a5b07e48a 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -243,6 +243,14 @@ namespace llvm {
/// updating the dependence of instructions that previously depended on it.
void removeInstruction(Instruction *InstToRemove);
+ /// invalidateCachedPointerInfo - This method is used to invalidate cached
+ /// information about the specified pointer, because it may be too
+ /// conservative in memdep. This is an optional call that can be used when
+ /// the client detects an equivalence between the pointer and some other
+ /// value and replaces the other value with ptr. This can make Ptr available
+ /// in more places that cached info does not necessarily keep.
+ void invalidateCachedPointerInfo(Value *Ptr);
+
private:
MemDepResult getPointerDependencyFrom(Value *Pointer, uint64_t MemSize,
bool isLoad,
@@ -260,7 +268,6 @@ namespace llvm {
NonLocalDepInfo *Cache,
unsigned NumSortedEntries);
-
void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
/// verifyRemoved - Verify that the specified instruction does not occur
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
index 42114938ed..0b185b1c7c 100644
--- a/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -698,6 +698,21 @@ RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P) {
}
+/// invalidateCachedPointerInfo - This method is used to invalidate cached
+/// information about the specified pointer, because it may be too
+/// conservative in memdep. This is an optional call that can be used when
+/// the client detects an equivalence between the pointer and some other
+/// value and replaces the other value with ptr. This can make Ptr available
+/// in more places that cached info does not necessarily keep.
+void MemoryDependenceAnalysis::invalidateCachedPointerInfo(Value *Ptr) {
+ // If Ptr isn't really a pointer, just ignore it.
+ if (!isa<PointerType>(Ptr->getType())) return;
+ // Flush store info for the pointer.
+ RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr, false));
+ // Flush load info for the pointer.
+ RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr, true));
+}
+
/// removeInstruction - Remove an instruction from the dependence analysis,
/// updating the dependence of instructions that previously depended on it.
/// This method attempts to keep the cache coherent using the reverse map.
@@ -864,7 +879,6 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) {
AA->deleteValue(RemInst);
DEBUG(verifyRemoved(RemInst));
}
-
/// verifyRemoved - Verify that the specified instruction does not occur
/// in our internal data structures.
void MemoryDependenceAnalysis::verifyRemoved(Instruction *D) const {
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp
index 79a0fc24e3..2081811f0d 100644
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -842,6 +842,8 @@ Value *GVN::GetValueForBlock(BasicBlock *BB, LoadInst* orig,
}
PN->replaceAllUsesWith(v);
+ if (isa<PointerType>(v->getType()))
+ MD->invalidateCachedPointerInfo(v);
for (DenseMap<BasicBlock*, Value*>::iterator I = Phis.begin(),
E = Phis.end(); I != E; ++I)
@@ -1015,6 +1017,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
if ((*I)->getParent() == LI->getParent()) {
DEBUG(cerr << "GVN REMOVING NONLOCAL LOAD #1: " << *LI);
LI->replaceAllUsesWith(*I);
+ if (isa<PointerType>((*I)->getType()))
+ MD->invalidateCachedPointerInfo(*I);
toErase.push_back(LI);
NumGVNLoad++;
return true;
@@ -1030,6 +1034,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
// Perform PHI construction.
Value* v = GetValueForBlock(LI->getParent(), LI, BlockReplValues, true);
LI->replaceAllUsesWith(v);
+ if (isa<PointerType>(v->getType()))
+ MD->invalidateCachedPointerInfo(v);
toErase.push_back(LI);
NumGVNLoad++;
return true;
@@ -1124,6 +1130,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
Value* v = GetValueForBlock(LI->getParent(), LI, BlockReplValues, true);
LI->replaceAllUsesWith(v);
v->takeName(LI);
+ if (isa<PointerType>(v->getType()))
+ MD->invalidateCachedPointerInfo(v);
toErase.push_back(LI);
NumPRELoad++;
return true;
@@ -1157,6 +1165,8 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) {
// Remove it!
L->replaceAllUsesWith(DepSI->getOperand(0));
+ if (isa<PointerType>(DepSI->getOperand(0)->getType()))
+ MD->invalidateCachedPointerInfo(DepSI->getOperand(0));
toErase.push_back(L);
NumGVNLoad++;
return true;
@@ -1170,6 +1180,8 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) {
// Remove it!
L->replaceAllUsesWith(DepLI);
+ if (isa<PointerType>(DepLI->getType()))
+ MD->invalidateCachedPointerInfo(DepLI);
toErase.push_back(L);
NumGVNLoad++;
return true;
@@ -1241,6 +1253,8 @@ bool GVN::processInstruction(Instruction *I,
PI->second.erase(p);
p->replaceAllUsesWith(constVal);
+ if (isa<PointerType>(constVal->getType()))
+ MD->invalidateCachedPointerInfo(constVal);
toErase.push_back(p);
} else {
localAvail[I->getParent()]->table.insert(std::make_pair(num, I));
@@ -1257,6 +1271,8 @@ bool GVN::processInstruction(Instruction *I,
// Remove it!
VN.erase(I);
I->replaceAllUsesWith(repl);
+ if (isa<PointerType>(repl->getType()))
+ MD->invalidateCachedPointerInfo(repl);
toErase.push_back(I);
return true;
} else {
@@ -1494,6 +1510,8 @@ bool GVN::performPRE(Function& F) {
localAvail[CurrentBlock]->table[valno] = Phi;
CurInst->replaceAllUsesWith(Phi);
+ if (isa<PointerType>(Phi->getType()))
+ MD->invalidateCachedPointerInfo(Phi);
VN.erase(CurInst);
DEBUG(cerr << "GVN PRE removed: " << *CurInst);