58#define DEBUG_TYPE "memdep"
60STATISTIC(NumCacheNonLocal,
"Number of fully cached non-local responses");
61STATISTIC(NumCacheDirtyNonLocal,
"Number of dirty cached non-local responses");
62STATISTIC(NumUncacheNonLocal,
"Number of uncached non-local responses");
65 "Number of fully cached non-local ptr responses");
67 "Number of cached, but dirty, non-local ptr responses");
68STATISTIC(NumUncacheNonLocalPtr,
"Number of uncached non-local ptr responses");
70 "Number of block queries that were completely cached");
76 cl::desc(
"The number of instructions to scan in a block in memory "
77 "dependency analysis (default = 100)"));
81 cl::desc(
"The number of blocks to scan during memory "
82 "dependency analysis (default = 200)"));
86 cl::desc(
"The max number of entries allowed in a cache (default = 10000)"));
94template <
typename KeyTy>
99 ReverseMap.find(Inst);
100 assert(InstIt != ReverseMap.
end() &&
"Reverse map out of sync?");
101 bool Found = InstIt->second.
erase(Val);
102 assert(Found &&
"Invalid reverse map!");
104 if (InstIt->second.
empty())
105 ReverseMap.erase(InstIt);
116 if (LI->isUnordered()) {
129 if (
SI->isUnordered()) {
155 switch (
II->getIntrinsicID()) {
156 case Intrinsic::lifetime_start:
157 case Intrinsic::lifetime_end:
162 case Intrinsic::invariant_start:
167 case Intrinsic::invariant_end:
172 case Intrinsic::masked_load:
175 case Intrinsic::masked_store:
192MemDepResult MemoryDependenceResults::getCallDependencyFrom(
196 bool IsInvariantLoad =
Call->
hasMetadata(LLVMContext::MD_invariant_load);
199 while (ScanIt != BB->
begin()) {
222 bool IsIdenticalReadOnlyCall = isReadOnlyCall && !
isModSet(MR) &&
227 if (IsInvariantLoad && IsIdenticalReadOnlyCall)
234 if (IsIdenticalReadOnlyCall)
240 }
else if (IsInvariantLoad) {
265 if (QueryInst !=
nullptr) {
269 if (InvariantGroupDependency.
isDef())
270 return InvariantGroupDependency;
274 MemLoc,
isLoad, ScanIt, BB, QueryInst, Limit, BatchAA);
275 if (SimpleDep.
isDef())
281 return InvariantGroupDependency;
284 "InvariantGroupDependency should be only unknown at this point");
300 if (!LI->
hasMetadata(LLVMContext::MD_invariant_group))
318 assert(
Other &&
"Must call it with not null instruction");
319 if (Best ==
nullptr || DT.dominates(Best,
Other))
324 for (
const Use &Us : LoadOperand->
uses()) {
326 if (!U || U == LI || !DT.dominates(U, LI))
335 U->hasMetadata(LLVMContext::MD_invariant_group))
336 ClosestDependency = GetClosestDependency(ClosestDependency, U);
339 if (!ClosestDependency)
341 if (ClosestDependency->
getParent() == BB)
347 NonLocalDefsCache.try_emplace(
350 ReverseNonLocalDefsCache[ClosestDependency].insert(LI);
362 unsigned ScanLimit) {
369 if (std::min(MemLocAlign,
SI->getAlign()).value() <
374 if (!LI || LI->getParent() !=
SI->getParent())
378 unsigned NumVisitedInsts = 0;
380 if (++NumVisitedInsts > ScanLimit ||
397 Limit = &DefaultLimit;
431 if (
isLoad && QueryInst) {
434 MemLocAlign = LI->getAlign();
447 return I->mayReadOrWriteMemory();
451 while (ScanIt != BB->
begin()) {
465 case Intrinsic::lifetime_start: {
475 case Intrinsic::masked_load:
476 case Intrinsic::masked_store: {
484 if (ID == Intrinsic::masked_load)
500 if (LI->isVolatile()) {
538 ClobberOffsets[LI] = R.getOffset();
559 if (!
SI->isUnordered() &&
SI->isAtomic()) {
577 if (
SI->isVolatile())
614 if (AccessPtr == Inst || BatchAA.
isMustAlias(Inst, AccessPtr))
662 ClobberOffsets.clear();
670 if (!LocalCache.isDirty())
698 isLoad |=
II->getIntrinsicID() == Intrinsic::lifetime_start;
702 QueryParent, QueryInst,
nullptr);
704 bool isReadOnly = AA.onlyReadsMemory(QueryCall);
705 LocalCache = getCallDependencyFrom(QueryCall, isReadOnly,
714 ReverseLocalDeps[
I].insert(QueryInst);
725 Count = Cache.size();
726 assert(std::is_sorted(Cache.begin(), Cache.begin() +
Count) &&
727 "Cache isn't sorted!");
734 "getNonLocalCallDependency should only be used on calls with "
736 PerInstNLInfo &CacheP = NonLocalDepsMap[QueryCall];
744 if (!Cache.empty()) {
747 if (!CacheP.second) {
754 for (
auto &Entry : Cache)
755 if (Entry.getResult().isDirty())
761 ++NumCacheDirtyNonLocal;
766 ++NumUncacheNonLocal;
770 bool isReadonlyCall = AA.onlyReadsMemory(QueryCall);
774 unsigned NumSortedEntries = Cache.
size();
778 while (!DirtyBlocks.
empty()) {
782 if (!Visited.
insert(DirtyBB).second)
788 NonLocalDepInfo::iterator Entry =
789 std::upper_bound(Cache.begin(), Cache.begin() + NumSortedEntries,
791 if (Entry != Cache.begin() && std::prev(Entry)->getBB() == DirtyBB)
795 if (Entry != Cache.begin() + NumSortedEntries &&
796 Entry->getBB() == DirtyBB) {
799 if (!Entry->getResult().isDirty())
803 ExistingResult = &*Entry;
809 if (ExistingResult) {
821 if (ScanPos != DirtyBB->
begin()) {
822 Dep = getCallDependencyFrom(QueryCall, isReadonlyCall, ScanPos, DirtyBB);
844 ReverseNonLocalDeps[Inst].insert(QueryCall);
863 assert(
Loc.Ptr->getType()->isPointerTy() &&
864 "Can't get pointer deps of a non-pointer!");
868 auto NonLocalDefIt = NonLocalDefsCache.find(QueryInst);
869 if (NonLocalDefIt != NonLocalDefsCache.end()) {
870 Result.push_back(NonLocalDefIt->second);
872 ReverseNonLocalDefsCache, NonLocalDefIt->second.getResult().getInst(),
874 NonLocalDefsCache.erase(NonLocalDefIt);
888 return !LI->isUnordered();
890 return !
SI->isUnordered();
906 ++NonLocalPointerDepEpoch;
907 assert(NonLocalPointerDepEpoch > 0 &&
908 "NonLocalPointerDepVisitedEpoch overflow");
923MemDepResult MemoryDependenceResults::getNonLocalInfoForBlock(
925 BasicBlock *BB, NonLocalDepInfo *Cache,
unsigned NumSortedEntries,
935 NonLocalDepInfo::iterator Entry = std::upper_bound(
937 if (Entry != Cache->begin() && (Entry - 1)->getBB() == BB)
941 if (Entry != Cache->begin() + NumSortedEntries && Entry->getBB() == BB)
942 ExistingResult = &*Entry;
949 ExistingResult =
nullptr;
953 if (ExistingResult && !ExistingResult->
getResult().isDirty()) {
954 ++NumCacheNonLocalPtr;
964 "Instruction invalidated?");
965 ++NumCacheDirtyNonLocalPtr;
969 ValueIsLoadPair CacheKey(
Loc.Ptr,
isLoad);
972 ++NumUncacheNonLocalPtr;
977 QueryInst,
nullptr, BatchAA);
988 Cache->push_back(NonLocalDepEntry(BB, Dep));
999 assert(Inst &&
"Didn't depend on anything?");
1000 ValueIsLoadPair CacheKey(Loc.
Ptr,
isLoad);
1001 ReverseNonLocalPtrDeps[Inst].insert(CacheKey);
1011 unsigned NumSortedEntries) {
1014 if (Cache.size() < 2)
1017 unsigned s = Cache.size() - NumSortedEntries;
1024 if (NumSortedEntries == 0) {
1032 if (s <
Log2_32(Cache.size())) {
1036 MemoryDependenceResults::NonLocalDepInfo::iterator Entry =
1037 std::upper_bound(Cache.begin(), Cache.end() - s + 1, Val);
1038 Cache.insert(Entry, Val);
1046void MemoryDependenceResults::setNonLocalPointerDepVisited(
BasicBlock *BB,
1048 NonLocalPointerDepVisited[BB->
getNumber()] = {
V, NonLocalPointerDepEpoch};
1051bool MemoryDependenceResults::isNonLocalPointerDepVisited(
1053 return NonLocalPointerDepVisited[BB->
getNumber()].second ==
1054 NonLocalPointerDepEpoch;
1058MemoryDependenceResults::lookupNonLocalPointerDepVisited(
BasicBlock *BB)
const {
1059 assert(isNonLocalPointerDepVisited(BB) &&
1060 "Visited value requested for unseen block");
1061 return NonLocalPointerDepVisited[BB->
getNumber()].first;
1077bool MemoryDependenceResults::getNonLocalPointerDepFromBB(
1081 bool IsIncomplete) {
1089 NonLocalPointerInfo InitialNLPI;
1090 InitialNLPI.Size = Loc.
Size;
1091 InitialNLPI.AATags = Loc.
AATags;
1099 std::pair<CachedNonLocalPointerInfo::iterator, bool> Pair =
1100 NonLocalPointerDeps.insert(std::make_pair(CacheKey, InitialNLPI));
1101 NonLocalPointerInfo *CacheInfo = &Pair.first->second;
1107 if (CacheInfo->Size != Loc.
Size) {
1110 CacheInfo->Pair = BBSkipFirstBlockPair();
1111 CacheInfo->Size = Loc.
Size;
1112 for (
auto &Entry : CacheInfo->NonLocalDeps)
1113 if (Instruction *Inst =
Entry.getResult().getInst())
1115 CacheInfo->NonLocalDeps.clear();
1119 IsIncomplete =
true;
1125 if (CacheInfo->AATags != Loc.
AATags) {
1126 if (CacheInfo->AATags) {
1127 CacheInfo->Pair = BBSkipFirstBlockPair();
1128 CacheInfo->AATags = AAMDNodes();
1129 for (
auto &Entry : CacheInfo->NonLocalDeps)
1130 if (Instruction *Inst =
Entry.getResult().getInst())
1132 CacheInfo->NonLocalDeps.clear();
1136 IsIncomplete =
true;
1139 return getNonLocalPointerDepFromBB(
1141 SkipFirstBlock, IsIncomplete);
1152 CacheInfo->Pair == BBSkipFirstBlockPair(StartBB, SkipFirstBlock)) {
1158 for (
auto &Entry : *Cache) {
1159 if (!isNonLocalPointerDepVisited(
Entry.getBB()))
1161 Value *Prev = lookupNonLocalPointerDepVisited(
Entry.getBB());
1162 if (Prev ==
Pointer.getAddr())
1172 for (
auto &Entry : *Cache) {
1173 setNonLocalPointerDepVisited(
Entry.getBB(), Addr);
1174 if (
Entry.getResult().isNonLocal()) {
1178 if (DT.isReachableFromEntry(
Entry.getBB())) {
1180 NonLocalDepResult(
Entry.getBB(),
Entry.getResult(), Addr));
1183 ++NumCacheCompleteNonLocalPtr;
1199 if (!IsIncomplete && Cache->empty())
1200 CacheInfo->Pair = BBSkipFirstBlockPair(StartBB, SkipFirstBlock);
1202 CacheInfo->Pair = BBSkipFirstBlockPair();
1216 unsigned NumSortedEntries = Cache->size();
1218 bool GotWorklistLimit =
false;
1221 BatchAAResults BatchAA(AA, &EEA);
1222 while (!Worklist.
empty()) {
1231 if (Cache && NumSortedEntries != Cache->size()) {
1238 CacheInfo->Pair = BBSkipFirstBlockPair();
1243 if (!SkipFirstBlock) {
1246 assert(isNonLocalPointerDepVisited(BB) &&
1247 "Should check 'visited' before adding to WL");
1252 MemDepResult Dep = getNonLocalInfoForBlock(
1253 QueryInst, Loc,
isLoad, BB, Cache, NumSortedEntries, BatchAA);
1257 if (DT.isReachableFromEntry(BB)) {
1258 Result.push_back(NonLocalDepResult(BB, Dep,
Pointer.getAddr()));
1268 if (!
Pointer.needsPHITranslationFromBlock(BB)) {
1269 SkipFirstBlock =
false;
1270 SmallVector<BasicBlock *, 16> NewBlocks;
1271 for (BasicBlock *Pred : PredCache.get(BB)) {
1273 if (!isNonLocalPointerDepVisited(Pred)) {
1274 setNonLocalPointerDepVisited(Pred,
Pointer.getAddr());
1279 Value *Prev = lookupNonLocalPointerDepVisited(Pred);
1283 if (Prev !=
Pointer.getAddr()) {
1286 for (
auto *NewBlock : NewBlocks)
1287 setNonLocalPointerDepVisited(NewBlock,
nullptr);
1288 goto PredTranslationFailure;
1291 if (NewBlocks.
size() > WorklistEntries) {
1294 for (
auto *NewBlock : NewBlocks)
1295 setNonLocalPointerDepVisited(NewBlock,
nullptr);
1296 GotWorklistLimit =
true;
1297 goto PredTranslationFailure;
1299 WorklistEntries -= NewBlocks.
size();
1306 if (!
Pointer.isPotentiallyPHITranslatable())
1307 goto PredTranslationFailure;
1314 if (Cache && NumSortedEntries != Cache->size()) {
1316 NumSortedEntries = Cache->size();
1321 for (BasicBlock *Pred : PredCache.get(BB)) {
1322 PredList.
push_back(std::make_pair(Pred, Pointer));
1326 PHITransAddr &PredPointer = PredList.
back().second;
1335 if (!isNonLocalPointerDepVisited(Pred)) {
1336 setNonLocalPointerDepVisited(Pred, PredPtrVal);
1339 Value *PrevVal = lookupNonLocalPointerDepVisited(Pred);
1346 if (PrevVal == PredPtrVal)
1355 for (
const auto &Pred : PredList)
1356 setNonLocalPointerDepVisited(Pred.first,
nullptr);
1358 goto PredTranslationFailure;
1366 for (
auto &
I : PredList) {
1368 PHITransAddr &PredPointer =
I.second;
1371 bool CanTranslate =
true;
1385 PHITransAddr(Pointer).translateValue(BB, Pred, &DT,
Cond);
1386 if (SelAddrs.first && SelAddrs.second) {
1388 SelectAddr(
Cond, SelAddrs)));
1389 NonLocalPointerInfo &NLPI = NonLocalPointerDeps[CacheKey];
1390 NLPI.Pair = BBSkipFirstBlockPair();
1394 CanTranslate =
false;
1405 if (!CanTranslate ||
1406 !getNonLocalPointerDepFromBB(QueryInst, PredPointer,
1418 NonLocalPointerInfo &NLPI = NonLocalPointerDeps[CacheKey];
1419 NLPI.Pair = BBSkipFirstBlockPair();
1425 CacheInfo = &NonLocalPointerDeps[CacheKey];
1426 Cache = &CacheInfo->NonLocalDeps;
1427 NumSortedEntries = Cache->size();
1433 CacheInfo->Pair = BBSkipFirstBlockPair();
1434 SkipFirstBlock =
false;
1437 PredTranslationFailure:
1444 CacheInfo = &NonLocalPointerDeps[CacheKey];
1445 Cache = &CacheInfo->NonLocalDeps;
1446 NumSortedEntries = Cache->size();
1453 CacheInfo->Pair = BBSkipFirstBlockPair();
1467 if (
I.getBB() != BB)
1470 assert((GotWorklistLimit ||
I.getResult().isNonLocal() ||
1471 !DT.isReachableFromEntry(BB)) &&
1472 "Should only be here with transparent block");
1480 (void)GotWorklistLimit;
1493void MemoryDependenceResults::removeCachedNonLocalPointerDependencies(
1494 ValueIsLoadPair
P) {
1497 if (!NonLocalDefsCache.empty()) {
1498 auto it = NonLocalDefsCache.find(
P.getPointer());
1499 if (it != NonLocalDefsCache.end()) {
1501 it->second.getResult().getInst(),
P.getPointer());
1502 NonLocalDefsCache.erase(it);
1506 auto toRemoveIt = ReverseNonLocalDefsCache.find(
I);
1507 if (toRemoveIt != ReverseNonLocalDefsCache.end()) {
1508 for (
const auto *Entry : toRemoveIt->second) {
1509 [[maybe_unused]]
bool Removed = NonLocalDefsCache.erase(Entry);
1510 assert(Removed &&
"Reverse non-local def map out of sync?");
1512 ReverseNonLocalDefsCache.erase(toRemoveIt);
1518 if (It == NonLocalPointerDeps.end())
1525 for (
const NonLocalDepEntry &DE : PInfo) {
1536 NonLocalPointerDeps.erase(It);
1544 removeCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr,
false));
1546 removeCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr,
true));
1554 EEA.removeInstruction(RemInst);
1559 if (NLDI != NonLocalDepsMap.end()) {
1561 for (
auto &Entry : BlockMap)
1562 if (
Instruction *Inst = Entry.getResult().getInst())
1564 NonLocalDepsMap.erase(NLDI);
1569 if (LocalDepEntry != LocalDeps.end()) {
1571 if (
Instruction *Inst = LocalDepEntry->second.getInst())
1575 LocalDeps.erase(LocalDepEntry);
1584 removeCachedNonLocalPointerDependencies(ValueIsLoadPair(RemInst,
false));
1585 removeCachedNonLocalPointerDependencies(ValueIsLoadPair(RemInst,
true));
1589 auto toRemoveIt = NonLocalDefsCache.find(RemInst);
1590 if (toRemoveIt != NonLocalDefsCache.end()) {
1592 "only load instructions should be added directly");
1593 Instruction *DepV = toRemoveIt->second.getResult().getInst();
1596 NonLocalDefsCache.erase(toRemoveIt);
1600 auto ReverseNonLocalDefIt = ReverseNonLocalDefsCache.find(RemInst);
1601 if (ReverseNonLocalDefIt != ReverseNonLocalDefsCache.end()) {
1602 for (
const Value *QueryInst : ReverseNonLocalDefIt->second) {
1603 [[maybe_unused]]
bool Removed = NonLocalDefsCache.erase(QueryInst);
1604 assert(Removed &&
"Reverse non-local def map out of sync?");
1606 ReverseNonLocalDefsCache.erase(ReverseNonLocalDefIt);
1620 NewDirtyVal = MemDepResult::getDirty(&*++RemInst->
getIterator());
1622 ReverseDepMapType::iterator ReverseDepIt = ReverseLocalDeps.find(RemInst);
1623 if (ReverseDepIt != ReverseLocalDeps.end()) {
1626 "Nothing can locally depend on a terminator");
1628 for (
Instruction *InstDependingOnRemInst : ReverseDepIt->second) {
1629 assert(InstDependingOnRemInst != RemInst &&
1630 "Already removed our local dep info");
1632 LocalDeps[InstDependingOnRemInst] = NewDirtyVal;
1636 "There is no way something else can have "
1637 "a local dep on this if it is a terminator!");
1639 std::make_pair(NewDirtyVal.
getInst(), InstDependingOnRemInst));
1642 ReverseLocalDeps.erase(ReverseDepIt);
1646 while (!ReverseDepsToAdd.
empty()) {
1647 ReverseLocalDeps[ReverseDepsToAdd.
back().first].insert(
1648 ReverseDepsToAdd.
back().second);
1653 ReverseDepIt = ReverseNonLocalDeps.find(RemInst);
1654 if (ReverseDepIt != ReverseNonLocalDeps.end()) {
1656 assert(
I != RemInst &&
"Already removed NonLocalDep info for RemInst");
1658 PerInstNLInfo &INLD = NonLocalDepsMap[
I];
1662 for (
auto &Entry : INLD.first) {
1663 if (Entry.getResult().getInst() != RemInst)
1667 Entry.setResult(NewDirtyVal);
1670 ReverseDepsToAdd.
push_back(std::make_pair(NextI,
I));
1674 ReverseNonLocalDeps.erase(ReverseDepIt);
1677 while (!ReverseDepsToAdd.
empty()) {
1678 ReverseNonLocalDeps[ReverseDepsToAdd.
back().first].insert(
1679 ReverseDepsToAdd.
back().second);
1686 ReverseNonLocalPtrDepTy::iterator ReversePtrDepIt =
1687 ReverseNonLocalPtrDeps.find(RemInst);
1688 if (ReversePtrDepIt != ReverseNonLocalPtrDeps.end()) {
1690 ReversePtrDepsToAdd;
1692 for (ValueIsLoadPair
P : ReversePtrDepIt->second) {
1693 assert(
P.getPointer() != RemInst &&
1694 "Already removed NonLocalPointerDeps info for RemInst");
1696 auto &NLPD = NonLocalPointerDeps[
P];
1701 NLPD.Pair = BBSkipFirstBlockPair();
1704 for (
auto &Entry : NLPDI) {
1705 if (Entry.getResult().getInst() != RemInst)
1709 Entry.setResult(NewDirtyVal);
1712 ReversePtrDepsToAdd.
push_back(std::make_pair(NewDirtyInst,
P));
1720 ReverseNonLocalPtrDeps.
erase(ReversePtrDepIt);
1722 while (!ReversePtrDepsToAdd.
empty()) {
1723 ReverseNonLocalPtrDeps[ReversePtrDepsToAdd.
back().first].insert(
1724 ReversePtrDepsToAdd.
back().second);
1729 assert(!NonLocalDepsMap.count(RemInst) &&
"RemInst got reinserted?");
1737void MemoryDependenceResults::verifyRemoved(
Instruction *
D)
const {
1739 for (
const auto &DepKV : LocalDeps) {
1740 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1741 assert(DepKV.second.getInst() !=
D &&
"Inst occurs in data structures");
1744 for (
const auto &DepKV : NonLocalPointerDeps) {
1745 assert(DepKV.first.getPointer() !=
D &&
"Inst occurs in NLPD map key");
1746 for (
const auto &Entry : DepKV.second.NonLocalDeps)
1747 assert(Entry.getResult().getInst() !=
D &&
"Inst occurs as NLPD value");
1750 for (
const auto &DepKV : NonLocalDepsMap) {
1751 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1752 const PerInstNLInfo &INLD = DepKV.second;
1753 for (
const auto &Entry : INLD.first)
1755 "Inst occurs in data structures");
1758 for (
const auto &DepKV : ReverseLocalDeps) {
1759 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1760 for (Instruction *Inst : DepKV.second)
1761 assert(Inst !=
D &&
"Inst occurs in data structures");
1764 for (
const auto &DepKV : ReverseNonLocalDeps) {
1765 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1766 for (Instruction *Inst : DepKV.second)
1767 assert(Inst !=
D &&
"Inst occurs in data structures");
1770 for (
const auto &DepKV : ReverseNonLocalPtrDeps) {
1771 assert(DepKV.first !=
D &&
"Inst occurs in rev NLPD map");
1773 for (ValueIsLoadPair
P : DepKV.second)
1774 assert(
P != ValueIsLoadPair(
D,
false) &&
P != ValueIsLoadPair(
D,
true) &&
1775 "Inst occurs in ReverseNonLocalPtrDeps map");
1797 "Memory Dependence Analysis",
false,
true)
1822 FunctionAnalysisManager::Invalidator &Inv) {
1840 return DefaultBlockScanLimit;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isLoad(int Opcode)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Atomic ordering constants.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file defines the DenseMap class.
Module.h This file contains the declarations for the Module class.
This defines the Use class.
static const unsigned int NumResultsLimit
static cl::opt< unsigned > CacheGlobalLimit("memdep-cache-global-limit", cl::Hidden, cl::init(10000), cl::desc("The max number of entries allowed in a cache (default = 10000)"))
static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc, const TargetLibraryInfo &TLI)
If the given instruction references a specific memory location, fill in Loc with the details,...
static cl::opt< unsigned > BlockNumberLimit("memdep-block-number-limit", cl::Hidden, cl::init(200), cl::desc("The number of blocks to scan during memory " "dependency analysis (default = 200)"))
static void RemoveFromReverseMap(DenseMap< Instruction *, SmallPtrSet< KeyTy, 4 > > &ReverseMap, Instruction *Inst, KeyTy Val)
This is a helper function that removes Val from 'Inst's set in ReverseMap.
static void SortNonLocalDepInfoCache(MemoryDependenceResults::NonLocalDepInfo &Cache, unsigned NumSortedEntries)
Sort the NonLocalDepInfo cache, given a certain number of elements in the array that are already prop...
static void AssertSorted(MemoryDependenceResults::NonLocalDepInfo &Cache, int Count=-1)
This method is used when -debug is specified to verify that cache arrays are properly kept sorted.
static bool canSkipClobberingStore(const StoreInst *SI, const MemoryLocation &MemLoc, Align MemLocAlign, BatchAAResults &BatchAA, unsigned ScanLimit)
static cl::opt< unsigned > BlockScanLimit("memdep-block-scan-limit", cl::Hidden, cl::init(100), cl::desc("The number of instructions to scan in a block in memory " "dependency analysis (default = 100)"))
This file provides utility analysis objects describing memory locations.
static bool isOrdered(const Instruction *I)
static bool isInvariantLoad(const Instruction *I, const Value *Ptr, const bool IsKernelFn)
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
The possible results of an alias query.
@ NoAlias
The two locations do not alias at all.
@ PartialAlias
The two locations alias, but only due to a partial overlap.
@ MustAlias
The two locations precisely alias each other.
This templated class represents "all analyses that operate over <aparticular IR unit>" (e....
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
AnalysisUsage & addRequiredTransitive()
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
LLVM Basic Block Representation.
unsigned getNumber() const
iterator begin()
Instruction iterator methods.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
InstListType::iterator iterator
Instruction iterators...
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, bool IgnoreLocals=false)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
A parsed version of the target data layout string in and methods for querying it.
bool erase(const KeyT &Val)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
An instruction for ordering other memory operations.
const BasicBlock & getEntryBlock() const
unsigned getMaxBlockNumber() const
Return a value larger than the largest block number.
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI bool isIdenticalToWhenDefined(const Instruction *I, bool IntersectAttrs=false) const LLVM_READONLY
This is like isIdenticalTo, except that it ignores the SubclassOptionalData flags,...
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI bool isVolatile() const LLVM_READONLY
Return true if this instruction has a volatile memory access.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
Value * getPointerOperand()
TypeSize getValue() const
A memory dependence query can return one of three different answers.
bool isNonLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the block,...
static MemDepResult getNonLocal()
bool isNonFuncLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the function.
static MemDepResult getSelect()
static MemDepResult getClobber(Instruction *Inst)
bool isDef() const
Tests if this MemDepResult represents a query that is an instruction definition dependency.
static MemDepResult getUnknown()
bool isLocal() const
Tests if this MemDepResult represents a valid local query (Clobber/Def).
bool isUnknown() const
Tests if this MemDepResult represents a query which cannot and/or will not be computed.
static MemDepResult getNonFuncLocal()
static MemDepResult getDef(Instruction *Inst)
get methods: These are static ctor methods for creating various MemDepResult kinds.
Instruction * getInst() const
If this is a normal dependency, returns the instruction that is depended on.
An analysis that produces MemoryDependenceResults for a function.
LLVM_ABI MemoryDependenceResults run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI MemoryDependenceAnalysis()
Provides a lazy, caching interface for making common memory aliasing information queries,...
LLVM_ABI MemDepResult getSimplePointerDependencyFrom(const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB, Instruction *QueryInst, unsigned *Limit, BatchAAResults &BatchAA)
std::vector< NonLocalDepEntry > NonLocalDepInfo
LLVM_ABI void invalidateCachedPredecessors()
Clears the PredIteratorCache info.
LLVM_ABI void invalidateCachedPointerInfo(Value *Ptr)
Invalidates cached information about the specified pointer, because it may be too conservative in mem...
LLVM_ABI MemDepResult getPointerDependencyFrom(const MemoryLocation &Loc, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB, Instruction *QueryInst=nullptr, unsigned *Limit=nullptr)
Returns the instruction on which a memory location depends.
LLVM_ABI void removeInstruction(Instruction *InstToRemove)
Removes an instruction from the dependence analysis, updating the dependence of instructions that pre...
LLVM_ABI MemDepResult getInvariantGroupPointerDependency(LoadInst *LI, BasicBlock *BB)
This analysis looks for other loads and stores with invariant.group metadata and the same pointer ope...
LLVM_ABI unsigned getDefaultBlockScanLimit() const
Some methods limit the number of instructions they will examine.
LLVM_ABI MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.
LLVM_ABI const NonLocalDepInfo & getNonLocalCallDependency(CallBase *QueryCall)
Perform a full dependency query for the specified call, returning the set of blocks that the value is...
LLVM_ABI void getNonLocalPointerDependency(Instruction *QueryInst, SmallVectorImpl< NonLocalDepResult > &Result)
Perform a full dependency query for an access to the QueryInst's specified memory location,...
LLVM_ABI bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
Handle invalidation in the new PM.
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance.
bool runOnFunction(Function &) override
Pass Implementation stuff. This doesn't do any analysis eagerly.
~MemoryDependenceWrapperPass() override
void getAnalysisUsage(AnalysisUsage &AU) const override
Does not modify anything. It uses Value Numbering and Alias Analysis.
void releaseMemory() override
Clean up memory in between runs.
MemoryDependenceWrapperPass()
Representation for a specific memory location.
MemoryLocation getWithoutAATags() const
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known.
static MemoryLocation getAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location after Ptr, while remaining within the underlying objec...
MemoryLocation getWithNewPtr(const Value *NewPtr) const
AAMDNodes AATags
The metadata nodes which describes the aliasing of the location (each member is null if that kind of ...
const Value * Ptr
The address of the start of the location.
static LLVM_ABI MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
This is an entry in the NonLocalDepInfo cache.
void setResult(const MemDepResult &R)
const MemDepResult & getResult() const
This is a result from a NonLocal dependence query.
PHITransAddr - An address value which tracks and handles phi translation.
LLVM_ABI Value * translateValue(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree *DT, bool MustDominate)
translateValue - PHI translate the current address up the CFG from CurBB to Pred, updating our state ...
LLVM_ABI Value * getSelectCondition() const
If the address expression depends on a select instruction (possibly through casts or GEPs),...
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
A set of analyses that are preserved following a run of a transformation pass.
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
std::pair< Value *, Value * > SelectAddrs
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator erase(const_iterator CI)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool isPointerTy() const
True if this is an instance of PointerType.
A Use represents the edge between a Value definition and its users.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
iterator_range< use_iterator > uses()
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
const ParentTy * getParent() const
self_iterator getIterator()
Abstract Attribute helper functions.
@ BasicBlock
Various leaf nodes.
initializer< Ty > init(const Ty &Val)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
bool isStrongerThanUnordered(AtomicOrdering AO)
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
auto reverse(ContainerTy &&C)
bool isModSet(const ModRefInfo MRI)
void sort(IteratorTy Start, IteratorTy End)
bool isModOrRefSet(const ModRefInfo MRI)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
AtomicOrdering
Atomic ordering for LLVM's memory model.
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ Ref
The access may reference the value stored in memory.
@ ModRef
The access may reference and may modify the value stored in memory.
@ Mod
The access may modify the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isNoModRef(const ModRefInfo MRI)
bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other)
Returns true if ao is stronger than other as defined by the AtomicOrdering lattice,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
A special type used by analysis passes to provide an address that identifies that particular analysis...