forked from OSchip/llvm-project
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:
parent
d634003ebd
commit
1d760ce8b3
|
@ -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!
|
||||
|
|
Loading…
Reference in New Issue