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");
78template <
typename KeyTy>
83 ReverseMap.find(Inst);
84 assert(InstIt != ReverseMap.
end() &&
"Reverse map out of sync?");
85 bool Found = InstIt->second.
erase(Val);
86 assert(Found &&
"Invalid reverse map!");
88 if (InstIt->second.
empty())
89 ReverseMap.erase(InstIt);
100 if (LI->isUnordered()) {
113 if (
SI->isUnordered()) {
139 switch (
II->getIntrinsicID()) {
140 case Intrinsic::lifetime_start:
141 case Intrinsic::lifetime_end:
146 case Intrinsic::invariant_start:
151 case Intrinsic::invariant_end:
156 case Intrinsic::masked_load:
159 case Intrinsic::masked_store:
176MemDepResult MemoryDependenceResults::getCallDependencyFrom(
180 bool IsInvariantLoad =
Call->
hasMetadata(LLVMContext::MD_invariant_load);
183 while (ScanIt != BB->
begin()) {
206 bool IsIdenticalReadOnlyCall = isReadOnlyCall && !
isModSet(MR) &&
211 if (IsInvariantLoad && IsIdenticalReadOnlyCall)
218 if (IsIdenticalReadOnlyCall)
224 }
else if (IsInvariantLoad) {
249 if (QueryInst !=
nullptr) {
253 if (InvariantGroupDependency.
isDef())
254 return InvariantGroupDependency;
258 MemLoc,
isLoad, ScanIt, BB, QueryInst, Limit, BatchAA);
259 if (SimpleDep.
isDef())
265 return InvariantGroupDependency;
268 "InvariantGroupDependency should be only unknown at this point");
284 if (!LI->
hasMetadata(LLVMContext::MD_invariant_group))
302 assert(
Other &&
"Must call it with not null instruction");
303 if (Best ==
nullptr || DT.dominates(Best,
Other))
308 for (
const Use &Us : LoadOperand->
uses()) {
310 if (!U || U == LI || !DT.dominates(U, LI))
319 U->hasMetadata(LLVMContext::MD_invariant_group))
320 ClosestDependency = GetClosestDependency(ClosestDependency, U);
323 if (!ClosestDependency)
325 if (ClosestDependency->
getParent() == BB)
331 NonLocalDefsCache.try_emplace(
334 ReverseNonLocalDefsCache[ClosestDependency].insert(LI);
348 Limit = &DefaultLimit;
382 if (
isLoad && QueryInst) {
385 MemLocAlign = LI->getAlign();
398 return I->mayReadOrWriteMemory();
402 while (ScanIt != BB->
begin()) {
416 case Intrinsic::lifetime_start: {
426 case Intrinsic::masked_load:
427 case Intrinsic::masked_store: {
435 if (ID == Intrinsic::masked_load)
451 if (LI->isVolatile()) {
489 ClobberOffsets[LI] = R.getOffset();
510 if (!
SI->isUnordered() &&
SI->isAtomic()) {
528 if (
SI->isVolatile())
566 if (AccessPtr == Inst || BatchAA.
isMustAlias(Inst, AccessPtr))
614 ClobberOffsets.clear();
622 if (!LocalCache.isDirty())
650 isLoad |=
II->getIntrinsicID() == Intrinsic::lifetime_start;
654 QueryParent, QueryInst,
nullptr);
656 bool isReadOnly = AA.onlyReadsMemory(QueryCall);
657 LocalCache = getCallDependencyFrom(QueryCall, isReadOnly,
666 ReverseLocalDeps[
I].insert(QueryInst);
677 Count = Cache.size();
678 assert(std::is_sorted(Cache.begin(), Cache.begin() +
Count) &&
679 "Cache isn't sorted!");
686 "getNonLocalCallDependency should only be used on calls with "
688 PerInstNLInfo &CacheP = NonLocalDepsMap[QueryCall];
696 if (!Cache.empty()) {
699 if (!CacheP.second) {
706 for (
auto &Entry : Cache)
707 if (Entry.getResult().isDirty())
713 ++NumCacheDirtyNonLocal;
718 ++NumUncacheNonLocal;
722 bool isReadonlyCall = AA.onlyReadsMemory(QueryCall);
726 unsigned NumSortedEntries = Cache.
size();
730 while (!DirtyBlocks.
empty()) {
734 if (!Visited.
insert(DirtyBB).second)
740 NonLocalDepInfo::iterator Entry =
741 std::upper_bound(Cache.begin(), Cache.begin() + NumSortedEntries,
743 if (Entry != Cache.begin() && std::prev(Entry)->getBB() == DirtyBB)
747 if (Entry != Cache.begin() + NumSortedEntries &&
748 Entry->getBB() == DirtyBB) {
751 if (!Entry->getResult().isDirty())
755 ExistingResult = &*Entry;
761 if (ExistingResult) {
773 if (ScanPos != DirtyBB->
begin()) {
774 Dep = getCallDependencyFrom(QueryCall, isReadonlyCall, ScanPos, DirtyBB);
796 ReverseNonLocalDeps[Inst].insert(QueryCall);
815 assert(
Loc.Ptr->getType()->isPointerTy() &&
816 "Can't get pointer deps of a non-pointer!");
820 auto NonLocalDefIt = NonLocalDefsCache.find(QueryInst);
821 if (NonLocalDefIt != NonLocalDefsCache.end()) {
822 Result.push_back(NonLocalDefIt->second);
824 ReverseNonLocalDefsCache, NonLocalDefIt->second.getResult().getInst(),
826 NonLocalDefsCache.erase(NonLocalDefIt);
840 return !LI->isUnordered();
842 return !
SI->isUnordered();
858 ++NonLocalPointerDepEpoch;
859 assert(NonLocalPointerDepEpoch > 0 &&
860 "NonLocalPointerDepVisitedEpoch overflow");
875MemDepResult MemoryDependenceResults::getNonLocalInfoForBlock(
877 BasicBlock *BB, NonLocalDepInfo *Cache,
unsigned NumSortedEntries,
887 NonLocalDepInfo::iterator Entry = std::upper_bound(
889 if (Entry != Cache->begin() && (Entry - 1)->getBB() == BB)
893 if (Entry != Cache->begin() + NumSortedEntries && Entry->getBB() == BB)
894 ExistingResult = &*Entry;
901 ExistingResult =
nullptr;
905 if (ExistingResult && !ExistingResult->
getResult().isDirty()) {
906 ++NumCacheNonLocalPtr;
916 "Instruction invalidated?");
917 ++NumCacheDirtyNonLocalPtr;
921 ValueIsLoadPair CacheKey(
Loc.Ptr,
isLoad);
924 ++NumUncacheNonLocalPtr;
929 QueryInst,
nullptr, BatchAA);
940 Cache->push_back(NonLocalDepEntry(BB, Dep));
951 assert(Inst &&
"Didn't depend on anything?");
952 ValueIsLoadPair CacheKey(Loc.
Ptr,
isLoad);
953 ReverseNonLocalPtrDeps[Inst].insert(CacheKey);
963 unsigned NumSortedEntries) {
966 if (Cache.size() < 2)
969 unsigned s = Cache.size() - NumSortedEntries;
976 if (NumSortedEntries == 0) {
984 if (s <
Log2_32(Cache.size())) {
988 MemoryDependenceResults::NonLocalDepInfo::iterator Entry =
989 std::upper_bound(Cache.begin(), Cache.end() - s + 1, Val);
990 Cache.insert(Entry, Val);
998void MemoryDependenceResults::setNonLocalPointerDepVisited(
BasicBlock *BB,
1000 NonLocalPointerDepVisited[BB->
getNumber()] = {
V, NonLocalPointerDepEpoch};
1003bool MemoryDependenceResults::isNonLocalPointerDepVisited(
1005 return NonLocalPointerDepVisited[BB->
getNumber()].second ==
1006 NonLocalPointerDepEpoch;
1010MemoryDependenceResults::lookupNonLocalPointerDepVisited(
BasicBlock *BB)
const {
1011 assert(isNonLocalPointerDepVisited(BB) &&
1012 "Visited value requested for unseen block");
1013 return NonLocalPointerDepVisited[BB->
getNumber()].first;
1029bool MemoryDependenceResults::getNonLocalPointerDepFromBB(
1033 bool IsIncomplete) {
1041 NonLocalPointerInfo InitialNLPI;
1042 InitialNLPI.Size = Loc.
Size;
1043 InitialNLPI.AATags = Loc.
AATags;
1051 std::pair<CachedNonLocalPointerInfo::iterator, bool> Pair =
1052 NonLocalPointerDeps.insert(std::make_pair(CacheKey, InitialNLPI));
1053 NonLocalPointerInfo *CacheInfo = &Pair.first->second;
1059 if (CacheInfo->Size != Loc.
Size) {
1062 CacheInfo->Pair = BBSkipFirstBlockPair();
1063 CacheInfo->Size = Loc.
Size;
1064 for (
auto &Entry : CacheInfo->NonLocalDeps)
1065 if (Instruction *Inst =
Entry.getResult().getInst())
1067 CacheInfo->NonLocalDeps.clear();
1071 IsIncomplete =
true;
1077 if (CacheInfo->AATags != Loc.
AATags) {
1078 if (CacheInfo->AATags) {
1079 CacheInfo->Pair = BBSkipFirstBlockPair();
1080 CacheInfo->AATags = AAMDNodes();
1081 for (
auto &Entry : CacheInfo->NonLocalDeps)
1082 if (Instruction *Inst =
Entry.getResult().getInst())
1084 CacheInfo->NonLocalDeps.clear();
1088 IsIncomplete =
true;
1091 return getNonLocalPointerDepFromBB(
1093 SkipFirstBlock, IsIncomplete);
1104 CacheInfo->Pair == BBSkipFirstBlockPair(StartBB, SkipFirstBlock)) {
1110 for (
auto &Entry : *Cache) {
1111 if (!isNonLocalPointerDepVisited(
Entry.getBB()))
1113 Value *Prev = lookupNonLocalPointerDepVisited(
Entry.getBB());
1114 if (Prev ==
Pointer.getAddr())
1124 for (
auto &Entry : *Cache) {
1125 setNonLocalPointerDepVisited(
Entry.getBB(), Addr);
1126 if (
Entry.getResult().isNonLocal()) {
1130 if (DT.isReachableFromEntry(
Entry.getBB())) {
1132 NonLocalDepResult(
Entry.getBB(),
Entry.getResult(), Addr));
1135 ++NumCacheCompleteNonLocalPtr;
1140 if (Cache->size() > Opts.memdep_cache_global_limit)
1151 if (!IsIncomplete && Cache->empty())
1152 CacheInfo->Pair = BBSkipFirstBlockPair(StartBB, SkipFirstBlock);
1154 CacheInfo->Pair = BBSkipFirstBlockPair();
1168 unsigned NumSortedEntries = Cache->size();
1169 unsigned WorklistEntries = Opts.memdep_block_number_limit;
1170 bool GotWorklistLimit =
false;
1173 BatchAAResults BatchAA(AA, &EEA);
1174 while (!Worklist.
empty()) {
1183 if (Cache && NumSortedEntries != Cache->size()) {
1190 CacheInfo->Pair = BBSkipFirstBlockPair();
1195 if (!SkipFirstBlock) {
1198 assert(isNonLocalPointerDepVisited(BB) &&
1199 "Should check 'visited' before adding to WL");
1204 MemDepResult Dep = getNonLocalInfoForBlock(
1205 QueryInst, Loc,
isLoad, BB, Cache, NumSortedEntries, BatchAA);
1209 if (DT.isReachableFromEntry(BB)) {
1210 Result.push_back(NonLocalDepResult(BB, Dep,
Pointer.getAddr()));
1220 if (!
Pointer.needsPHITranslationFromBlock(BB)) {
1221 SkipFirstBlock =
false;
1222 SmallVector<BasicBlock *, 16> NewBlocks;
1223 for (BasicBlock *Pred : PredCache.get(BB)) {
1225 if (!isNonLocalPointerDepVisited(Pred)) {
1226 setNonLocalPointerDepVisited(Pred,
Pointer.getAddr());
1231 Value *Prev = lookupNonLocalPointerDepVisited(Pred);
1235 if (Prev !=
Pointer.getAddr()) {
1238 for (
auto *NewBlock : NewBlocks)
1239 setNonLocalPointerDepVisited(NewBlock,
nullptr);
1240 goto PredTranslationFailure;
1243 if (NewBlocks.
size() > WorklistEntries) {
1246 for (
auto *NewBlock : NewBlocks)
1247 setNonLocalPointerDepVisited(NewBlock,
nullptr);
1248 GotWorklistLimit =
true;
1249 goto PredTranslationFailure;
1251 WorklistEntries -= NewBlocks.
size();
1258 if (!
Pointer.isPotentiallyPHITranslatable())
1259 goto PredTranslationFailure;
1266 if (Cache && NumSortedEntries != Cache->size()) {
1268 NumSortedEntries = Cache->size();
1273 for (BasicBlock *Pred : PredCache.get(BB)) {
1274 PredList.
push_back(std::make_pair(Pred, Pointer));
1278 PHITransAddr &PredPointer = PredList.
back().second;
1287 if (!isNonLocalPointerDepVisited(Pred)) {
1288 setNonLocalPointerDepVisited(Pred, PredPtrVal);
1291 Value *PrevVal = lookupNonLocalPointerDepVisited(Pred);
1298 if (PrevVal == PredPtrVal)
1307 for (
const auto &Pred : PredList)
1308 setNonLocalPointerDepVisited(Pred.first,
nullptr);
1310 goto PredTranslationFailure;
1318 for (
auto &
I : PredList) {
1320 PHITransAddr &PredPointer =
I.second;
1323 bool CanTranslate =
true;
1335 if (SelectInst *Sel = PredPointer.
getSelect()) {
1337 PHITransAddr(Pointer).translateValue(BB, Pred, &DT,
1338 Sel->getCondition());
1339 if (SelAddrs.first && SelAddrs.second) {
1341 SelectAddr(Sel, SelAddrs)));
1342 NonLocalPointerInfo &NLPI = NonLocalPointerDeps[CacheKey];
1343 NLPI.Pair = BBSkipFirstBlockPair();
1347 CanTranslate =
false;
1358 if (!CanTranslate ||
1359 !getNonLocalPointerDepFromBB(QueryInst, PredPointer,
1371 NonLocalPointerInfo &NLPI = NonLocalPointerDeps[CacheKey];
1372 NLPI.Pair = BBSkipFirstBlockPair();
1378 CacheInfo = &NonLocalPointerDeps[CacheKey];
1379 Cache = &CacheInfo->NonLocalDeps;
1380 NumSortedEntries = Cache->size();
1386 CacheInfo->Pair = BBSkipFirstBlockPair();
1387 SkipFirstBlock =
false;
1390 PredTranslationFailure:
1397 CacheInfo = &NonLocalPointerDeps[CacheKey];
1398 Cache = &CacheInfo->NonLocalDeps;
1399 NumSortedEntries = Cache->size();
1406 CacheInfo->Pair = BBSkipFirstBlockPair();
1420 if (
I.getBB() != BB)
1423 assert((GotWorklistLimit ||
I.getResult().isNonLocal() ||
1424 !DT.isReachableFromEntry(BB)) &&
1425 "Should only be here with transparent block");
1433 (void)GotWorklistLimit;
1446void MemoryDependenceResults::removeCachedNonLocalPointerDependencies(
1447 ValueIsLoadPair
P) {
1450 if (!NonLocalDefsCache.empty()) {
1451 auto it = NonLocalDefsCache.find(
P.getPointer());
1452 if (it != NonLocalDefsCache.end()) {
1454 it->second.getResult().getInst(),
P.getPointer());
1455 NonLocalDefsCache.erase(it);
1459 auto toRemoveIt = ReverseNonLocalDefsCache.find(
I);
1460 if (toRemoveIt != ReverseNonLocalDefsCache.end()) {
1461 for (
const auto *Entry : toRemoveIt->second) {
1462 [[maybe_unused]]
bool Removed = NonLocalDefsCache.erase(Entry);
1463 assert(Removed &&
"Reverse non-local def map out of sync?");
1465 ReverseNonLocalDefsCache.erase(toRemoveIt);
1471 if (It == NonLocalPointerDeps.end())
1478 for (
const NonLocalDepEntry &DE : PInfo) {
1489 NonLocalPointerDeps.erase(It);
1497 removeCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr,
false));
1499 removeCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr,
true));
1507 EEA.removeInstruction(RemInst);
1512 if (NLDI != NonLocalDepsMap.end()) {
1514 for (
auto &Entry : BlockMap)
1515 if (
Instruction *Inst = Entry.getResult().getInst())
1517 NonLocalDepsMap.erase(NLDI);
1522 if (LocalDepEntry != LocalDeps.end()) {
1524 if (
Instruction *Inst = LocalDepEntry->second.getInst())
1528 LocalDeps.erase(LocalDepEntry);
1537 removeCachedNonLocalPointerDependencies(ValueIsLoadPair(RemInst,
false));
1538 removeCachedNonLocalPointerDependencies(ValueIsLoadPair(RemInst,
true));
1542 auto toRemoveIt = NonLocalDefsCache.find(RemInst);
1543 if (toRemoveIt != NonLocalDefsCache.end()) {
1545 "only load instructions should be added directly");
1546 Instruction *DepV = toRemoveIt->second.getResult().getInst();
1549 NonLocalDefsCache.erase(toRemoveIt);
1553 auto ReverseNonLocalDefIt = ReverseNonLocalDefsCache.find(RemInst);
1554 if (ReverseNonLocalDefIt != ReverseNonLocalDefsCache.end()) {
1555 for (
const Value *QueryInst : ReverseNonLocalDefIt->second) {
1556 [[maybe_unused]]
bool Removed = NonLocalDefsCache.erase(QueryInst);
1557 assert(Removed &&
"Reverse non-local def map out of sync?");
1559 ReverseNonLocalDefsCache.erase(ReverseNonLocalDefIt);
1573 NewDirtyVal = MemDepResult::getDirty(&*++RemInst->
getIterator());
1575 ReverseDepMapType::iterator ReverseDepIt = ReverseLocalDeps.find(RemInst);
1576 if (ReverseDepIt != ReverseLocalDeps.end()) {
1579 "Nothing can locally depend on a terminator");
1581 for (
Instruction *InstDependingOnRemInst : ReverseDepIt->second) {
1582 assert(InstDependingOnRemInst != RemInst &&
1583 "Already removed our local dep info");
1585 LocalDeps[InstDependingOnRemInst] = NewDirtyVal;
1589 "There is no way something else can have "
1590 "a local dep on this if it is a terminator!");
1592 std::make_pair(NewDirtyVal.
getInst(), InstDependingOnRemInst));
1595 ReverseLocalDeps.erase(ReverseDepIt);
1599 while (!ReverseDepsToAdd.
empty()) {
1600 ReverseLocalDeps[ReverseDepsToAdd.
back().first].insert(
1601 ReverseDepsToAdd.
back().second);
1606 ReverseDepIt = ReverseNonLocalDeps.find(RemInst);
1607 if (ReverseDepIt != ReverseNonLocalDeps.end()) {
1609 assert(
I != RemInst &&
"Already removed NonLocalDep info for RemInst");
1611 PerInstNLInfo &INLD = NonLocalDepsMap[
I];
1615 for (
auto &Entry : INLD.first) {
1616 if (Entry.getResult().getInst() != RemInst)
1620 Entry.setResult(NewDirtyVal);
1623 ReverseDepsToAdd.
push_back(std::make_pair(NextI,
I));
1627 ReverseNonLocalDeps.erase(ReverseDepIt);
1630 while (!ReverseDepsToAdd.
empty()) {
1631 ReverseNonLocalDeps[ReverseDepsToAdd.
back().first].insert(
1632 ReverseDepsToAdd.
back().second);
1639 ReverseNonLocalPtrDepTy::iterator ReversePtrDepIt =
1640 ReverseNonLocalPtrDeps.find(RemInst);
1641 if (ReversePtrDepIt != ReverseNonLocalPtrDeps.end()) {
1643 ReversePtrDepsToAdd;
1645 for (ValueIsLoadPair
P : ReversePtrDepIt->second) {
1646 assert(
P.getPointer() != RemInst &&
1647 "Already removed NonLocalPointerDeps info for RemInst");
1649 auto &NLPD = NonLocalPointerDeps[
P];
1654 NLPD.Pair = BBSkipFirstBlockPair();
1657 for (
auto &Entry : NLPDI) {
1658 if (Entry.getResult().getInst() != RemInst)
1662 Entry.setResult(NewDirtyVal);
1665 ReversePtrDepsToAdd.
push_back(std::make_pair(NewDirtyInst,
P));
1673 ReverseNonLocalPtrDeps.
erase(ReversePtrDepIt);
1675 while (!ReversePtrDepsToAdd.
empty()) {
1676 ReverseNonLocalPtrDeps[ReversePtrDepsToAdd.
back().first].insert(
1677 ReversePtrDepsToAdd.
back().second);
1682 assert(!NonLocalDepsMap.count(RemInst) &&
"RemInst got reinserted?");
1690void MemoryDependenceResults::verifyRemoved(
Instruction *
D)
const {
1692 for (
const auto &DepKV : LocalDeps) {
1693 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1694 assert(DepKV.second.getInst() !=
D &&
"Inst occurs in data structures");
1697 for (
const auto &DepKV : NonLocalPointerDeps) {
1698 assert(DepKV.first.getPointer() !=
D &&
"Inst occurs in NLPD map key");
1699 for (
const auto &Entry : DepKV.second.NonLocalDeps)
1700 assert(Entry.getResult().getInst() !=
D &&
"Inst occurs as NLPD value");
1703 for (
const auto &DepKV : NonLocalDepsMap) {
1704 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1705 const PerInstNLInfo &INLD = DepKV.second;
1706 for (
const auto &Entry : INLD.first)
1708 "Inst occurs in data structures");
1711 for (
const auto &DepKV : ReverseLocalDeps) {
1712 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1713 for (Instruction *Inst : DepKV.second)
1714 assert(Inst !=
D &&
"Inst occurs in data structures");
1717 for (
const auto &DepKV : ReverseNonLocalDeps) {
1718 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1719 for (Instruction *Inst : DepKV.second)
1720 assert(Inst !=
D &&
"Inst occurs in data structures");
1723 for (
const auto &DepKV : ReverseNonLocalPtrDeps) {
1724 assert(DepKV.first !=
D &&
"Inst occurs in rev NLPD map");
1726 for (ValueIsLoadPair
P : DepKV.second)
1727 assert(
P != ValueIsLoadPair(
D,
false) &&
P != ValueIsLoadPair(
D,
true) &&
1728 "Inst occurs in ReverseNonLocalPtrDeps map");
1745 DefaultBlockScanLimit.value_or(
1752 "Memory Dependence Analysis",
false,
true)
1780 unsigned DefaultBlockScanLimit)
1782 TLI(TLI), DT(DT), EEA(DT), DefaultBlockScanLimit(DefaultBlockScanLimit) {}
1785 FunctionAnalysisManager::Invalidator &Inv) {
1803 return DefaultBlockScanLimit;
1811 MemDep.emplace(
AA, AC, TLI, DT,
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isLoad(int Opcode)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Atomic ordering constants.
static const Function * getParent(const Value *V)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static DeltaTreeNode * getRoot(void *Root)
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 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 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.
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)
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.
A cache of @llvm.assume calls within a function.
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.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
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()
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 MemoryDependenceResults(AAResults &AA, AssumptionCache &AC, const TargetLibraryInfo &TLI, DominatorTree &DT, unsigned DefaultBlockScanLimit)
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 SelectInst * getSelect() 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()
const ParentTy * getParent() const
self_iterator getIterator()
Abstract Attribute helper functions.
@ BasicBlock
Various leaf nodes.
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.
LLVM_ABI bool isStorePreservingMemoryLocation(const StoreInst *SI, const MemoryLocation &MemLoc, Align MemLocAlign, BatchAAResults &AA, unsigned ScanLimit)
Check whether SI, which may alias MemLoc, can be safely skipped.
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
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
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...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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.
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...