diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index 014922e1555..8f4fca0effc 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -20,6 +20,7 @@ #include "llvm/Pass.h" #include "llvm/Support/CallSite.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/Compiler.h" #include @@ -37,6 +38,7 @@ class MemoryDependenceAnalysis : public FunctionPass { Instruction* getCallSiteDependency(CallSite C, Instruction* start, bool local = true); + SmallPtrSet nonLocalHelper(Instruction* query, BasicBlock* block); public: static Instruction* NonLocal; @@ -63,7 +65,9 @@ class MemoryDependenceAnalysis : public FunctionPass { /// getDependency - Return the instruction on which a memory operation /// depends, starting with start. Instruction* getDependency(Instruction* query, Instruction* start = 0, - bool local = true); + BasicBlock* block = 0); + + SmallPtrSet getNonLocalDependency(Instruction* query); /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 3ec733f9e4c..34c43484bfe 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -19,6 +19,7 @@ #include "llvm/Instructions.h" #include "llvm/Function.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Support/CFG.h" #include "llvm/Target/TargetData.h" using namespace llvm; @@ -26,7 +27,7 @@ using namespace llvm; char MemoryDependenceAnalysis::ID = 0; Instruction* MemoryDependenceAnalysis::NonLocal = (Instruction*)0; -Instruction* MemoryDependenceAnalysis::None = (Instruction*)~0; +Instruction* MemoryDependenceAnalysis::None = (Instruction*)(~0 - 1); // Register this pass... static RegisterPass X("memdep", @@ -100,15 +101,60 @@ Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C, Instruc return NonLocal; } +SmallPtrSet MemoryDependenceAnalysis::nonLocalHelper(Instruction* query, + BasicBlock* block) { + SmallPtrSet ret; + + Instruction* localDep = getDependency(query, block->end(), block); + if (localDep != NonLocal) { + ret.insert(localDep); + return ret; + } + + for (pred_iterator PI = pred_begin(block), PE = pred_end(block); + PI != PE; ++PI) { + SmallPtrSet pred_deps = nonLocalHelper(query, *PI); + for (SmallPtrSet::iterator I = pred_deps.begin(), + E = pred_deps.end(); I != E; ++I) + ret.insert(*I); + } + + if (ret.empty()) + ret.insert(None); + + return ret; +} + +SmallPtrSet MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query) { + SmallPtrSet ret; + + Instruction* localDep = getDependency(query); + if (localDep != NonLocal) { + ret.insert(localDep); + return ret; + } + + BasicBlock* parent = query->getParent(); + for (pred_iterator PI = pred_begin(parent), PE = pred_end(parent); + PI != PE; ++PI) { + SmallPtrSet pred_deps = nonLocalHelper(query, *PI); + for (SmallPtrSet::iterator I = pred_deps.begin(), + E = pred_deps.end(); I != E; ++I) + ret.insert(*I); + } + + if (ret.empty()) + ret.insert(None); + + return ret; +} + /// 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. Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query, Instruction* start, - bool local) { - if (!local) - assert(0 && "Non-local memory dependence is not yet supported."); - + BasicBlock* block) { // Start looking for dependencies with the queried inst BasicBlock::iterator QI = query; @@ -154,7 +200,8 @@ Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query, else return None; - BasicBlock::iterator blockBegin = query->getParent()->begin(); + BasicBlock::iterator blockBegin = block ? block->begin() + : query->getParent()->begin(); while (QI != blockBegin) { --QI;