[llvm-commits] [llvm] r60649 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp
Chris Lattner
sabre at nondot.org
Sat Dec 6 18:15:48 PST 2008
Author: lattner
Date: Sat Dec 6 20:15:47 2008
New Revision: 60649
URL: http://llvm.org/viewvc/llvm-project?rev=60649&view=rev
Log:
Introduce a new MemDep::getNonLocalPointerDependency
method. This will eventually take over load/store dep
queries from getNonLocalDependency. For now it works
fine, but is incredibly slow because it does no caching.
Lets not switch GVN to use it until that is fixed :)
Modified:
llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h
llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60649&r1=60648&r2=60649&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Dec 6 20:15:47 2008
@@ -214,6 +214,18 @@
/// that.
const NonLocalDepInfo &getNonLocalDependency(Instruction *QueryInst);
+
+ /// getNonLocalPointerDependency - Perform a full dependency query for an
+ /// access to the specified (non-volatile) memory location, returning the
+ /// set of instructions that either define or clobber the value.
+ ///
+ /// This method assumes the pointer has a "NonLocal" dependency within BB
+ /// and assumes that Result is empty when you call it.
+ ///
+ void getNonLocalPointerDependency(Value *Pointer, bool isLoad,
+ BasicBlock *BB,
+ SmallVectorImpl<NonLocalDepEntry> &Result);
+
/// removeInstruction - Remove an instruction from the dependence analysis,
/// updating the dependence of instructions that previously depended on it.
void removeInstruction(Instruction *InstToRemove);
Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60649&r1=60648&r2=60649&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec 6 20:15:47 2008
@@ -101,8 +101,11 @@
return MemDepResult::getClobber(Inst);
}
- // No dependence found.
- return MemDepResult::getNonLocal();
+ // No dependence found. If this is the entry block of the function, it is a
+ // clobber, otherwise it is non-local.
+ if (BB != &BB->getParent()->getEntryBlock())
+ return MemDepResult::getNonLocal();
+ return MemDepResult::getClobber(ScanIt);
}
/// getPointerDependencyFrom - Return the instruction on which a memory
@@ -111,10 +114,7 @@
MemDepResult MemoryDependenceAnalysis::
getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
BasicBlock::iterator ScanIt, BasicBlock *BB) {
- // The first instruction in a block is always non-local.
- if (ScanIt == BB->begin())
- return MemDepResult::getNonLocal();
-
+
// Walk backwards through the basic block, looking for dependencies
while (ScanIt != BB->begin()) {
Instruction *Inst = --ScanIt;
@@ -174,8 +174,11 @@
return MemDepResult::getClobber(Inst);
}
- // If we found nothing, return the non-local flag.
- return MemDepResult::getNonLocal();
+ // No dependence found. If this is the entry block of the function, it is a
+ // clobber, otherwise it is non-local.
+ if (BB != &BB->getParent()->getEntryBlock())
+ return MemDepResult::getNonLocal();
+ return MemDepResult::getClobber(ScanIt);
}
/// getDependency - Return the instruction on which a memory operation
@@ -209,8 +212,12 @@
// Do the scan.
if (BasicBlock::iterator(QueryInst) == QueryParent->begin()) {
- // First instruction in the block -> non local.
- LocalCache = MemDepResult::getNonLocal();
+ // No dependence found. If this is the entry block of the function, it is a
+ // clobber, otherwise it is non-local.
+ if (QueryParent != &QueryParent->getParent()->getEntryBlock())
+ LocalCache = MemDepResult::getNonLocal();
+ else
+ LocalCache = MemDepResult::getClobber(QueryInst);
} else if (StoreInst *SI = dyn_cast<StoreInst>(QueryInst)) {
// If this is a volatile store, don't mess around with it. Just return the
// previous instruction as a clobber.
@@ -264,6 +271,7 @@
///
const MemoryDependenceAnalysis::NonLocalDepInfo &
MemoryDependenceAnalysis::getNonLocalDependency(Instruction *QueryInst) {
+ // FIXME: Make this only be for callsites in the future.
assert(isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst) ||
isa<LoadInst>(QueryInst) || isa<StoreInst>(QueryInst));
assert(getDependency(QueryInst).isNonLocal() &&
@@ -359,9 +367,13 @@
Value *MemPtr = 0;
uint64_t MemSize = 0;
- if (BasicBlock::iterator(QueryInst) == DirtyBB->begin()) {
- // First instruction in the block -> non local.
- Dep = MemDepResult::getNonLocal();
+ if (ScanPos == DirtyBB->begin()) {
+ // No dependence found. If this is the entry block of the function, it is a
+ // clobber, otherwise it is non-local.
+ if (DirtyBB != &DirtyBB->getParent()->getEntryBlock())
+ Dep = MemDepResult::getNonLocal();
+ else
+ Dep = MemDepResult::getClobber(ScanPos);
} else if (StoreInst *SI = dyn_cast<StoreInst>(QueryInst)) {
// If this is a volatile store, don't mess around with it. Just return the
// previous instruction as a clobber.
@@ -415,6 +427,63 @@
return Cache;
}
+/// getNonLocalPointerDependency - Perform a full dependency query for an
+/// access to the specified (non-volatile) memory location, returning the
+/// set of instructions that either define or clobber the value.
+///
+/// This method assumes the pointer has a "NonLocal" dependency within its
+/// own block.
+///
+void MemoryDependenceAnalysis::
+getNonLocalPointerDependency(Value *Pointer, bool isLoad, BasicBlock *FromBB,
+ SmallVectorImpl<NonLocalDepEntry> &Result) {
+ // We know that the pointer value is live into FromBB find the def/clobbers
+ // from presecessors.
+ SmallVector<std::pair<BasicBlock*, Value*>, 32> Worklist;
+
+ for (pred_iterator PI = pred_begin(FromBB), E = pred_end(FromBB); PI != E;
+ ++PI)
+ // TODO: PHI TRANSLATE.
+ Worklist.push_back(std::make_pair(*PI, Pointer));
+
+ const Type *EltTy = cast<PointerType>(Pointer->getType())->getElementType();
+ uint64_t PointeeSize = TD->getTypeStoreSize(EltTy);
+
+ // While we have blocks to analyze, get their values.
+ SmallPtrSet<BasicBlock*, 64> Visited;
+ while (!Worklist.empty()) {
+ FromBB = Worklist.back().first;
+ Pointer = Worklist.back().second;
+ Worklist.pop_back();
+
+ // Analyze the dependency of *Pointer in FromBB. See if we already have
+ // been here.
+ if (!Visited.insert(FromBB))
+ continue;
+
+ // FIXME: CACHE!
+
+ MemDepResult Dep =
+ getPointerDependencyFrom(Pointer, PointeeSize, isLoad,
+ FromBB->end(), FromBB);
+
+ // If we got a Def or Clobber, add this to the list of results.
+ if (!Dep.isNonLocal()) {
+ Result.push_back(NonLocalDepEntry(FromBB, Dep));
+ continue;
+ }
+
+ // Otherwise, we have to process all the predecessors of this block to scan
+ // them as well.
+ for (pred_iterator PI = pred_begin(FromBB), E = pred_end(FromBB); PI != E;
+ ++PI)
+ // TODO: PHI TRANSLATE.
+ Worklist.push_back(std::make_pair(*PI, Pointer));
+ }
+}
+
+
+
/// 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.
More information about the llvm-commits
mailing list