Factor out the code for computing an AliasAnalysis::Location

for a given instruction into a helper function.

llvm-svn: 118723
This commit is contained in:
Dan Gohman 2010-11-10 21:51:35 +00:00
parent d634003ebd
commit 1d760ce8b3
1 changed files with 101 additions and 82 deletions

View File

@ -102,6 +102,81 @@ static void RemoveFromReverseMap(DenseMap<Instruction*,
ReverseMap.erase(InstIt);
}
/// GetLocation - If the given instruction references a specific memory
/// location, fill in Loc with the details, otherwise set Loc.Ptr to null.
/// Return a ModRefInfo value describing the general behavior of the
/// instruction.
static
AliasAnalysis::ModRefResult GetLocation(const Instruction *Inst,
AliasAnalysis::Location &Loc,
AliasAnalysis *AA) {
if (const LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
if (LI->isVolatile()) {
Loc = AliasAnalysis::Location();
return AliasAnalysis::ModRef;
}
Loc = AliasAnalysis::Location(LI->getPointerOperand(),
AA->getTypeStoreSize(LI->getType()),
LI->getMetadata(LLVMContext::MD_tbaa));
return AliasAnalysis::Ref;
}
if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
if (SI->isVolatile()) {
Loc = AliasAnalysis::Location();
return AliasAnalysis::ModRef;
}
Loc = AliasAnalysis::Location(SI->getPointerOperand(),
AA->getTypeStoreSize(SI->getValueOperand()
->getType()),
SI->getMetadata(LLVMContext::MD_tbaa));
return AliasAnalysis::Mod;
}
if (const VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {
Loc = AliasAnalysis::Location(V->getPointerOperand(),
AA->getTypeStoreSize(V->getType()),
V->getMetadata(LLVMContext::MD_tbaa));
return AliasAnalysis::ModRef;
}
if (const CallInst *CI = isFreeCall(Inst)) {
// calls to free() deallocate the entire structure
Loc = AliasAnalysis::Location(CI->getArgOperand(0));
return AliasAnalysis::Mod;
}
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst))
switch (II->getIntrinsicID()) {
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
case Intrinsic::invariant_start:
Loc = AliasAnalysis::Location(II->getArgOperand(1),
cast<ConstantInt>(II->getArgOperand(0))
->getZExtValue(),
II->getMetadata(LLVMContext::MD_tbaa));
// These intrinsics don't really modify the memory, but returning Mod
// will allow them to be handled conservatively.
return AliasAnalysis::Mod;
case Intrinsic::invariant_end:
Loc = AliasAnalysis::Location(II->getArgOperand(2),
cast<ConstantInt>(II->getArgOperand(1))
->getZExtValue(),
II->getMetadata(LLVMContext::MD_tbaa));
// These intrinsics don't really modify the memory, but returning Mod
// will allow them to be handled conservatively.
return AliasAnalysis::Mod;
default:
break;
}
// Otherwise, just do the coarse-grained thing that always works.
if (Inst->mayWriteToMemory())
return AliasAnalysis::ModRef;
if (Inst->mayReadFromMemory())
return AliasAnalysis::Ref;
return AliasAnalysis::NoModRef;
}
/// getCallSiteDependencyFrom - Private helper for finding the local
/// dependencies of a call site.
@ -114,19 +189,15 @@ getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall,
// If this inst is a memory op, get the pointer it accessed
AliasAnalysis::Location Loc;
if (StoreInst *S = dyn_cast<StoreInst>(Inst)) {
Loc = AliasAnalysis::Location(S->getPointerOperand(),
AA->getTypeStoreSize(S->getValueOperand()
->getType()),
S->getMetadata(LLVMContext::MD_tbaa));
} else if (VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {
Loc = AliasAnalysis::Location(V->getPointerOperand(),
AA->getTypeStoreSize(V->getType()),
V->getMetadata(LLVMContext::MD_tbaa));
} else if (const CallInst *CI = isFreeCall(Inst)) {
// calls to free() erase the entire structure
Loc = AliasAnalysis::Location(CI->getArgOperand(0));
} else if (CallSite InstCS = cast<Value>(Inst)) {
AliasAnalysis::ModRefResult MR = GetLocation(Inst, Loc, AA);
if (Loc.Ptr) {
// A simple instruction.
if (AA->getModRefInfo(CS, Loc) != AliasAnalysis::NoModRef)
return MemDepResult::getClobber(Inst);
continue;
}
if (CallSite InstCS = cast<Value>(Inst)) {
// Debug intrinsics don't cause dependences.
if (isa<DbgInfoIntrinsic>(Inst)) continue;
// If these two calls do not interfere, look past it.
@ -134,23 +205,17 @@ getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall,
case AliasAnalysis::NoModRef:
// If the two calls are the same, return InstCS as a Def, so that
// CS can be found redundant and eliminated.
if (isReadOnlyCall && InstCS.onlyReadsMemory() &&
if (isReadOnlyCall && !(MR & AliasAnalysis::Mod) &&
CS.getInstruction()->isIdenticalToWhenDefined(Inst))
return MemDepResult::getDef(Inst);
// Otherwise if the two calls don't interact (e.g. InstCS is readnone)
// keep scanning.
continue;
break;
default:
return MemDepResult::getClobber(Inst);
}
} else {
// Non-memory instruction.
continue;
}
if (AA->getModRefInfo(CS, Loc) != AliasAnalysis::NoModRef)
return MemDepResult::getClobber(Inst);
}
// No dependence found. If this is the entry block of the function, it is a
@ -344,8 +409,6 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) {
BasicBlock *QueryParent = QueryInst->getParent();
AliasAnalysis::Location MemLoc;
// Do the scan.
if (BasicBlock::iterator(QueryInst) == QueryParent->begin()) {
// No dependence found. If this is the entry block of the function, it is a
@ -354,69 +417,25 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) {
LocalCache = MemDepResult::getNonLocal();
else
LocalCache = MemDepResult::getClobber(QueryInst);
} else 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())
LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
else
MemLoc = AliasAnalysis::Location(SI->getPointerOperand(),
AA->getTypeStoreSize(SI->getOperand(0)
->getType()),
SI->getMetadata(LLVMContext::MD_tbaa));
} 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())
LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
else
MemLoc = AliasAnalysis::Location(LI->getPointerOperand(),
AA->getTypeStoreSize(LI->getType()),
LI->getMetadata(LLVMContext::MD_tbaa));
} else if (const CallInst *CI = isFreeCall(QueryInst)) {
// calls to free() erase the entire structure, not just a field.
MemLoc = AliasAnalysis::Location(CI->getArgOperand(0));
} else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) {
int IntrinsicID = 0; // Intrinsic IDs start at 1.
IntrinsicInst *II = dyn_cast<IntrinsicInst>(QueryInst);
if (II)
IntrinsicID = II->getIntrinsicID();
switch (IntrinsicID) {
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
case Intrinsic::invariant_start:
MemLoc = AliasAnalysis::Location(II->getArgOperand(1),
cast<ConstantInt>(II->getArgOperand(0))
->getZExtValue(),
II->getMetadata(LLVMContext::MD_tbaa));
break;
case Intrinsic::invariant_end:
MemLoc = AliasAnalysis::Location(II->getArgOperand(2),
cast<ConstantInt>(II->getArgOperand(1))
->getZExtValue(),
II->getMetadata(LLVMContext::MD_tbaa));
break;
default:
} else {
AliasAnalysis::Location MemLoc;
AliasAnalysis::ModRefResult MR = GetLocation(QueryInst, MemLoc, AA);
if (MemLoc.Ptr) {
// If we can do a pointer scan, make it happen.
bool isLoad = !(MR & AliasAnalysis::Mod);
if (IntrinsicInst *II = dyn_cast<MemoryUseIntrinsic>(QueryInst)) {
isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_end;
}
LocalCache = getPointerDependencyFrom(MemLoc, isLoad, ScanPos,
QueryParent);
} else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) {
CallSite QueryCS(QueryInst);
bool isReadOnly = AA->onlyReadsMemory(QueryCS);
LocalCache = getCallSiteDependencyFrom(QueryCS, isReadOnly, ScanPos,
QueryParent);
break;
}
} else {
// Non-memory instruction.
LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
}
// If we need to do a pointer scan, make it happen.
if (MemLoc.Ptr) {
bool isLoad = !QueryInst->mayWriteToMemory();
if (IntrinsicInst *II = dyn_cast<MemoryUseIntrinsic>(QueryInst)) {
isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_end;
}
LocalCache = getPointerDependencyFrom(MemLoc, isLoad, ScanPos,
QueryParent);
} else
// Non-memory instruction.
LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
}
// Remember the result!