}
-/// getCallSiteDependency - Private helper for finding the local dependencies
-/// of a call site.
+/// getCallSiteDependencyFrom - Private helper for finding the local
+/// dependencies of a call site.
MemDepResult MemoryDependenceAnalysis::
-getCallSiteDependency(CallSite CS, BasicBlock::iterator ScanIt, BasicBlock *BB) {
+getCallSiteDependencyFrom(CallSite CS, BasicBlock::iterator ScanIt,
+ BasicBlock *BB) {
// Walk backwards through the block, looking for dependencies
while (ScanIt != BB->begin()) {
Instruction *Inst = --ScanIt;
MemDepResult MemoryDependenceAnalysis::
getDependencyFrom(Instruction *QueryInst, BasicBlock::iterator ScanIt,
BasicBlock *BB) {
+ // The first instruction in a block is always non-local.
+ if (ScanIt == BB->begin())
+ return MemDepResult::getNonLocal();
+
// Get the pointer value for which dependence will be determined
Value *MemPtr = 0;
uint64_t MemSize = 0;
- bool MemVolatile = false;
- if (StoreInst* S = dyn_cast<StoreInst>(QueryInst)) {
- MemPtr = S->getPointerOperand();
- MemSize = TD->getTypeStoreSize(S->getOperand(0)->getType());
- MemVolatile = S->isVolatile();
- } else if (LoadInst* LI = dyn_cast<LoadInst>(QueryInst)) {
+ if (StoreInst *SI = dyn_cast<StoreInst>(QueryInst)) {
+ // If this is a volatile store, don't mess around with it. Just return the
+ // previous instruction as a clobber.
+ if (SI->isVolatile())
+ return MemDepResult::getClobber(--ScanIt);
+
+ MemPtr = SI->getPointerOperand();
+ MemSize = TD->getTypeStoreSize(SI->getOperand(0)->getType());
+ } else if (LoadInst *LI = dyn_cast<LoadInst>(QueryInst)) {
+ // If this is a volatile load, don't mess around with it. Just return the
+ // previous instruction as a clobber.
+ if (LI->isVolatile())
+ return MemDepResult::getClobber(--ScanIt);
+
MemPtr = LI->getPointerOperand();
MemSize = TD->getTypeStoreSize(LI->getType());
- MemVolatile = LI->isVolatile();
- } else if (VAArgInst* V = dyn_cast<VAArgInst>(QueryInst)) {
- MemPtr = V->getOperand(0);
- MemSize = TD->getTypeStoreSize(V->getType());
- } else if (FreeInst* F = dyn_cast<FreeInst>(QueryInst)) {
- MemPtr = F->getPointerOperand();
+ } else if (FreeInst *FI = dyn_cast<FreeInst>(QueryInst)) {
+ MemPtr = FI->getPointerOperand();
// FreeInsts erase the entire structure, not just a field.
MemSize = ~0UL;
+ } else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) {
+ assert(0 && "Should use getCallSiteDependencyFrom!");
+ return getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanIt, BB);
} else {
- assert((isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) &&
- "Can only get dependency info for memory instructions!");
- return getCallSiteDependency(CallSite::get(QueryInst), ScanIt, BB);
+ // Otherwise, this is a vaarg or non-memory instruction, just return a
+ // clobber dependency on the previous inst.
+ return MemDepResult::getClobber(--ScanIt);
}
// Walk backwards through the basic block, looking for dependencies
// Values depend on loads if the pointers are must aliased. This means that
// a load depends on another must aliased load from the same value.
if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
- // If the access is volatile and this is volatile, return a dependence.
- if (MemVolatile && LI->isVolatile())
- return MemDepResult::getClobber(LI);
-
Value *Pointer = LI->getPointerOperand();
uint64_t PointerSize = TD->getTypeStoreSize(LI->getType());
}
if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
- // If the access is volatile and this is volatile, return a dependence.
- if (MemVolatile && SI->isVolatile())
- return MemDepResult::getClobber(SI);
-
Value *Pointer = SI->getPointerOperand();
uint64_t PointerSize = TD->getTypeStoreSize(SI->getOperand(0)->getType());
}
// Do the scan.
- LocalCache = getDependencyFrom(QueryInst, ScanPos, QueryInst->getParent());
+ if (!isa<CallInst>(QueryInst) && !isa<InvokeInst>(QueryInst))
+ LocalCache = getDependencyFrom(QueryInst, ScanPos, QueryInst->getParent());
+ else
+ LocalCache = getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanPos,
+ QueryInst->getParent());
// Remember the result!
if (Instruction *I = LocalCache.getInst())
}
// Find out if this block has a local dependency for QueryInst.
- MemDepResult Dep = getDependencyFrom(QueryInst, ScanPos, DirtyBB);
+ MemDepResult Dep;
+ if (!isa<CallInst>(QueryInst) && !isa<InvokeInst>(QueryInst))
+ Dep = getDependencyFrom(QueryInst, ScanPos, DirtyBB);
+ else
+ Dep = getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanPos,
+ DirtyBB);
// If we had a dirty entry for the block, update it. Otherwise, just add
// a new entry.
return Cache;
}
+
/// removeInstruction - Remove an instruction from the dependence analysis,
/// updating the dependence of instructions that previously depended on it.
/// This method attempts to keep the cache coherent using the reverse map.