MemoryAccess *getClobberingMemoryAccess(MemoryAccess *, UpwardsMemoryQuery &);
bool instructionClobbersQuery(const MemoryDef *, UpwardsMemoryQuery &,
const MemoryLocation &Loc) const;
+ void verifyRemoved(MemoryAccess *);
SmallDenseMap<ConstMemoryAccessPair, MemoryAccess *>
CachedUpwardsClobberingAccess;
DenseMap<const MemoryAccess *, MemoryAccess *> CachedUpwardsClobberingCall;
if (!Q.IsCall)
Q.StartingLoc = MemoryLocation::get(I);
doCacheRemove(MA, Q, Q.StartingLoc);
- return;
- }
- // If it is not a use, the best we can do right now is destroy the cache.
- bool IsCall = false;
-
- if (auto *MUD = dyn_cast<MemoryUseOrDef>(MA)) {
- Instruction *I = MUD->getMemoryInst();
- IsCall = bool(ImmutableCallSite(I));
- }
- if (IsCall)
+ } else {
+ // If it is not a use, the best we can do right now is destroy the cache.
CachedUpwardsClobberingCall.clear();
- else
CachedUpwardsClobberingAccess.clear();
+ }
+
+#ifdef XDEBUG
+ // Run this only when expensive checks are enabled.
+ verifyRemoved(MA);
+#endif
}
void CachingMemorySSAWalker::doCacheRemove(const MemoryAccess *M,
return Result;
}
+// Verify that MA doesn't exist in any of the caches.
+void CachingMemorySSAWalker::verifyRemoved(MemoryAccess *MA) {
+#ifndef NDEBUG
+ for (auto &P : CachedUpwardsClobberingAccess)
+ assert(P.first.first != MA && P.second != MA &&
+ "Found removed MemoryAccess in cache.");
+ for (auto &P : CachedUpwardsClobberingCall)
+ assert(P.first != MA && P.second != MA &&
+ "Found removed MemoryAccess in cache.");
+#endif // !NDEBUG
+}
+
MemoryAccess *
DoNothingMemorySSAWalker::getClobberingMemoryAccess(const Instruction *I) {
MemoryAccess *MA = MSSA->getMemoryAccess(I);