[llvm-commits] [llvm] r60234 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/DeadStoreElimination.cpp lib/Transforms/Scalar/GVN.cpp
Chris Lattner
sabre at nondot.org
Fri Nov 28 19:47:00 PST 2008
Author: lattner
Date: Fri Nov 28 21:47:00 2008
New Revision: 60234
URL: http://llvm.org/viewvc/llvm-project?rev=60234&view=rev
Log:
Split getDependency into getDependency and getDependencyFrom, the
former does caching, the later doesn't. This dramatically simplifies
the logic in getDependency and getDependencyFrom.
Modified:
llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h
llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.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=60234&r1=60233&r2=60234&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Nov 28 21:47:00 2008
@@ -14,6 +14,7 @@
#ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
#define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
+#include "llvm/BasicBlock.h"
#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -156,9 +157,15 @@
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
/// getDependency - Return the instruction on which a memory operation
- /// depends, starting with start.
- MemDepResult getDependency(Instruction *query, Instruction *start = 0,
- BasicBlock *block = 0);
+ /// depends.
+ MemDepResult getDependency(Instruction *QueryInst);
+
+ /// getDependencyFrom - Return the instruction on which the memory operation
+ /// 'QueryInst' depends. This starts scanning from the instruction before
+ /// the position indicated by ScanIt.
+ MemDepResult getDependencyFrom(Instruction *QueryInst,
+ BasicBlock::iterator ScanIt, BasicBlock *BB);
+
/// getNonLocalDependency - Fills the passed-in map with the non-local
/// dependencies of the queries. The map will contain NonLocal for
@@ -199,8 +206,8 @@
/// in our internal data structures.
void verifyRemoved(Instruction *Inst) const;
- MemDepResult getCallSiteDependency(CallSite C, Instruction* start,
- BasicBlock* block);
+ MemDepResult getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt,
+ BasicBlock *BB);
void nonLocalHelper(Instruction* query, BasicBlock* block,
DenseMap<BasicBlock*, DepResultTy> &resp);
};
Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60234&r1=60233&r2=60234&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Nov 28 21:47:00 2008
@@ -87,74 +87,49 @@
/// getCallSiteDependency - Private helper for finding the local dependencies
/// of a call site.
MemDepResult MemoryDependenceAnalysis::
-getCallSiteDependency(CallSite C, Instruction *start, BasicBlock *block) {
- DepResultTy &cachedResult = LocalDeps[C.getInstruction()];
+getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt,
+ BasicBlock *BB) {
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
TargetData &TD = getAnalysis<TargetData>();
- BasicBlock::iterator blockBegin = C.getInstruction()->getParent()->begin();
- BasicBlock::iterator QI = C.getInstruction();
-
- // If the starting point was specified, use it
- if (start) {
- QI = start;
- blockBegin = start->getParent()->begin();
- // If the starting point wasn't specified, but the block was, use it
- } else if (!start && block) {
- QI = block->end();
- blockBegin = block->begin();
- }
// Walk backwards through the block, looking for dependencies
- while (QI != blockBegin) {
- --QI;
+ while (ScanIt != BB->begin()) {
+ Instruction *Inst = --ScanIt;
// If this inst is a memory op, get the pointer it accessed
Value* pointer = 0;
uint64_t pointerSize = 0;
- if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
+ if (StoreInst* S = dyn_cast<StoreInst>(Inst)) {
pointer = S->getPointerOperand();
pointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType());
- } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
+ } else if (AllocationInst* AI = dyn_cast<AllocationInst>(Inst)) {
pointer = AI;
if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
pointerSize = C->getZExtValue() *
TD.getABITypeSize(AI->getAllocatedType());
else
pointerSize = ~0UL;
- } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
+ } else if (VAArgInst* V = dyn_cast<VAArgInst>(Inst)) {
pointer = V->getOperand(0);
pointerSize = TD.getTypeStoreSize(V->getType());
- } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
+ } else if (FreeInst* F = dyn_cast<FreeInst>(Inst)) {
pointer = F->getPointerOperand();
// FreeInsts erase the entire structure
pointerSize = ~0UL;
- } else if (CallSite::get(QI).getInstruction() != 0) {
- AliasAnalysis::ModRefBehavior result =
- AA.getModRefBehavior(CallSite::get(QI));
- if (result != AliasAnalysis::DoesNotAccessMemory) {
- if (!start && !block) {
- cachedResult = DepResultTy(QI, Normal);
- reverseDep[QI].insert(C.getInstruction());
- }
- return MemDepResult::get(QI);
- } else {
- continue;
- }
+ } else if (CallSite::get(Inst).getInstruction() != 0) {
+ if (AA.getModRefBehavior(CallSite::get(Inst)) !=
+ AliasAnalysis::DoesNotAccessMemory)
+ return MemDepResult::get(Inst);
+ continue;
} else
continue;
- if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) {
- if (!start && !block) {
- cachedResult = DepResultTy(QI, Normal);
- reverseDep[QI].insert(C.getInstruction());
- }
- return MemDepResult::get(QI);
- }
+ if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef)
+ return MemDepResult::get(Inst);
}
- // No dependence found
- cachedResult = DepResultTy(0, NonLocal);
+ // No dependence found.
return MemDepResult::getNonLocal();
}
@@ -193,7 +168,7 @@
if (BB != block) {
visited.insert(BB);
- MemDepResult localDep = getDependency(query, 0, BB);
+ MemDepResult localDep = getDependencyFrom(query, BB->end(), BB);
if (!localDep.isNonLocal()) {
resp.insert(std::make_pair(BB, ConvFromResult(localDep)));
stack.pop_back();
@@ -205,7 +180,7 @@
} else if (BB == block) {
visited.insert(BB);
- MemDepResult localDep = getDependency(query, 0, BB);
+ MemDepResult localDep = getDependencyFrom(query, BB->end(), BB);
if (localDep.getInst() != query)
resp.insert(std::make_pair(BB, ConvFromResult(localDep)));
@@ -262,7 +237,7 @@
for (SmallVector<BasicBlock*, 4>::iterator I = dirtied.begin(),
E = dirtied.end(); I != E; ++I) {
- MemDepResult localDep = getDependency(query, 0, *I);
+ MemDepResult localDep = getDependencyFrom(query, (*I)->end(), *I);
if (!localDep.isNonLocal())
cached[*I] = ConvFromResult(localDep);
else {
@@ -303,127 +278,86 @@
/// evaluate dependencies within the same basic block.
/// FIXME: ELIMINATE START/BLOCK and make the caching happen in a higher level
/// METHOD.
-MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *query,
- Instruction *start,
- BasicBlock *block) {
- // Start looking for dependencies with the queried inst
- BasicBlock::iterator QI = query;
-
- // Check for a cached result
- // FIXME: why do this when Block or Start is specified??
- DepResultTy &cachedResult = LocalDeps[query];
-
- if (start)
- QI = start;
- else if (block)
- QI = block->end();
- else if (cachedResult.getInt() != Dirty) {
- // If we have a _confirmed_ cached entry, return it.
- return ConvToResult(cachedResult);
- } else if (Instruction *Inst = cachedResult.getPointer()) {
- // If we have an unconfirmed cached entry, we can start our search from it.
- QI = Inst;
- }
-
- AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
- TargetData& TD = getAnalysis<TargetData>();
+MemDepResult MemoryDependenceAnalysis::
+getDependencyFrom(Instruction *QueryInst, BasicBlock::iterator ScanIt,
+ BasicBlock *BB) {
+ AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+ TargetData &TD = getAnalysis<TargetData>();
// Get the pointer value for which dependence will be determined
Value* dependee = 0;
uint64_t dependeeSize = 0;
bool queryIsVolatile = false;
- if (StoreInst* S = dyn_cast<StoreInst>(query)) {
+
+ if (StoreInst* S = dyn_cast<StoreInst>(QueryInst)) {
dependee = S->getPointerOperand();
dependeeSize = TD.getTypeStoreSize(S->getOperand(0)->getType());
queryIsVolatile = S->isVolatile();
- } else if (LoadInst* L = dyn_cast<LoadInst>(query)) {
+ } else if (LoadInst* L = dyn_cast<LoadInst>(QueryInst)) {
dependee = L->getPointerOperand();
dependeeSize = TD.getTypeStoreSize(L->getType());
queryIsVolatile = L->isVolatile();
- } else if (VAArgInst* V = dyn_cast<VAArgInst>(query)) {
+ } else if (VAArgInst* V = dyn_cast<VAArgInst>(QueryInst)) {
dependee = V->getOperand(0);
dependeeSize = TD.getTypeStoreSize(V->getType());
- } else if (FreeInst* F = dyn_cast<FreeInst>(query)) {
+ } else if (FreeInst* F = dyn_cast<FreeInst>(QueryInst)) {
dependee = F->getPointerOperand();
-
// FreeInsts erase the entire structure, not just a field
dependeeSize = ~0UL;
- } else if (CallSite::get(query).getInstruction() != 0)
- return getCallSiteDependency(CallSite::get(query), start, block);
- else if (isa<AllocationInst>(query))
- return MemDepResult::getNone();
+ } else if (CallSite::get(QueryInst).getInstruction() != 0)
+ return getCallSiteDependency(CallSite::get(QueryInst), ScanIt, BB);
else
return MemDepResult::getNone();
- BasicBlock::iterator blockBegin = block ? block->begin()
- : query->getParent()->begin();
-
// Walk backwards through the basic block, looking for dependencies
- while (QI != blockBegin) {
- --QI;
+ while (ScanIt != BB->begin()) {
+ Instruction *Inst = --ScanIt;
// If this inst is a memory op, get the pointer it accessed
Value* pointer = 0;
uint64_t pointerSize = 0;
- if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
+ if (StoreInst* S = dyn_cast<StoreInst>(Inst)) {
// All volatile loads/stores depend on each other
- if (queryIsVolatile && S->isVolatile()) {
- if (!start && !block) {
- cachedResult = DepResultTy(S, Normal);
- reverseDep[S].insert(query);
- }
-
+ if (queryIsVolatile && S->isVolatile())
return MemDepResult::get(S);
- }
pointer = S->getPointerOperand();
pointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType());
- } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
+ } else if (LoadInst* L = dyn_cast<LoadInst>(Inst)) {
// All volatile loads/stores depend on each other
- if (queryIsVolatile && L->isVolatile()) {
- if (!start && !block) {
- cachedResult = DepResultTy(L, Normal);
- reverseDep[L].insert(query);
- }
-
+ if (queryIsVolatile && L->isVolatile())
return MemDepResult::get(L);
- }
pointer = L->getPointerOperand();
pointerSize = TD.getTypeStoreSize(L->getType());
- } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
+ } else if (AllocationInst* AI = dyn_cast<AllocationInst>(Inst)) {
pointer = AI;
if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
pointerSize = C->getZExtValue() *
TD.getABITypeSize(AI->getAllocatedType());
else
pointerSize = ~0UL;
- } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
+ } else if (VAArgInst* V = dyn_cast<VAArgInst>(Inst)) {
pointer = V->getOperand(0);
pointerSize = TD.getTypeStoreSize(V->getType());
- } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
+ } else if (FreeInst* F = dyn_cast<FreeInst>(Inst)) {
pointer = F->getPointerOperand();
// FreeInsts erase the entire structure
pointerSize = ~0UL;
- } else if (CallSite::get(QI).getInstruction() != 0) {
+ } else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {
// Call insts need special handling. Check if they can modify our pointer
- AliasAnalysis::ModRefResult MR = AA.getModRefInfo(CallSite::get(QI),
+ AliasAnalysis::ModRefResult MR = AA.getModRefInfo(CallSite::get(Inst),
dependee, dependeeSize);
if (MR != AliasAnalysis::NoModRef) {
// Loads don't depend on read-only calls
- if (isa<LoadInst>(query) && MR == AliasAnalysis::Ref)
+ if (isa<LoadInst>(QueryInst) && MR == AliasAnalysis::Ref)
continue;
-
- if (!start && !block) {
- cachedResult = DepResultTy(QI, Normal);
- reverseDep[QI].insert(query);
- }
- return MemDepResult::get(QI);
- } else {
- continue;
+ return MemDepResult::get(Inst);
}
+
+ continue;
}
// If we found a pointer, check if it could be the same as our pointer
@@ -433,27 +367,49 @@
if (R != AliasAnalysis::NoAlias) {
// May-alias loads don't depend on each other
- if (isa<LoadInst>(query) && isa<LoadInst>(QI) &&
+ if (isa<LoadInst>(QueryInst) && isa<LoadInst>(Inst) &&
R == AliasAnalysis::MayAlias)
continue;
-
- if (!start && !block) {
- cachedResult = DepResultTy(QI, Normal);
- reverseDep[QI].insert(query);
- }
-
- return MemDepResult::get(QI);
+ return MemDepResult::get(Inst);
}
}
}
- // If we found nothing, return the non-local flag
- if (!start && !block)
- cachedResult = DepResultTy(0, NonLocal);
-
+ // If we found nothing, return the non-local flag.
return MemDepResult::getNonLocal();
}
+/// getDependency - Return the instruction on which a memory operation
+/// depends.
+MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) {
+ Instruction *ScanPos = QueryInst;
+
+ // Check for a cached result
+ DepResultTy &LocalCache = LocalDeps[QueryInst];
+
+ // If the cached entry is non-dirty, just return it.
+ if (LocalCache.getInt() != Dirty)
+ return ConvToResult(LocalCache);
+
+ // Otherwise, if we have a dirty entry, we know we can start the scan at that
+ // instruction, which may save us some work.
+ if (Instruction *Inst = LocalCache.getPointer())
+ ScanPos = Inst;
+
+ // Do the scan.
+ MemDepResult Res =
+ getDependencyFrom(QueryInst, ScanPos, QueryInst->getParent());
+
+ // Remember the result!
+ // FIXME: Don't convert back and forth! Make a shared helper function.
+ LocalCache = ConvFromResult(Res);
+ if (Instruction *I = Res.getInst())
+ reverseDep[I].insert(QueryInst);
+
+ return Res;
+}
+
+
/// dropInstruction - Remove an instruction from the analysis, making
/// absolutely conservative assumptions when updating the cache. This is
/// useful, for example when an instruction is changed rather than removed.
Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=60234&r1=60233&r2=60234&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Fri Nov 28 21:47:00 2008
@@ -116,7 +116,7 @@
if (DepStore != last ||
TD.getTypeStoreSize(last->getOperand(0)->getType()) >
TD.getTypeStoreSize(Inst->getOperand(0)->getType())) {
- dep = MD.getDependency(Inst, DepStore);
+ dep = MD.getDependencyFrom(Inst, DepStore, DepStore->getParent());
continue;
}
Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60234&r1=60233&r2=60234&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Nov 28 21:47:00 2008
@@ -990,7 +990,7 @@
break;
} else {
- dep = MD.getDependency(L, DepInst);
+ dep = MD.getDependencyFrom(L, DepInst, DepInst->getParent());
}
}
More information about the llvm-commits
mailing list