aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/MemoryDependenceAnalysis.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-11-29 09:09:48 +0000
committerChris Lattner <sabre@nondot.org>2008-11-29 09:09:48 +0000
commita161ab06d9e194bbc048b04998e64a8f8a14e49c (patch)
tree1183b60e5f81d820e0687250d4de1f053c517458 /lib/Analysis/MemoryDependenceAnalysis.cpp
parent10ca770020e12cf86d43f7b15cb6959e380e935d (diff)
eliminate a bunch of code in favor of using AliasAnalysis::getModRefInfo.
Put a some code back to handle buggy behavior that GVN expects: it wants loads to depend on each other, and accesses to depend on their allocations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60240 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/MemoryDependenceAnalysis.cpp')
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp92
1 files changed, 45 insertions, 47 deletions
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
index 18e5a6aa8a..fdc14bdb19 100644
--- a/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -310,68 +310,66 @@ getDependencyFrom(Instruction *QueryInst, BasicBlock::iterator ScanIt,
// Walk backwards through the basic block, looking for dependencies
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>(Inst)) {
- // All volatile loads/stores depend on each other.
- if (MemVolatile && S->isVolatile())
- return MemDepResult::get(S);
+
+ // If the access is volatile and this is a volatile load/store, return a
+ // dependence.
+ if (MemVolatile &&
+ ((isa<LoadInst>(Inst) && cast<LoadInst>(Inst)->isVolatile()) ||
+ (isa<StoreInst>(Inst) && cast<StoreInst>(Inst)->isVolatile())))
+ return MemDepResult::get(Inst);
+
+ // MemDep is broken w.r.t. loads: it says that two loads of the same pointer
+ // depend on each other. :(
+ // FIXME: ELIMINATE THIS!
+ if (LoadInst *L = dyn_cast<LoadInst>(Inst)) {
+ Value *Pointer = L->getPointerOperand();
+ uint64_t PointerSize = TD.getTypeStoreSize(L->getType());
- Pointer = S->getPointerOperand();
- PointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType());
- } else if (LoadInst *L = dyn_cast<LoadInst>(Inst)) {
- // All volatile loads/stores depend on each other
- if (MemVolatile && L->isVolatile())
- return MemDepResult::get(L);
+ // If we found a pointer, check if it could be the same as our pointer
+ AliasAnalysis::AliasResult R =
+ AA.alias(Pointer, PointerSize, MemPtr, MemSize);
- Pointer = L->getPointerOperand();
- PointerSize = TD.getTypeStoreSize(L->getType());
- } else if (AllocationInst *AI = dyn_cast<AllocationInst>(Inst)) {
- Pointer = AI;
+ if (R == AliasAnalysis::NoAlias)
+ continue;
+
+ // May-alias loads don't depend on each other without a dependence.
+ if (isa<LoadInst>(QueryInst) && R == AliasAnalysis::MayAlias)
+ continue;
+ return MemDepResult::get(Inst);
+ }
+
+ // FIXME: This claims that an access depends on the allocation. This may
+ // make sense, but is dubious at best. It would be better to fix GVN to
+ // handle a 'None' Query.
+ if (AllocationInst *AI = dyn_cast<AllocationInst>(Inst)) {
+ Value *Pointer = AI;
+ uint64_t PointerSize;
if (ConstantInt *C = dyn_cast<ConstantInt>(AI->getArraySize()))
PointerSize = C->getZExtValue() *
- TD.getTypeStoreSize(AI->getAllocatedType());
+ TD.getTypeStoreSize(AI->getAllocatedType());
else
PointerSize = ~0UL;
- } else if (VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {
- Pointer = V->getOperand(0);
- PointerSize = TD.getTypeStoreSize(V->getType());
- } else if (FreeInst *F = dyn_cast<FreeInst>(Inst)) {
- Pointer = F->getPointerOperand();
- // FreeInsts erase the entire structure.
- PointerSize = ~0UL;
- } else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {
- // Calls need special handling. Check if they can modify our pointer.
- AliasAnalysis::ModRefResult MR =
- AA.getModRefInfo(CallSite::get(Inst), MemPtr, MemSize);
+ AliasAnalysis::AliasResult R =
+ AA.alias(Pointer, PointerSize, MemPtr, MemSize);
- if (MR == AliasAnalysis::NoModRef)
+ if (R == AliasAnalysis::NoAlias)
continue;
-
- // Loads don't depend on read-only calls
- if (isa<LoadInst>(QueryInst) && MR == AliasAnalysis::Ref)
- continue;
-
return MemDepResult::get(Inst);
- } else {
- // Non memory instruction, move to the next one.
- continue;
}
-
- // If we found a pointer, check if it could be the same as our pointer
- AliasAnalysis::AliasResult R =
- AA.alias(Pointer, PointerSize, MemPtr, MemSize);
- if (R == AliasAnalysis::NoAlias)
+
+ // See if this instruction mod/ref's the pointer.
+ AliasAnalysis::ModRefResult MRR = AA.getModRefInfo(Inst, MemPtr, MemSize);
+
+ if (MRR == AliasAnalysis::NoModRef)
continue;
- // May-alias loads don't depend on each other without a dependence.
- if (isa<LoadInst>(QueryInst) && isa<LoadInst>(Inst) &&
- R == AliasAnalysis::MayAlias)
+ // Loads don't depend on read-only instructions.
+ if (isa<LoadInst>(QueryInst) && MRR == AliasAnalysis::Ref)
continue;
+
+ // Otherwise, there is a dependence.
return MemDepResult::get(Inst);
}