57#define DEBUG_TYPE "memdep"
59STATISTIC(NumCacheNonLocal,
"Number of fully cached non-local responses");
60STATISTIC(NumCacheDirtyNonLocal,
"Number of dirty cached non-local responses");
61STATISTIC(NumUncacheNonLocal,
"Number of uncached non-local responses");
64 "Number of fully cached non-local ptr responses");
66 "Number of cached, but dirty, non-local ptr responses");
67STATISTIC(NumUncacheNonLocalPtr,
"Number of uncached non-local ptr responses");
69 "Number of block queries that were completely cached");
75 cl::desc(
"The number of instructions to scan in a block in memory "
76 "dependency analysis (default = 100)"));
80 cl::desc(
"The number of blocks to scan during memory "
81 "dependency analysis (default = 200)"));
85 cl::desc(
"The max number of entries allowed in a cache (default = 10000)"));
93template <
typename KeyTy>
98 ReverseMap.find(Inst);
99 assert(InstIt != ReverseMap.
end() &&
"Reverse map out of sync?");
100 bool Found = InstIt->second.
erase(Val);
101 assert(Found &&
"Invalid reverse map!");
103 if (InstIt->second.
empty())
104 ReverseMap.erase(InstIt);
115 if (LI->isUnordered()) {
128 if (
SI->isUnordered()) {
154 switch (
II->getIntrinsicID()) {
155 case Intrinsic::lifetime_start:
156 case Intrinsic::lifetime_end:
161 case Intrinsic::invariant_start:
166 case Intrinsic::invariant_end:
171 case Intrinsic::masked_load:
174 case Intrinsic::masked_store:
191MemDepResult MemoryDependenceResults::getCallDependencyFrom(
197 while (ScanIt != BB->
begin()) {
221 if (isReadOnlyCall && !
isModSet(MR) &&
250 if (QueryInst !=
nullptr) {
254 if (InvariantGroupDependency.
isDef())
255 return InvariantGroupDependency;
259 MemLoc,
isLoad, ScanIt, BB, QueryInst, Limit, BatchAA);
260 if (SimpleDep.
isDef())
266 return InvariantGroupDependency;
269 "InvariantGroupDependency should be only unknown at this point");
285 if (!LI->
hasMetadata(LLVMContext::MD_invariant_group))
303 assert(
Other &&
"Must call it with not null instruction");
304 if (Best ==
nullptr || DT.dominates(Best,
Other))
309 for (
const Use &Us : LoadOperand->
uses()) {
311 if (!U || U == LI || !DT.dominates(U, LI))
320 U->hasMetadata(LLVMContext::MD_invariant_group))
321 ClosestDependency = GetClosestDependency(ClosestDependency, U);
324 if (!ClosestDependency)
326 if (ClosestDependency->
getParent() == BB)
332 NonLocalDefsCache.try_emplace(
335 ReverseNonLocalDefsCache[ClosestDependency].insert(LI);
347 unsigned ScanLimit) {
354 if (std::min(MemLocAlign,
SI->getAlign()).value() <
359 if (!LI || LI->getParent() !=
SI->getParent())
363 unsigned NumVisitedInsts = 0;
365 if (++NumVisitedInsts > ScanLimit ||
382 Limit = &DefaultLimit;
418 if (LI->hasMetadata(LLVMContext::MD_invariant_load))
420 MemLocAlign = LI->getAlign();
433 return I->mayReadOrWriteMemory();
437 while (ScanIt != BB->
begin()) {
451 case Intrinsic::lifetime_start: {
457 case Intrinsic::masked_load:
458 case Intrinsic::masked_store: {
466 if (
ID == Intrinsic::masked_load)
482 if (LI->isVolatile()) {
520 ClobberOffsets[LI] = R.getOffset();
541 if (!
SI->isUnordered() &&
SI->isAtomic()) {
559 if (
SI->isVolatile())
596 if (AccessPtr == Inst || BatchAA.
isMustAlias(Inst, AccessPtr))
644 ClobberOffsets.clear();
652 if (!LocalCache.isDirty())
680 isLoad |=
II->getIntrinsicID() == Intrinsic::lifetime_start;
684 QueryParent, QueryInst,
nullptr);
686 bool isReadOnly = AA.onlyReadsMemory(QueryCall);
687 LocalCache = getCallDependencyFrom(QueryCall, isReadOnly,
696 ReverseLocalDeps[
I].insert(QueryInst);
707 Count = Cache.size();
708 assert(std::is_sorted(Cache.begin(), Cache.begin() +
Count) &&
709 "Cache isn't sorted!");
716 "getNonLocalCallDependency should only be used on calls with "
718 PerInstNLInfo &CacheP = NonLocalDepsMap[QueryCall];
726 if (!Cache.empty()) {
729 if (!CacheP.second) {
736 for (
auto &Entry : Cache)
737 if (Entry.getResult().isDirty())
743 ++NumCacheDirtyNonLocal;
748 ++NumUncacheNonLocal;
752 bool isReadonlyCall = AA.onlyReadsMemory(QueryCall);
756 unsigned NumSortedEntries = Cache.
size();
760 while (!DirtyBlocks.
empty()) {
764 if (!Visited.
insert(DirtyBB).second)
770 NonLocalDepInfo::iterator Entry =
771 std::upper_bound(Cache.begin(), Cache.begin() + NumSortedEntries,
773 if (Entry != Cache.begin() && std::prev(Entry)->getBB() == DirtyBB)
777 if (Entry != Cache.begin() + NumSortedEntries &&
778 Entry->getBB() == DirtyBB) {
781 if (!Entry->getResult().isDirty())
785 ExistingResult = &*Entry;
791 if (ExistingResult) {
803 if (ScanPos != DirtyBB->
begin()) {
804 Dep = getCallDependencyFrom(QueryCall, isReadonlyCall, ScanPos, DirtyBB);
826 ReverseNonLocalDeps[Inst].insert(QueryCall);
845 assert(
Loc.Ptr->getType()->isPointerTy() &&
846 "Can't get pointer deps of a non-pointer!");
850 auto NonLocalDefIt = NonLocalDefsCache.find(QueryInst);
851 if (NonLocalDefIt != NonLocalDefsCache.end()) {
852 Result.push_back(NonLocalDefIt->second);
853 ReverseNonLocalDefsCache[NonLocalDefIt->second.getResult().getInst()]
855 NonLocalDefsCache.erase(NonLocalDefIt);
869 return !LI->isUnordered();
871 return !
SI->isUnordered();
887 ++NonLocalPointerDepEpoch;
888 assert(NonLocalPointerDepEpoch > 0 &&
889 "NonLocalPointerDepVisitedEpoch overflow");
904MemDepResult MemoryDependenceResults::getNonLocalInfoForBlock(
906 BasicBlock *BB, NonLocalDepInfo *Cache,
unsigned NumSortedEntries,
916 NonLocalDepInfo::iterator Entry = std::upper_bound(
918 if (Entry != Cache->begin() && (Entry - 1)->getBB() == BB)
922 if (Entry != Cache->begin() + NumSortedEntries && Entry->getBB() == BB)
923 ExistingResult = &*Entry;
930 ExistingResult =
nullptr;
934 if (ExistingResult && !ExistingResult->
getResult().isDirty()) {
935 ++NumCacheNonLocalPtr;
945 "Instruction invalidated?");
946 ++NumCacheDirtyNonLocalPtr;
950 ValueIsLoadPair CacheKey(
Loc.Ptr,
isLoad);
953 ++NumUncacheNonLocalPtr;
958 QueryInst,
nullptr, BatchAA);
969 Cache->push_back(NonLocalDepEntry(BB, Dep));
980 assert(Inst &&
"Didn't depend on anything?");
981 ValueIsLoadPair CacheKey(Loc.
Ptr,
isLoad);
982 ReverseNonLocalPtrDeps[Inst].insert(CacheKey);
992 unsigned NumSortedEntries) {
995 if (Cache.size() < 2)
998 unsigned s = Cache.size() - NumSortedEntries;
1005 if (NumSortedEntries == 0) {
1013 if (s <
Log2_32(Cache.size())) {
1017 MemoryDependenceResults::NonLocalDepInfo::iterator Entry =
1018 std::upper_bound(Cache.begin(), Cache.end() - s + 1, Val);
1019 Cache.insert(Entry, Val);
1027void MemoryDependenceResults::setNonLocalPointerDepVisited(
BasicBlock *BB,
1029 NonLocalPointerDepVisited[BB->
getNumber()] = {
V, NonLocalPointerDepEpoch};
1033MemoryDependenceResults::lookupNonLocalPointerDepVisited(
BasicBlock *BB)
const {
1035 return Entry.second == NonLocalPointerDepEpoch ?
Entry.first :
nullptr;
1051bool MemoryDependenceResults::getNonLocalPointerDepFromBB(
1055 bool IsIncomplete) {
1063 NonLocalPointerInfo InitialNLPI;
1064 InitialNLPI.Size = Loc.
Size;
1065 InitialNLPI.AATags = Loc.
AATags;
1073 std::pair<CachedNonLocalPointerInfo::iterator, bool> Pair =
1074 NonLocalPointerDeps.insert(std::make_pair(CacheKey, InitialNLPI));
1075 NonLocalPointerInfo *CacheInfo = &Pair.first->second;
1081 if (CacheInfo->Size != Loc.
Size) {
1084 CacheInfo->Pair = BBSkipFirstBlockPair();
1085 CacheInfo->Size = Loc.
Size;
1086 for (
auto &Entry : CacheInfo->NonLocalDeps)
1087 if (Instruction *Inst =
Entry.getResult().getInst())
1089 CacheInfo->NonLocalDeps.clear();
1093 IsIncomplete =
true;
1099 if (CacheInfo->AATags != Loc.
AATags) {
1100 if (CacheInfo->AATags) {
1101 CacheInfo->Pair = BBSkipFirstBlockPair();
1102 CacheInfo->AATags = AAMDNodes();
1103 for (
auto &Entry : CacheInfo->NonLocalDeps)
1104 if (Instruction *Inst =
Entry.getResult().getInst())
1106 CacheInfo->NonLocalDeps.clear();
1110 IsIncomplete =
true;
1113 return getNonLocalPointerDepFromBB(
1115 SkipFirstBlock, IsIncomplete);
1126 CacheInfo->Pair == BBSkipFirstBlockPair(StartBB, SkipFirstBlock)) {
1132 for (
auto &Entry : *Cache) {
1133 Value *Prev = lookupNonLocalPointerDepVisited(
Entry.getBB());
1134 if (!Prev || Prev ==
Pointer.getAddr())
1144 for (
auto &Entry : *Cache) {
1145 setNonLocalPointerDepVisited(
Entry.getBB(), Addr);
1146 if (
Entry.getResult().isNonLocal()) {
1150 if (DT.isReachableFromEntry(
Entry.getBB())) {
1152 NonLocalDepResult(
Entry.getBB(),
Entry.getResult(), Addr));
1155 ++NumCacheCompleteNonLocalPtr;
1171 if (!IsIncomplete && Cache->empty())
1172 CacheInfo->Pair = BBSkipFirstBlockPair(StartBB, SkipFirstBlock);
1174 CacheInfo->Pair = BBSkipFirstBlockPair();
1188 unsigned NumSortedEntries = Cache->size();
1190 bool GotWorklistLimit =
false;
1193 BatchAAResults BatchAA(AA, &EEA);
1194 while (!Worklist.
empty()) {
1203 if (Cache && NumSortedEntries != Cache->size()) {
1210 CacheInfo->Pair = BBSkipFirstBlockPair();
1215 if (!SkipFirstBlock) {
1218 assert(lookupNonLocalPointerDepVisited(BB) &&
1219 "Should check 'visited' before adding to WL");
1224 MemDepResult Dep = getNonLocalInfoForBlock(
1225 QueryInst, Loc,
isLoad, BB, Cache, NumSortedEntries, BatchAA);
1229 if (DT.isReachableFromEntry(BB)) {
1230 Result.push_back(NonLocalDepResult(BB, Dep,
Pointer.getAddr()));
1240 if (!
Pointer.needsPHITranslationFromBlock(BB)) {
1241 SkipFirstBlock =
false;
1242 SmallVector<BasicBlock *, 16> NewBlocks;
1243 for (BasicBlock *Pred : PredCache.get(BB)) {
1245 Value *Prev = lookupNonLocalPointerDepVisited(Pred);
1247 setNonLocalPointerDepVisited(Pred,
Pointer.getAddr());
1256 if (Prev !=
Pointer.getAddr()) {
1259 for (
auto *NewBlock : NewBlocks)
1260 setNonLocalPointerDepVisited(NewBlock,
nullptr);
1261 goto PredTranslationFailure;
1264 if (NewBlocks.
size() > WorklistEntries) {
1267 for (
auto *NewBlock : NewBlocks)
1268 setNonLocalPointerDepVisited(NewBlock,
nullptr);
1269 GotWorklistLimit =
true;
1270 goto PredTranslationFailure;
1272 WorklistEntries -= NewBlocks.
size();
1279 if (!
Pointer.isPotentiallyPHITranslatable())
1280 goto PredTranslationFailure;
1287 if (Cache && NumSortedEntries != Cache->size()) {
1289 NumSortedEntries = Cache->size();
1294 for (BasicBlock *Pred : PredCache.get(BB)) {
1295 PredList.
push_back(std::make_pair(Pred, Pointer));
1299 PHITransAddr &PredPointer = PredList.
back().second;
1308 Value *PrevVal = lookupNonLocalPointerDepVisited(Pred);
1310 setNonLocalPointerDepVisited(Pred, PredPtrVal);
1319 if (PrevVal == PredPtrVal)
1328 for (
const auto &Pred : PredList)
1329 setNonLocalPointerDepVisited(Pred.first,
nullptr);
1331 goto PredTranslationFailure;
1339 for (
auto &
I : PredList) {
1341 PHITransAddr &PredPointer =
I.second;
1344 bool CanTranslate =
true;
1350 CanTranslate =
false;
1360 if (!CanTranslate ||
1361 !getNonLocalPointerDepFromBB(QueryInst, PredPointer,
1373 NonLocalPointerInfo &NLPI = NonLocalPointerDeps[CacheKey];
1374 NLPI.Pair = BBSkipFirstBlockPair();
1380 CacheInfo = &NonLocalPointerDeps[CacheKey];
1381 Cache = &CacheInfo->NonLocalDeps;
1382 NumSortedEntries = Cache->size();
1388 CacheInfo->Pair = BBSkipFirstBlockPair();
1389 SkipFirstBlock =
false;
1392 PredTranslationFailure:
1399 CacheInfo = &NonLocalPointerDeps[CacheKey];
1400 Cache = &CacheInfo->NonLocalDeps;
1401 NumSortedEntries = Cache->size();
1408 CacheInfo->Pair = BBSkipFirstBlockPair();
1422 if (
I.getBB() != BB)
1425 assert((GotWorklistLimit ||
I.getResult().isNonLocal() ||
1426 !DT.isReachableFromEntry(BB)) &&
1427 "Should only be here with transparent block");
1435 (void)GotWorklistLimit;
1448void MemoryDependenceResults::removeCachedNonLocalPointerDependencies(
1449 ValueIsLoadPair
P) {
1452 if (!NonLocalDefsCache.empty()) {
1453 auto it = NonLocalDefsCache.find(
P.getPointer());
1454 if (it != NonLocalDefsCache.end()) {
1456 it->second.getResult().getInst(),
P.getPointer());
1457 NonLocalDefsCache.erase(it);
1461 auto toRemoveIt = ReverseNonLocalDefsCache.find(
I);
1462 if (toRemoveIt != ReverseNonLocalDefsCache.end()) {
1463 for (
const auto *entry : toRemoveIt->second)
1464 NonLocalDefsCache.erase(entry);
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 const Instruction *DepV = toRemoveIt->second.getResult().getInst();
1547 ReverseNonLocalDefsCache.find(DepV)->second.erase(RemInst);
1548 NonLocalDefsCache.erase(toRemoveIt);
1563 NewDirtyVal = MemDepResult::getDirty(&*++RemInst->
getIterator());
1565 ReverseDepMapType::iterator ReverseDepIt = ReverseLocalDeps.find(RemInst);
1566 if (ReverseDepIt != ReverseLocalDeps.end()) {
1569 "Nothing can locally depend on a terminator");
1571 for (
Instruction *InstDependingOnRemInst : ReverseDepIt->second) {
1572 assert(InstDependingOnRemInst != RemInst &&
1573 "Already removed our local dep info");
1575 LocalDeps[InstDependingOnRemInst] = NewDirtyVal;
1579 "There is no way something else can have "
1580 "a local dep on this if it is a terminator!");
1582 std::make_pair(NewDirtyVal.
getInst(), InstDependingOnRemInst));
1585 ReverseLocalDeps.erase(ReverseDepIt);
1589 while (!ReverseDepsToAdd.
empty()) {
1590 ReverseLocalDeps[ReverseDepsToAdd.
back().first].insert(
1591 ReverseDepsToAdd.
back().second);
1596 ReverseDepIt = ReverseNonLocalDeps.find(RemInst);
1597 if (ReverseDepIt != ReverseNonLocalDeps.end()) {
1599 assert(
I != RemInst &&
"Already removed NonLocalDep info for RemInst");
1601 PerInstNLInfo &INLD = NonLocalDepsMap[
I];
1605 for (
auto &Entry : INLD.first) {
1606 if (Entry.getResult().getInst() != RemInst)
1610 Entry.setResult(NewDirtyVal);
1613 ReverseDepsToAdd.
push_back(std::make_pair(NextI,
I));
1617 ReverseNonLocalDeps.erase(ReverseDepIt);
1620 while (!ReverseDepsToAdd.
empty()) {
1621 ReverseNonLocalDeps[ReverseDepsToAdd.
back().first].insert(
1622 ReverseDepsToAdd.
back().second);
1629 ReverseNonLocalPtrDepTy::iterator ReversePtrDepIt =
1630 ReverseNonLocalPtrDeps.find(RemInst);
1631 if (ReversePtrDepIt != ReverseNonLocalPtrDeps.end()) {
1633 ReversePtrDepsToAdd;
1635 for (ValueIsLoadPair
P : ReversePtrDepIt->second) {
1636 assert(
P.getPointer() != RemInst &&
1637 "Already removed NonLocalPointerDeps info for RemInst");
1639 auto &NLPD = NonLocalPointerDeps[
P];
1644 NLPD.Pair = BBSkipFirstBlockPair();
1647 for (
auto &Entry : NLPDI) {
1648 if (Entry.getResult().getInst() != RemInst)
1652 Entry.setResult(NewDirtyVal);
1655 ReversePtrDepsToAdd.
push_back(std::make_pair(NewDirtyInst,
P));
1663 ReverseNonLocalPtrDeps.
erase(ReversePtrDepIt);
1665 while (!ReversePtrDepsToAdd.
empty()) {
1666 ReverseNonLocalPtrDeps[ReversePtrDepsToAdd.
back().first].insert(
1667 ReversePtrDepsToAdd.
back().second);
1672 assert(!NonLocalDepsMap.count(RemInst) &&
"RemInst got reinserted?");
1680void MemoryDependenceResults::verifyRemoved(
Instruction *
D)
const {
1682 for (
const auto &DepKV : LocalDeps) {
1683 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1684 assert(DepKV.second.getInst() !=
D &&
"Inst occurs in data structures");
1687 for (
const auto &DepKV : NonLocalPointerDeps) {
1688 assert(DepKV.first.getPointer() !=
D &&
"Inst occurs in NLPD map key");
1689 for (
const auto &Entry : DepKV.second.NonLocalDeps)
1690 assert(Entry.getResult().getInst() !=
D &&
"Inst occurs as NLPD value");
1693 for (
const auto &DepKV : NonLocalDepsMap) {
1694 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1695 const PerInstNLInfo &INLD = DepKV.second;
1696 for (
const auto &Entry : INLD.first)
1698 "Inst occurs in data structures");
1701 for (
const auto &DepKV : ReverseLocalDeps) {
1702 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1703 for (Instruction *Inst : DepKV.second)
1704 assert(Inst !=
D &&
"Inst occurs in data structures");
1707 for (
const auto &DepKV : ReverseNonLocalDeps) {
1708 assert(DepKV.first !=
D &&
"Inst occurs in data structures");
1709 for (Instruction *Inst : DepKV.second)
1710 assert(Inst !=
D &&
"Inst occurs in data structures");
1713 for (
const auto &DepKV : ReverseNonLocalPtrDeps) {
1714 assert(DepKV.first !=
D &&
"Inst occurs in rev NLPD map");
1716 for (ValueIsLoadPair
P : DepKV.second)
1717 assert(
P != ValueIsLoadPair(
D,
false) &&
P != ValueIsLoadPair(
D,
true) &&
1718 "Inst occurs in ReverseNonLocalPtrDeps map");
1740 "Memory Dependence Analysis",
false,
true)
1765 FunctionAnalysisManager::Invalidator &Inv) {
1783 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)
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 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.
MemoryDependenceResults run(Function &F, FunctionAnalysisManager &AM)
MemoryDependenceAnalysis()
Provides a lazy, caching interface for making common memory aliasing information queries,...
MemDepResult getSimplePointerDependencyFrom(const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB, Instruction *QueryInst, unsigned *Limit, BatchAAResults &BatchAA)
std::vector< NonLocalDepEntry > NonLocalDepInfo
void invalidateCachedPredecessors()
Clears the PredIteratorCache info.
void invalidateCachedPointerInfo(Value *Ptr)
Invalidates cached information about the specified pointer, because it may be too conservative in mem...
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.
void removeInstruction(Instruction *InstToRemove)
Removes an instruction from the dependence analysis, updating the dependence of instructions that pre...
MemDepResult getInvariantGroupPointerDependency(LoadInst *LI, BasicBlock *BB)
This analysis looks for other loads and stores with invariant.group metadata and the same pointer ope...
unsigned getDefaultBlockScanLimit() const
Some methods limit the number of instructions they will examine.
MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.
const NonLocalDepInfo & getNonLocalCallDependency(CallBase *QueryCall)
Perform a full dependency query for the specified call, returning the set of blocks that the value is...
void getNonLocalPointerDependency(Instruction *QueryInst, SmallVectorImpl< NonLocalDepResult > &Result)
Perform a full dependency query for an access to the QueryInst's specified memory location,...
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 ...
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< 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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ 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.
FunctionAddr VTableAddr Value
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.
auto dyn_cast_or_null(const Y &Val)
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)
FunctionAddr VTableAddr Count
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.
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...