diff options
Diffstat (limited to 'lib/Analysis/MemoryDependenceAnalysis.cpp')
-rw-r--r-- | lib/Analysis/MemoryDependenceAnalysis.cpp | 100 |
1 files changed, 56 insertions, 44 deletions
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index feae53c54ecb..e22182b99e11 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -31,7 +31,6 @@ #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" -#include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" @@ -182,8 +181,8 @@ static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc, } /// Private helper for finding the local dependencies of a call site. -MemDepResult MemoryDependenceResults::getCallSiteDependencyFrom( - CallSite CS, bool isReadOnlyCall, BasicBlock::iterator ScanIt, +MemDepResult MemoryDependenceResults::getCallDependencyFrom( + CallBase *Call, bool isReadOnlyCall, BasicBlock::iterator ScanIt, BasicBlock *BB) { unsigned Limit = BlockScanLimit; @@ -205,21 +204,21 @@ MemDepResult MemoryDependenceResults::getCallSiteDependencyFrom( ModRefInfo MR = GetLocation(Inst, Loc, TLI); if (Loc.Ptr) { // A simple instruction. - if (isModOrRefSet(AA.getModRefInfo(CS, Loc))) + if (isModOrRefSet(AA.getModRefInfo(Call, Loc))) return MemDepResult::getClobber(Inst); continue; } - if (auto InstCS = CallSite(Inst)) { + if (auto *CallB = dyn_cast<CallBase>(Inst)) { // If these two calls do not interfere, look past it. - if (isNoModRef(AA.getModRefInfo(CS, InstCS))) { - // If the two calls are the same, return InstCS as a Def, so that - // CS can be found redundant and eliminated. + if (isNoModRef(AA.getModRefInfo(Call, CallB))) { + // If the two calls are the same, return Inst as a Def, so that + // Call can be found redundant and eliminated. if (isReadOnlyCall && !isModSet(MR) && - CS.getInstruction()->isIdenticalToWhenDefined(Inst)) + Call->isIdenticalToWhenDefined(CallB)) return MemDepResult::getDef(Inst); - // Otherwise if the two calls don't interact (e.g. InstCS is readnone) + // Otherwise if the two calls don't interact (e.g. CallB is readnone) // keep scanning. continue; } else @@ -750,11 +749,10 @@ MemDepResult MemoryDependenceResults::getDependency(Instruction *QueryInst) { LocalCache = getPointerDependencyFrom( MemLoc, isLoad, ScanPos->getIterator(), QueryParent, QueryInst); - } else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) { - CallSite QueryCS(QueryInst); - bool isReadOnly = AA.onlyReadsMemory(QueryCS); - LocalCache = getCallSiteDependencyFrom( - QueryCS, isReadOnly, ScanPos->getIterator(), QueryParent); + } else if (auto *QueryCall = dyn_cast<CallBase>(QueryInst)) { + bool isReadOnly = AA.onlyReadsMemory(QueryCall); + LocalCache = getCallDependencyFrom(QueryCall, isReadOnly, + ScanPos->getIterator(), QueryParent); } else // Non-memory instruction. LocalCache = MemDepResult::getUnknown(); @@ -780,11 +778,11 @@ static void AssertSorted(MemoryDependenceResults::NonLocalDepInfo &Cache, #endif const MemoryDependenceResults::NonLocalDepInfo & -MemoryDependenceResults::getNonLocalCallDependency(CallSite QueryCS) { - assert(getDependency(QueryCS.getInstruction()).isNonLocal() && +MemoryDependenceResults::getNonLocalCallDependency(CallBase *QueryCall) { + assert(getDependency(QueryCall).isNonLocal() && "getNonLocalCallDependency should only be used on calls with " "non-local deps!"); - PerInstNLInfo &CacheP = NonLocalDeps[QueryCS.getInstruction()]; + PerInstNLInfo &CacheP = NonLocalDeps[QueryCall]; NonLocalDepInfo &Cache = CacheP.first; // This is the set of blocks that need to be recomputed. In the cached case, @@ -807,21 +805,21 @@ MemoryDependenceResults::getNonLocalCallDependency(CallSite QueryCS) { DirtyBlocks.push_back(Entry.getBB()); // Sort the cache so that we can do fast binary search lookups below. - llvm::sort(Cache.begin(), Cache.end()); + llvm::sort(Cache); ++NumCacheDirtyNonLocal; // cerr << "CACHED CASE: " << DirtyBlocks.size() << " dirty: " // << Cache.size() << " cached: " << *QueryInst; } else { // Seed DirtyBlocks with each of the preds of QueryInst's block. - BasicBlock *QueryBB = QueryCS.getInstruction()->getParent(); + BasicBlock *QueryBB = QueryCall->getParent(); for (BasicBlock *Pred : PredCache.get(QueryBB)) DirtyBlocks.push_back(Pred); ++NumUncacheNonLocal; } // isReadonlyCall - If this is a read-only call, we can be more aggressive. - bool isReadonlyCall = AA.onlyReadsMemory(QueryCS); + bool isReadonlyCall = AA.onlyReadsMemory(QueryCall); SmallPtrSet<BasicBlock *, 32> Visited; @@ -865,8 +863,8 @@ MemoryDependenceResults::getNonLocalCallDependency(CallSite QueryCS) { if (Instruction *Inst = ExistingResult->getResult().getInst()) { ScanPos = Inst->getIterator(); // We're removing QueryInst's use of Inst. - RemoveFromReverseMap(ReverseNonLocalDeps, Inst, - QueryCS.getInstruction()); + RemoveFromReverseMap<Instruction *>(ReverseNonLocalDeps, Inst, + QueryCall); } } @@ -874,8 +872,7 @@ MemoryDependenceResults::getNonLocalCallDependency(CallSite QueryCS) { MemDepResult Dep; if (ScanPos != DirtyBB->begin()) { - Dep = - getCallSiteDependencyFrom(QueryCS, isReadonlyCall, ScanPos, DirtyBB); + Dep = getCallDependencyFrom(QueryCall, isReadonlyCall, ScanPos, DirtyBB); } else if (DirtyBB != &DirtyBB->getParent()->getEntryBlock()) { // No dependence found. If this is the entry block of the function, it is // a clobber, otherwise it is unknown. @@ -897,7 +894,7 @@ MemoryDependenceResults::getNonLocalCallDependency(CallSite QueryCS) { // Keep the ReverseNonLocalDeps map up to date so we can efficiently // update this when we remove instructions. if (Instruction *Inst = Dep.getInst()) - ReverseNonLocalDeps[Inst].insert(QueryCS.getInstruction()); + ReverseNonLocalDeps[Inst].insert(QueryCall); } else { // If the block *is* completely transparent to the load, we need to check @@ -1070,7 +1067,7 @@ SortNonLocalDepInfoCache(MemoryDependenceResults::NonLocalDepInfo &Cache, break; default: // Added many values, do a full scale sort. - llvm::sort(Cache.begin(), Cache.end()); + llvm::sort(Cache); break; } } @@ -1113,21 +1110,36 @@ bool MemoryDependenceResults::getNonLocalPointerDepFromBB( // If we already have a cache entry for this CacheKey, we may need to do some // work to reconcile the cache entry and the current query. if (!Pair.second) { - if (CacheInfo->Size < Loc.Size) { - // The query's Size is greater than the cached one. Throw out the - // cached data and proceed with the query at the greater size. - CacheInfo->Pair = BBSkipFirstBlockPair(); - CacheInfo->Size = Loc.Size; - for (auto &Entry : CacheInfo->NonLocalDeps) - if (Instruction *Inst = Entry.getResult().getInst()) - RemoveFromReverseMap(ReverseNonLocalPtrDeps, Inst, CacheKey); - CacheInfo->NonLocalDeps.clear(); - } else if (CacheInfo->Size > Loc.Size) { - // This query's Size is less than the cached one. Conservatively restart - // the query using the greater size. - return getNonLocalPointerDepFromBB( - QueryInst, Pointer, Loc.getWithNewSize(CacheInfo->Size), isLoad, - StartBB, Result, Visited, SkipFirstBlock); + if (CacheInfo->Size != Loc.Size) { + bool ThrowOutEverything; + if (CacheInfo->Size.hasValue() && Loc.Size.hasValue()) { + // FIXME: We may be able to do better in the face of results with mixed + // precision. We don't appear to get them in practice, though, so just + // be conservative. + ThrowOutEverything = + CacheInfo->Size.isPrecise() != Loc.Size.isPrecise() || + CacheInfo->Size.getValue() < Loc.Size.getValue(); + } else { + // For our purposes, unknown size > all others. + ThrowOutEverything = !Loc.Size.hasValue(); + } + + if (ThrowOutEverything) { + // The query's Size is greater than the cached one. Throw out the + // cached data and proceed with the query at the greater size. + CacheInfo->Pair = BBSkipFirstBlockPair(); + CacheInfo->Size = Loc.Size; + for (auto &Entry : CacheInfo->NonLocalDeps) + if (Instruction *Inst = Entry.getResult().getInst()) + RemoveFromReverseMap(ReverseNonLocalPtrDeps, Inst, CacheKey); + CacheInfo->NonLocalDeps.clear(); + } else { + // This query's Size is less than the cached one. Conservatively restart + // the query using the greater size. + return getNonLocalPointerDepFromBB( + QueryInst, Pointer, Loc.getWithNewSize(CacheInfo->Size), isLoad, + StartBB, Result, Visited, SkipFirstBlock); + } } // If the query's AATags are inconsistent with the cached one, @@ -1572,7 +1584,7 @@ void MemoryDependenceResults::removeInstruction(Instruction *RemInst) { ReverseDepMapType::iterator ReverseDepIt = ReverseLocalDeps.find(RemInst); if (ReverseDepIt != ReverseLocalDeps.end()) { // RemInst can't be the terminator if it has local stuff depending on it. - assert(!ReverseDepIt->second.empty() && !isa<TerminatorInst>(RemInst) && + assert(!ReverseDepIt->second.empty() && !RemInst->isTerminator() && "Nothing can locally depend on a terminator"); for (Instruction *InstDependingOnRemInst : ReverseDepIt->second) { @@ -1662,7 +1674,7 @@ void MemoryDependenceResults::removeInstruction(Instruction *RemInst) { // Re-sort the NonLocalDepInfo. Changing the dirty entry to its // subsequent value may invalidate the sortedness. - llvm::sort(NLPDI.begin(), NLPDI.end()); + llvm::sort(NLPDI); } ReverseNonLocalPtrDeps.erase(ReversePtrDepIt); |