diff options
author | Owen Anderson <resistor@mac.com> | 2007-07-10 17:59:22 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2007-07-10 17:59:22 +0000 |
commit | 5f323207971da23e2f78dd61d383e9d506fd9d6c (patch) | |
tree | 1a5fa33df49bd58c96936ef86e6187f26dced0b1 /lib/Analysis/MemoryDependenceAnalysis.cpp | |
parent | 5e2456c95996338ad7ed461b8ce4d21cb9d70a0b (diff) |
Add support for finding the dependencies of call and invoke instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@38497 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/MemoryDependenceAnalysis.cpp')
-rw-r--r-- | lib/Analysis/MemoryDependenceAnalysis.cpp | 81 |
1 files changed, 64 insertions, 17 deletions
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 8c6886da90..283b6b7f5d 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -40,6 +40,61 @@ void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequiredTransitive<TargetData>(); } +// Find the dependency of a CallSite +Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C, bool local) { + assert(local && "Non-local memory dependence analysis not yet implemented"); + + AliasAnalysis& AA = getAnalysis<AliasAnalysis>(); + TargetData& TD = getAnalysis<TargetData>(); + BasicBlock::iterator blockBegin = C.getInstruction()->getParent()->begin(); + BasicBlock::iterator QI = C.getInstruction(); + + while (QI != blockBegin) { + --QI; + + // 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)) { + pointer = S->getPointerOperand(); + pointerSize = TD.getTypeSize(S->getOperand(0)->getType()); + } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) { + pointer = L->getPointerOperand(); + pointerSize = TD.getTypeSize(L->getType()); + } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) { + pointer = AI; + if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize())) + pointerSize = C->getZExtValue(); + else + pointerSize = ~0UL; + } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) { + pointer = F->getPointerOperand(); + + // FreeInsts erase the entire structure + pointerSize = ~0UL; + } else if (CallSite::get(QI).getInstruction() != 0) { + if (AA.getModRefInfo(C, CallSite::get(QI)) != AliasAnalysis::NoModRef) { + depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(QI, true))); + reverseDep.insert(std::make_pair(QI, C.getInstruction())); + return QI; + } else { + continue; + } + } + + if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) { + depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(QI, true))); + reverseDep.insert(std::make_pair(QI, C.getInstruction())); + return QI; + } + } + + // No dependence found + depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(NonLocal, true))); + reverseDep.insert(std::make_pair(NonLocal, C.getInstruction())); + return NonLocal; +} + /// getDependency - Return the instruction on which a memory operation /// depends. The local paramter indicates if the query should only /// evaluate dependencies within the same basic block. @@ -77,13 +132,13 @@ Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query, // FreeInsts erase the entire structure, not just a field dependeeSize = ~0UL; - } else if (isa<AllocationInst>(query)) + } else if (CallSite::get(QI).getInstruction() != 0) + return getCallSiteDependency(CallSite::get(QI)); + else if (isa<AllocationInst>(query)) return None; else - // FIXME: Call/InvokeInsts need proper handling return None; - BasicBlock::iterator blockBegin = query->getParent()->begin(); while (QI != blockBegin) { @@ -109,21 +164,13 @@ Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query, // FreeInsts erase the entire structure pointerSize = ~0UL; - } else if (CallInst* C = dyn_cast<CallInst>(QI)) { + } else if (CallSite::get(QI).getInstruction() != 0) { // Call insts need special handling. Check is they can modify our pointer - if (AA.getModRefInfo(C, dependee, dependeeSize) != AliasAnalysis::NoModRef) { - depGraphLocal.insert(std::make_pair(query, std::make_pair(C, true))); - reverseDep.insert(std::make_pair(C, query)); - return C; - } else { - continue; - } - } else if (InvokeInst* I = dyn_cast<InvokeInst>(QI)) { - // Invoke insts need special handling. Check is they can modify our pointer - if (AA.getModRefInfo(I, dependee, dependeeSize) != AliasAnalysis::NoModRef) { - depGraphLocal.insert(std::make_pair(query, std::make_pair(I, true))); - reverseDep.insert(std::make_pair(I, query)); - return I; + if (AA.getModRefInfo(CallSite::get(QI), dependee, dependeeSize) != + AliasAnalysis::NoModRef) { + depGraphLocal.insert(std::make_pair(query, std::make_pair(QI, true))); + reverseDep.insert(std::make_pair(QI, query)); + return QI; } else { continue; } |