summaryrefslogtreecommitdiff
path: root/lib/Analysis/MemoryDependenceAnalysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/MemoryDependenceAnalysis.cpp')
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp100
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);