diff options
author | Dan Gohman <gohman@apple.com> | 2010-11-10 21:51:35 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-11-10 21:51:35 +0000 |
commit | 533c2ad360eaaab2a0a25dab5a99255256b84814 (patch) | |
tree | f1917ca55add4cc8e8b74cdf0461913106df4166 | |
parent | bab2a80525956b03b5f9126e1496785493326c37 (diff) | |
download | external_llvm-533c2ad360eaaab2a0a25dab5a99255256b84814.zip external_llvm-533c2ad360eaaab2a0a25dab5a99255256b84814.tar.gz external_llvm-533c2ad360eaaab2a0a25dab5a99255256b84814.tar.bz2 |
Factor out the code for computing an AliasAnalysis::Location
for a given instruction into a helper function.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118723 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/MemoryDependenceAnalysis.cpp | 183 |
1 files changed, 101 insertions, 82 deletions
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 97c679a..369175c 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -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! |