diff options
author | Chris Lattner <sabre@nondot.org> | 2008-11-29 09:09:48 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-11-29 09:09:48 +0000 |
commit | a161ab06d9e194bbc048b04998e64a8f8a14e49c (patch) | |
tree | 1183b60e5f81d820e0687250d4de1f053c517458 /lib/Analysis/MemoryDependenceAnalysis.cpp | |
parent | 10ca770020e12cf86d43f7b15cb6959e380e935d (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.cpp | 92 |
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); } |