aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2007-07-10 17:59:22 +0000
committerOwen Anderson <resistor@mac.com>2007-07-10 17:59:22 +0000
commit5f323207971da23e2f78dd61d383e9d506fd9d6c (patch)
tree1a5fa33df49bd58c96936ef86e6187f26dced0b1
parent5e2456c95996338ad7ed461b8ce4d21cb9d70a0b (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
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h2
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp81
2 files changed, 66 insertions, 17 deletions
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index 572d24129b..00f5587d23 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 <map>
@@ -34,6 +35,7 @@ class MemoryDependenceAnalysis : public FunctionPass {
DenseMap<Instruction*, std::pair<Instruction*, bool> > depGraphLocal;
std::multimap<Instruction*, Instruction*> 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 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;
}