forked from OSchip/llvm-project
Cache TargetData/AliasAnalysis in the pass instead of calling
getAnalysis<>. getAnalysis<> is apparently extremely expensive. Doing this speeds up GVN on 403.gcc by 16%! llvm-svn: 60304
This commit is contained in:
parent
15b598618e
commit
13cae612b9
|
@ -25,6 +25,8 @@ namespace llvm {
|
||||||
class FunctionPass;
|
class FunctionPass;
|
||||||
class Instruction;
|
class Instruction;
|
||||||
class CallSite;
|
class CallSite;
|
||||||
|
class AliasAnalysis;
|
||||||
|
class TargetData;
|
||||||
|
|
||||||
/// MemDepResult - A memory dependence query can return one of three different
|
/// MemDepResult - A memory dependence query can return one of three different
|
||||||
/// answers:
|
/// answers:
|
||||||
|
@ -148,13 +150,15 @@ namespace llvm {
|
||||||
// A reverse mapping form dependencies to the non-local dependees.
|
// A reverse mapping form dependencies to the non-local dependees.
|
||||||
ReverseDepMapType ReverseNonLocalDeps;
|
ReverseDepMapType ReverseNonLocalDeps;
|
||||||
|
|
||||||
|
/// Current AA implementation, just a cache.
|
||||||
|
AliasAnalysis *AA;
|
||||||
|
TargetData *TD;
|
||||||
public:
|
public:
|
||||||
MemoryDependenceAnalysis() : FunctionPass(&ID) {}
|
MemoryDependenceAnalysis() : FunctionPass(&ID) {}
|
||||||
static char ID;
|
static char ID;
|
||||||
|
|
||||||
/// Pass Implementation stuff. This doesn't do any analysis.
|
/// Pass Implementation stuff. This doesn't do any analysis eagerly.
|
||||||
///
|
bool runOnFunction(Function &);
|
||||||
bool runOnFunction(Function &) {return false; }
|
|
||||||
|
|
||||||
/// Clean up memory in between runs
|
/// Clean up memory in between runs
|
||||||
void releaseMemory() {
|
void releaseMemory() {
|
||||||
|
|
|
@ -45,14 +45,17 @@ void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.addRequiredTransitive<TargetData>();
|
AU.addRequiredTransitive<TargetData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MemoryDependenceAnalysis::runOnFunction(Function &) {
|
||||||
|
AA = &getAnalysis<AliasAnalysis>();
|
||||||
|
TD = &getAnalysis<TargetData>();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// getCallSiteDependency - Private helper for finding the local dependencies
|
/// getCallSiteDependency - Private helper for finding the local dependencies
|
||||||
/// of a call site.
|
/// of a call site.
|
||||||
MemoryDependenceAnalysis::DepResultTy MemoryDependenceAnalysis::
|
MemoryDependenceAnalysis::DepResultTy MemoryDependenceAnalysis::
|
||||||
getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt,
|
getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt,
|
||||||
BasicBlock *BB) {
|
BasicBlock *BB) {
|
||||||
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
|
|
||||||
TargetData &TD = getAnalysis<TargetData>();
|
|
||||||
|
|
||||||
// Walk backwards through the block, looking for dependencies
|
// Walk backwards through the block, looking for dependencies
|
||||||
while (ScanIt != BB->begin()) {
|
while (ScanIt != BB->begin()) {
|
||||||
Instruction *Inst = --ScanIt;
|
Instruction *Inst = --ScanIt;
|
||||||
|
@ -62,17 +65,17 @@ getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt,
|
||||||
uint64_t PointerSize = 0;
|
uint64_t PointerSize = 0;
|
||||||
if (StoreInst *S = dyn_cast<StoreInst>(Inst)) {
|
if (StoreInst *S = dyn_cast<StoreInst>(Inst)) {
|
||||||
Pointer = S->getPointerOperand();
|
Pointer = S->getPointerOperand();
|
||||||
PointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType());
|
PointerSize = TD->getTypeStoreSize(S->getOperand(0)->getType());
|
||||||
} else if (VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {
|
} else if (VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {
|
||||||
Pointer = V->getOperand(0);
|
Pointer = V->getOperand(0);
|
||||||
PointerSize = TD.getTypeStoreSize(V->getType());
|
PointerSize = TD->getTypeStoreSize(V->getType());
|
||||||
} else if (FreeInst *F = dyn_cast<FreeInst>(Inst)) {
|
} else if (FreeInst *F = dyn_cast<FreeInst>(Inst)) {
|
||||||
Pointer = F->getPointerOperand();
|
Pointer = F->getPointerOperand();
|
||||||
|
|
||||||
// FreeInsts erase the entire structure
|
// FreeInsts erase the entire structure
|
||||||
PointerSize = ~0UL;
|
PointerSize = ~0UL;
|
||||||
} else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {
|
} else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {
|
||||||
if (AA.getModRefBehavior(CallSite::get(Inst)) ==
|
if (AA->getModRefBehavior(CallSite::get(Inst)) ==
|
||||||
AliasAnalysis::DoesNotAccessMemory)
|
AliasAnalysis::DoesNotAccessMemory)
|
||||||
continue;
|
continue;
|
||||||
return DepResultTy(Inst, Normal);
|
return DepResultTy(Inst, Normal);
|
||||||
|
@ -81,7 +84,7 @@ getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AA.getModRefInfo(C, Pointer, PointerSize) != AliasAnalysis::NoModRef)
|
if (AA->getModRefInfo(C, Pointer, PointerSize) != AliasAnalysis::NoModRef)
|
||||||
return DepResultTy(Inst, Normal);
|
return DepResultTy(Inst, Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,9 +98,6 @@ getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt,
|
||||||
MemoryDependenceAnalysis::DepResultTy MemoryDependenceAnalysis::
|
MemoryDependenceAnalysis::DepResultTy MemoryDependenceAnalysis::
|
||||||
getDependencyFromInternal(Instruction *QueryInst, BasicBlock::iterator ScanIt,
|
getDependencyFromInternal(Instruction *QueryInst, BasicBlock::iterator ScanIt,
|
||||||
BasicBlock *BB) {
|
BasicBlock *BB) {
|
||||||
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
|
|
||||||
TargetData &TD = getAnalysis<TargetData>();
|
|
||||||
|
|
||||||
// Get the pointer value for which dependence will be determined
|
// Get the pointer value for which dependence will be determined
|
||||||
Value *MemPtr = 0;
|
Value *MemPtr = 0;
|
||||||
uint64_t MemSize = 0;
|
uint64_t MemSize = 0;
|
||||||
|
@ -105,15 +105,15 @@ getDependencyFromInternal(Instruction *QueryInst, BasicBlock::iterator ScanIt,
|
||||||
|
|
||||||
if (StoreInst* S = dyn_cast<StoreInst>(QueryInst)) {
|
if (StoreInst* S = dyn_cast<StoreInst>(QueryInst)) {
|
||||||
MemPtr = S->getPointerOperand();
|
MemPtr = S->getPointerOperand();
|
||||||
MemSize = TD.getTypeStoreSize(S->getOperand(0)->getType());
|
MemSize = TD->getTypeStoreSize(S->getOperand(0)->getType());
|
||||||
MemVolatile = S->isVolatile();
|
MemVolatile = S->isVolatile();
|
||||||
} else if (LoadInst* L = dyn_cast<LoadInst>(QueryInst)) {
|
} else if (LoadInst* L = dyn_cast<LoadInst>(QueryInst)) {
|
||||||
MemPtr = L->getPointerOperand();
|
MemPtr = L->getPointerOperand();
|
||||||
MemSize = TD.getTypeStoreSize(L->getType());
|
MemSize = TD->getTypeStoreSize(L->getType());
|
||||||
MemVolatile = L->isVolatile();
|
MemVolatile = L->isVolatile();
|
||||||
} else if (VAArgInst* V = dyn_cast<VAArgInst>(QueryInst)) {
|
} else if (VAArgInst* V = dyn_cast<VAArgInst>(QueryInst)) {
|
||||||
MemPtr = V->getOperand(0);
|
MemPtr = V->getOperand(0);
|
||||||
MemSize = TD.getTypeStoreSize(V->getType());
|
MemSize = TD->getTypeStoreSize(V->getType());
|
||||||
} else if (FreeInst* F = dyn_cast<FreeInst>(QueryInst)) {
|
} else if (FreeInst* F = dyn_cast<FreeInst>(QueryInst)) {
|
||||||
MemPtr = F->getPointerOperand();
|
MemPtr = F->getPointerOperand();
|
||||||
// FreeInsts erase the entire structure, not just a field.
|
// FreeInsts erase the entire structure, not just a field.
|
||||||
|
@ -138,11 +138,11 @@ getDependencyFromInternal(Instruction *QueryInst, BasicBlock::iterator ScanIt,
|
||||||
// a load depends on another must aliased load from the same value.
|
// a load depends on another must aliased load from the same value.
|
||||||
if (LoadInst *L = dyn_cast<LoadInst>(Inst)) {
|
if (LoadInst *L = dyn_cast<LoadInst>(Inst)) {
|
||||||
Value *Pointer = L->getPointerOperand();
|
Value *Pointer = L->getPointerOperand();
|
||||||
uint64_t PointerSize = TD.getTypeStoreSize(L->getType());
|
uint64_t PointerSize = TD->getTypeStoreSize(L->getType());
|
||||||
|
|
||||||
// If we found a pointer, check if it could be the same as our pointer
|
// If we found a pointer, check if it could be the same as our pointer
|
||||||
AliasAnalysis::AliasResult R =
|
AliasAnalysis::AliasResult R =
|
||||||
AA.alias(Pointer, PointerSize, MemPtr, MemSize);
|
AA->alias(Pointer, PointerSize, MemPtr, MemSize);
|
||||||
|
|
||||||
if (R == AliasAnalysis::NoAlias)
|
if (R == AliasAnalysis::NoAlias)
|
||||||
continue;
|
continue;
|
||||||
|
@ -161,13 +161,13 @@ getDependencyFromInternal(Instruction *QueryInst, BasicBlock::iterator ScanIt,
|
||||||
Value *AccessPtr = MemPtr->getUnderlyingObject();
|
Value *AccessPtr = MemPtr->getUnderlyingObject();
|
||||||
|
|
||||||
if (AccessPtr == AI ||
|
if (AccessPtr == AI ||
|
||||||
AA.alias(AI, 1, AccessPtr, 1) == AliasAnalysis::MustAlias)
|
AA->alias(AI, 1, AccessPtr, 1) == AliasAnalysis::MustAlias)
|
||||||
return DepResultTy(0, None);
|
return DepResultTy(0, None);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if this instruction mod/ref's the pointer.
|
// See if this instruction mod/ref's the pointer.
|
||||||
AliasAnalysis::ModRefResult MRR = AA.getModRefInfo(Inst, MemPtr, MemSize);
|
AliasAnalysis::ModRefResult MRR = AA->getModRefInfo(Inst, MemPtr, MemSize);
|
||||||
|
|
||||||
if (MRR == AliasAnalysis::NoModRef)
|
if (MRR == AliasAnalysis::NoModRef)
|
||||||
continue;
|
continue;
|
||||||
|
@ -426,7 +426,7 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!NonLocalDeps.count(RemInst) && "RemInst got reinserted?");
|
assert(!NonLocalDeps.count(RemInst) && "RemInst got reinserted?");
|
||||||
getAnalysis<AliasAnalysis>().deleteValue(RemInst);
|
AA->deleteValue(RemInst);
|
||||||
DEBUG(verifyRemoved(RemInst));
|
DEBUG(verifyRemoved(RemInst));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue