forked from OSchip/llvm-project
Add initial support for non-local memory dependence analysis.
NOTE: This has only been cursorily tested. Expected improvements soon. llvm-svn: 40476
This commit is contained in:
parent
44fd8ff400
commit
d998be79cc
|
@ -20,6 +20,7 @@
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/CallSite.h"
|
#include "llvm/Support/CallSite.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ class MemoryDependenceAnalysis : public FunctionPass {
|
||||||
|
|
||||||
Instruction* getCallSiteDependency(CallSite C, Instruction* start,
|
Instruction* getCallSiteDependency(CallSite C, Instruction* start,
|
||||||
bool local = true);
|
bool local = true);
|
||||||
|
SmallPtrSet<Instruction*, 4> nonLocalHelper(Instruction* query, BasicBlock* block);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static Instruction* NonLocal;
|
static Instruction* NonLocal;
|
||||||
|
@ -63,7 +65,9 @@ class MemoryDependenceAnalysis : public FunctionPass {
|
||||||
/// getDependency - Return the instruction on which a memory operation
|
/// getDependency - Return the instruction on which a memory operation
|
||||||
/// depends, starting with start.
|
/// depends, starting with start.
|
||||||
Instruction* getDependency(Instruction* query, Instruction* start = 0,
|
Instruction* getDependency(Instruction* query, Instruction* start = 0,
|
||||||
bool local = true);
|
BasicBlock* block = 0);
|
||||||
|
|
||||||
|
SmallPtrSet<Instruction*, 4> getNonLocalDependency(Instruction* query);
|
||||||
|
|
||||||
/// removeInstruction - Remove an instruction from the dependence analysis,
|
/// removeInstruction - Remove an instruction from the dependence analysis,
|
||||||
/// updating the dependence of instructions that previously depended on it.
|
/// updating the dependence of instructions that previously depended on it.
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
|
#include "llvm/Support/CFG.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
@ -26,7 +27,7 @@ using namespace llvm;
|
||||||
char MemoryDependenceAnalysis::ID = 0;
|
char MemoryDependenceAnalysis::ID = 0;
|
||||||
|
|
||||||
Instruction* MemoryDependenceAnalysis::NonLocal = (Instruction*)0;
|
Instruction* MemoryDependenceAnalysis::NonLocal = (Instruction*)0;
|
||||||
Instruction* MemoryDependenceAnalysis::None = (Instruction*)~0;
|
Instruction* MemoryDependenceAnalysis::None = (Instruction*)(~0 - 1);
|
||||||
|
|
||||||
// Register this pass...
|
// Register this pass...
|
||||||
static RegisterPass<MemoryDependenceAnalysis> X("memdep",
|
static RegisterPass<MemoryDependenceAnalysis> X("memdep",
|
||||||
|
@ -100,15 +101,60 @@ Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C, Instruc
|
||||||
return NonLocal;
|
return NonLocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SmallPtrSet<Instruction*, 4> MemoryDependenceAnalysis::nonLocalHelper(Instruction* query,
|
||||||
|
BasicBlock* block) {
|
||||||
|
SmallPtrSet<Instruction*, 4> 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<Instruction*, 4> pred_deps = nonLocalHelper(query, *PI);
|
||||||
|
for (SmallPtrSet<Instruction*, 4>::iterator I = pred_deps.begin(),
|
||||||
|
E = pred_deps.end(); I != E; ++I)
|
||||||
|
ret.insert(*I);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret.empty())
|
||||||
|
ret.insert(None);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallPtrSet<Instruction*, 4> MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query) {
|
||||||
|
SmallPtrSet<Instruction*, 4> 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<Instruction*, 4> pred_deps = nonLocalHelper(query, *PI);
|
||||||
|
for (SmallPtrSet<Instruction*, 4>::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
|
/// getDependency - Return the instruction on which a memory operation
|
||||||
/// depends. The local paramter indicates if the query should only
|
/// depends. The local paramter indicates if the query should only
|
||||||
/// evaluate dependencies within the same basic block.
|
/// evaluate dependencies within the same basic block.
|
||||||
Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query,
|
Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query,
|
||||||
Instruction* start,
|
Instruction* start,
|
||||||
bool local) {
|
BasicBlock* block) {
|
||||||
if (!local)
|
|
||||||
assert(0 && "Non-local memory dependence is not yet supported.");
|
|
||||||
|
|
||||||
// Start looking for dependencies with the queried inst
|
// Start looking for dependencies with the queried inst
|
||||||
BasicBlock::iterator QI = query;
|
BasicBlock::iterator QI = query;
|
||||||
|
|
||||||
|
@ -154,7 +200,8 @@ Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query,
|
||||||
else
|
else
|
||||||
return None;
|
return None;
|
||||||
|
|
||||||
BasicBlock::iterator blockBegin = query->getParent()->begin();
|
BasicBlock::iterator blockBegin = block ? block->begin()
|
||||||
|
: query->getParent()->begin();
|
||||||
|
|
||||||
while (QI != blockBegin) {
|
while (QI != blockBegin) {
|
||||||
--QI;
|
--QI;
|
||||||
|
|
Loading…
Reference in New Issue