From 1f5fb875b6724029fbf1f1d7be68c2058b19f771 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Tue, 10 Jul 2007 17:59:22 +0000 Subject: [PATCH] Add support for finding the dependencies of call and invoke instructions. llvm-svn: 38497 --- .../llvm/Analysis/MemoryDependenceAnalysis.h | 2 + lib/Analysis/MemoryDependenceAnalysis.cpp | 81 +++++++++++++++---- 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index 572d24129bf..00f5587d23b 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -18,6 +18,7 @@ #define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H #include "llvm/Pass.h" +#include "llvm/Support/CallSite.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Compiler.h" #include @@ -34,6 +35,7 @@ class MemoryDependenceAnalysis : public FunctionPass { DenseMap > depGraphLocal; std::multimap reverseDep; + Instruction* getCallSiteDependency(CallSite C, bool local = true); public: static Instruction* NonLocal; diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 8c6886da902..283b6b7f5df 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -40,6 +40,61 @@ void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequiredTransitive(); } +// 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(); + TargetData& TD = getAnalysis(); + 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(QI)) { + pointer = S->getPointerOperand(); + pointerSize = TD.getTypeSize(S->getOperand(0)->getType()); + } else if (LoadInst* L = dyn_cast(QI)) { + pointer = L->getPointerOperand(); + pointerSize = TD.getTypeSize(L->getType()); + } else if (AllocationInst* AI = dyn_cast(QI)) { + pointer = AI; + if (ConstantInt* C = dyn_cast(AI->getArraySize())) + pointerSize = C->getZExtValue(); + else + pointerSize = ~0UL; + } else if (FreeInst* F = dyn_cast(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(query)) + } else if (CallSite::get(QI).getInstruction() != 0) + return getCallSiteDependency(CallSite::get(QI)); + else if (isa(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(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(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; }