66 #define DEBUG_TYPE "memdep" 68 STATISTIC(NumCacheNonLocal,
"Number of fully cached non-local responses");
69 STATISTIC(NumCacheDirtyNonLocal,
"Number of dirty cached non-local responses");
70 STATISTIC(NumUncacheNonLocal,
"Number of uncached non-local responses");
73 "Number of fully cached non-local ptr responses");
75 "Number of cached, but dirty, non-local ptr responses");
76 STATISTIC(NumUncacheNonLocalPtr,
"Number of uncached non-local ptr responses");
78 "Number of block queries that were completely cached");
84 cl::desc(
"The number of instructions to scan in a block in memory " 85 "dependency analysis (default = 100)"));
89 cl::desc(
"The number of blocks to scan during memory " 90 "dependency analysis (default = 1000)"));
98 template <
typename KeyTy>
103 ReverseMap.
find(Inst);
104 assert(InstIt != ReverseMap.
end() &&
"Reverse map out of sync?");
105 bool Found = InstIt->second.
erase(Val);
106 assert(Found &&
"Invalid reverse map!");
108 if (InstIt->second.
empty())
109 ReverseMap.erase(InstIt);
119 if (
const LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
120 if (LI->isUnordered()) {
132 if (
const StoreInst *
SI = dyn_cast<StoreInst>(Inst)) {
133 if (
SI->isUnordered()) {
145 if (
const VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {
156 if (
const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
157 switch (II->getIntrinsicID()) {
184 MemDepResult MemoryDependenceResults::getCallDependencyFrom(
190 while (ScanIt != BB->
begin()) {
193 if (isa<DbgInfoIntrinsic>(Inst))
212 if (
auto *CallB = dyn_cast<CallBase>(Inst)) {
217 if (isReadOnlyCall && !
isModSet(MR) &&
242 const Value *MemLocBase, int64_t MemLocOffs,
unsigned MemLocSize,
257 const Value *LIBase =
262 if (LIBase != MemLocBase)
272 if (MemLocOffs < LIOffs)
282 int64_t MemLocEnd = MemLocOffs + MemLocSize;
285 if (LIOffs + LoadAlign < MemLocEnd)
296 if (NewLoadByteSize > LoadAlign ||
300 if (LIOffs + NewLoadByteSize > MemLocEnd &&
311 if (LIOffs + NewLoadByteSize >= MemLocEnd)
312 return NewLoadByteSize;
314 NewLoadByteSize <<= 1;
319 if (
auto *LI = dyn_cast<LoadInst>(Inst))
320 return LI->isVolatile();
321 if (
auto *
SI = dyn_cast<StoreInst>(Inst))
322 return SI->isVolatile();
323 if (
auto *AI = dyn_cast<AtomicCmpXchgInst>(Inst))
324 return AI->isVolatile();
332 if (QueryInst !=
nullptr) {
333 if (
auto *LI = dyn_cast<LoadInst>(QueryInst)) {
336 if (InvariantGroupDependency.
isDef())
337 return InvariantGroupDependency;
341 MemLoc, isLoad, ScanIt, BB, QueryInst, Limit);
342 if (SimpleDep.
isDef())
348 return InvariantGroupDependency;
351 "InvariantGroupDependency should be only unknown at this point");
370 if (isa<GlobalValue>(LoadOperand))
375 LoadOperandsQueue.
push_back(LoadOperand);
381 assert(
Other &&
"Must call it with not null instruction");
389 while (!LoadOperandsQueue.
empty()) {
391 assert(Ptr && !isa<GlobalValue>(Ptr) &&
392 "Null or GlobalValue should not be inserted");
394 for (
const Use &Us : Ptr->
uses()) {
396 if (!U || U == LI || !DT.
dominates(U, LI))
401 if (isa<BitCastInst>(U)) {
410 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(U))
411 if (
GEP->hasAllZeroIndices()) {
419 if ((isa<LoadInst>(U) || isa<StoreInst>(U)) &&
421 ClosestDependency = GetClosestDependency(ClosestDependency, U);
425 if (!ClosestDependency)
427 if (ClosestDependency->
getParent() == BB)
433 NonLocalDefsCache.try_emplace(
436 ReverseNonLocalDefsCache[ClosestDependency].
insert(LI);
443 bool isInvariantLoad =
false;
483 if (isLoad && QueryInst) {
486 isInvariantLoad =
true;
499 auto isNonSimpleLoadOrStore = [](
Instruction *
I) ->
bool {
500 if (
auto *LI = dyn_cast<LoadInst>(
I))
501 return !LI->isSimple();
502 if (
auto *
SI = dyn_cast<StoreInst>(
I))
503 return !
SI->isSimple();
510 return !isa<LoadInst>(
I) && !isa<StoreInst>(
I) &&
I->mayReadOrWriteMemory();
514 while (ScanIt != BB->
begin()) {
519 if (isa<DbgInfoIntrinsic>(II))
547 if (
LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
551 if (LI->isVolatile()) {
566 if (!QueryInst || isNonSimpleLoadOrStore(QueryInst) ||
567 isOtherMemAccess(QueryInst))
586 #if 0 // FIXME: Temporarily disabled. GVN is cleverly rewriting loads 618 if (!
SI->isUnordered() &&
SI->isAtomic()) {
619 if (!QueryInst || isNonSimpleLoadOrStore(QueryInst) ||
620 isOtherMemAccess(QueryInst))
630 if (
SI->isVolatile())
631 if (!QueryInst || isNonSimpleLoadOrStore(QueryInst) ||
632 isOtherMemAccess(QueryInst))
664 if (isa<AllocaInst>(Inst) ||
isNoAliasFn(Inst, &TLI)) {
666 if (AccessPtr == Inst || AA.
isMustAlias(Inst, AccessPtr))
678 if (
FenceInst *FI = dyn_cast<FenceInst>(Inst))
720 if (!LocalCache.isDirty())
747 if (
auto *II = dyn_cast<IntrinsicInst>(QueryInst))
751 MemLoc, isLoad, ScanPos->
getIterator(), QueryParent, QueryInst);
752 }
else if (
auto *QueryCall = dyn_cast<CallBase>(QueryInst)) {
754 LocalCache = getCallDependencyFrom(QueryCall, isReadOnly,
763 ReverseLocalDeps[
I].insert(QueryInst);
774 Count = Cache.size();
775 assert(std::is_sorted(Cache.begin(), Cache.begin() + Count) &&
776 "Cache isn't sorted!");
783 "getNonLocalCallDependency should only be used on calls with " 785 PerInstNLInfo &CacheP = NonLocalDeps[QueryCall];
793 if (!Cache.empty()) {
796 if (!CacheP.second) {
803 for (
auto &Entry : Cache)
804 if (Entry.getResult().isDirty())
810 ++NumCacheDirtyNonLocal;
818 ++NumUncacheNonLocal;
826 unsigned NumSortedEntries = Cache.
size();
830 while (!DirtyBlocks.
empty()) {
835 if (!Visited.
insert(DirtyBB).second)
841 NonLocalDepInfo::iterator Entry =
844 if (Entry != Cache.begin() && std::prev(Entry)->getBB() == DirtyBB)
848 if (Entry != Cache.begin() + NumSortedEntries &&
849 Entry->getBB() == DirtyBB) {
852 if (!Entry->getResult().isDirty())
856 ExistingResult = &*Entry;
862 if (ExistingResult) {
864 ScanPos = Inst->getIterator();
866 RemoveFromReverseMap<Instruction *>(ReverseNonLocalDeps, Inst,
874 if (ScanPos != DirtyBB->
begin()) {
875 Dep = getCallDependencyFrom(QueryCall, isReadonlyCall, ScanPos, DirtyBB);
893 if (!Dep.isNonLocal()) {
897 ReverseNonLocalDeps[Inst].insert(QueryCall);
913 bool isLoad = isa<LoadInst>(QueryInst);
918 "Can't get pointer deps of a non-pointer!");
922 auto NonLocalDefIt = NonLocalDefsCache.find(QueryInst);
923 if (NonLocalDefIt != NonLocalDefsCache.end()) {
925 ReverseNonLocalDefsCache[NonLocalDefIt->second.getResult().getInst()]
927 NonLocalDefsCache.erase(NonLocalDefIt);
940 if (
LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
941 return !LI->isUnordered();
942 }
else if (
StoreInst *
SI = dyn_cast<StoreInst>(Inst)) {
943 return !
SI->isUnordered();
949 const_cast<Value *>(Loc.
Ptr)));
952 const DataLayout &DL = FromBB->getModule()->getDataLayout();
960 if (getNonLocalPointerDepFromBB(QueryInst, Address, Loc, isLoad, FromBB,
961 Result, Visited,
true))
965 const_cast<Value *>(Loc.
Ptr)));
973 MemDepResult MemoryDependenceResults::GetNonLocalInfoForBlock(
981 if (Entry != Cache->begin() && (Entry - 1)->getBB() == BB)
985 if (Entry != Cache->begin() + NumSortedEntries && Entry->getBB() == BB)
986 ExistingResult = &*Entry;
990 if (ExistingResult && !ExistingResult->
getResult().isDirty()) {
991 ++NumCacheNonLocalPtr;
1001 "Instruction invalidated?");
1002 ++NumCacheDirtyNonLocalPtr;
1009 ++NumUncacheNonLocalPtr;
1032 assert(Inst &&
"Didn't depend on anything?");
1034 ReverseNonLocalPtrDeps[Inst].
insert(CacheKey);
1044 unsigned NumSortedEntries) {
1045 switch (Cache.size() - NumSortedEntries) {
1053 MemoryDependenceResults::NonLocalDepInfo::iterator Entry =
1055 Cache.insert(Entry, Val);
1060 if (Cache.size() != 1) {
1063 MemoryDependenceResults::NonLocalDepInfo::iterator Entry =
1065 Cache.insert(Entry, Val);
1088 bool MemoryDependenceResults::getNonLocalPointerDepFromBB(
1100 NonLocalPointerInfo InitialNLPI;
1101 InitialNLPI.Size = Loc.
Size;
1102 InitialNLPI.AATags = Loc.
AATags;
1106 std::pair<CachedNonLocalPointerInfo::iterator, bool> Pair =
1107 NonLocalPointerDeps.
insert(std::make_pair(CacheKey, InitialNLPI));
1108 NonLocalPointerInfo *CacheInfo = &Pair.first->second;
1113 if (CacheInfo->Size != Loc.
Size) {
1114 bool ThrowOutEverything;
1115 if (CacheInfo->Size.hasValue() && Loc.
Size.
hasValue()) {
1119 ThrowOutEverything =
1127 if (ThrowOutEverything) {
1130 CacheInfo->Pair = BBSkipFirstBlockPair();
1131 CacheInfo->Size = Loc.
Size;
1132 for (
auto &Entry : CacheInfo->NonLocalDeps)
1133 if (
Instruction *Inst = Entry.getResult().getInst())
1135 CacheInfo->NonLocalDeps.clear();
1139 return getNonLocalPointerDepFromBB(
1141 StartBB, Result, Visited, SkipFirstBlock);
1148 if (CacheInfo->AATags != Loc.
AATags) {
1149 if (CacheInfo->AATags) {
1150 CacheInfo->Pair = BBSkipFirstBlockPair();
1152 for (
auto &Entry : CacheInfo->NonLocalDeps)
1153 if (
Instruction *Inst = Entry.getResult().getInst())
1155 CacheInfo->NonLocalDeps.clear();
1158 return getNonLocalPointerDepFromBB(
1160 Visited, SkipFirstBlock);
1168 if (CacheInfo->Pair == BBSkipFirstBlockPair(StartBB, SkipFirstBlock)) {
1174 if (!Visited.
empty()) {
1175 for (
auto &Entry : *Cache) {
1177 Visited.
find(Entry.getBB());
1178 if (VI == Visited.
end() || VI->second == Pointer.
getAddr())
1189 for (
auto &Entry : *Cache) {
1190 Visited.
insert(std::make_pair(Entry.getBB(), Addr));
1191 if (Entry.getResult().isNonLocal()) {
1200 ++NumCacheCompleteNonLocalPtr;
1209 CacheInfo->Pair = BBSkipFirstBlockPair(StartBB, SkipFirstBlock);
1211 CacheInfo->Pair = BBSkipFirstBlockPair();
1224 unsigned NumSortedEntries = Cache->size();
1226 bool GotWorklistLimit =
false;
1229 while (!Worklist.
empty()) {
1239 if (Cache && NumSortedEntries != Cache->size()) {
1246 CacheInfo->Pair = BBSkipFirstBlockPair();
1251 if (!SkipFirstBlock) {
1254 assert(Visited.
count(BB) &&
"Should check 'visited' before adding to WL");
1259 MemDepResult Dep = GetNonLocalInfoForBlock(QueryInst, Loc, isLoad, BB,
1260 Cache, NumSortedEntries);
1276 SkipFirstBlock =
false;
1280 std::pair<DenseMap<BasicBlock *, Value *>::iterator,
bool> InsertRes =
1282 if (InsertRes.second) {
1291 if (InsertRes.first->second != Pointer.
getAddr()) {
1294 for (
unsigned i = 0; i < NewBlocks.
size(); i++)
1295 Visited.
erase(NewBlocks[i]);
1296 goto PredTranslationFailure;
1299 if (NewBlocks.
size() > WorklistEntries) {
1302 for (
unsigned i = 0; i < NewBlocks.
size(); i++)
1303 Visited.
erase(NewBlocks[i]);
1304 GotWorklistLimit =
true;
1305 goto PredTranslationFailure;
1307 WorklistEntries -= NewBlocks.
size();
1315 goto PredTranslationFailure;
1322 if (Cache && NumSortedEntries != Cache->size()) {
1324 NumSortedEntries = Cache->size();
1330 PredList.
push_back(std::make_pair(Pred, Pointer));
1343 std::pair<DenseMap<BasicBlock *, Value *>::iterator,
bool> InsertRes =
1344 Visited.
insert(std::make_pair(Pred, PredPtrVal));
1346 if (!InsertRes.second) {
1352 if (InsertRes.first->second == PredPtrVal)
1361 for (
unsigned i = 0, n = PredList.
size(); i < n; ++i)
1362 Visited.
erase(PredList[i].first);
1364 goto PredTranslationFailure;
1373 for (
unsigned i = 0, n = PredList.
size(); i < n; ++i) {
1378 bool CanTranslate =
true;
1384 CanTranslate =
false;
1394 if (!CanTranslate ||
1395 !getNonLocalPointerDepFromBB(QueryInst, PredPointer,
1397 Pred, Result, Visited)) {
1400 Result.push_back(Entry);
1407 NonLocalPointerInfo &NLPI = NonLocalPointerDeps[CacheKey];
1408 NLPI.Pair = BBSkipFirstBlockPair();
1414 CacheInfo = &NonLocalPointerDeps[CacheKey];
1415 Cache = &CacheInfo->NonLocalDeps;
1416 NumSortedEntries = Cache->size();
1422 CacheInfo->Pair = BBSkipFirstBlockPair();
1423 SkipFirstBlock =
false;
1426 PredTranslationFailure:
1433 CacheInfo = &NonLocalPointerDeps[CacheKey];
1434 Cache = &CacheInfo->NonLocalDeps;
1435 NumSortedEntries = Cache->size();
1442 CacheInfo->Pair = BBSkipFirstBlockPair();
1452 bool foundBlock =
false;
1454 if (
I.getBB() != BB)
1457 assert((GotWorklistLimit ||
I.getResult().isNonLocal() ||
1459 "Should only be here with transparent block");
1466 (void)foundBlock; (void)GotWorklistLimit;
1467 assert((foundBlock || GotWorklistLimit) &&
"Current block not in cache?");
1477 void MemoryDependenceResults::RemoveCachedNonLocalPointerDependencies(
1478 ValueIsLoadPair
P) {
1481 if (!NonLocalDefsCache.empty()) {
1482 auto it = NonLocalDefsCache.find(P.getPointer());
1483 if (it != NonLocalDefsCache.end()) {
1485 it->second.getResult().getInst(), P.getPointer());
1486 NonLocalDefsCache.erase(it);
1489 if (
auto *
I = dyn_cast<Instruction>(P.getPointer())) {
1490 auto toRemoveIt = ReverseNonLocalDefsCache.
find(
I);
1491 if (toRemoveIt != ReverseNonLocalDefsCache.
end()) {
1492 for (
const auto &
entry : toRemoveIt->second)
1493 NonLocalDefsCache.erase(
entry);
1494 ReverseNonLocalDefsCache.
erase(toRemoveIt);
1500 if (It == NonLocalPointerDeps.
end())
1507 for (
unsigned i = 0, e = PInfo.size(); i != e; ++i) {
1518 NonLocalPointerDeps.
erase(It);
1541 if (NLDI != NonLocalDeps.
end()) {
1543 for (
auto &Entry : BlockMap)
1544 if (
Instruction *Inst = Entry.getResult().getInst())
1546 NonLocalDeps.
erase(NLDI);
1551 if (LocalDepEntry != LocalDeps.
end()) {
1553 if (
Instruction *Inst = LocalDepEntry->second.getInst())
1557 LocalDeps.
erase(LocalDepEntry);
1567 RemoveCachedNonLocalPointerDependencies(
ValueIsLoadPair(RemInst,
false));
1568 RemoveCachedNonLocalPointerDependencies(
ValueIsLoadPair(RemInst,
true));
1582 NewDirtyVal = MemDepResult::getDirty(&*++RemInst->
getIterator());
1585 if (ReverseDepIt != ReverseLocalDeps.
end()) {
1588 "Nothing can locally depend on a terminator");
1590 for (
Instruction *InstDependingOnRemInst : ReverseDepIt->second) {
1591 assert(InstDependingOnRemInst != RemInst &&
1592 "Already removed our local dep info");
1594 LocalDeps[InstDependingOnRemInst] = NewDirtyVal;
1598 "There is no way something else can have " 1599 "a local dep on this if it is a terminator!");
1601 std::make_pair(NewDirtyVal.
getInst(), InstDependingOnRemInst));
1604 ReverseLocalDeps.
erase(ReverseDepIt);
1608 while (!ReverseDepsToAdd.
empty()) {
1609 ReverseLocalDeps[ReverseDepsToAdd.
back().first].
insert(
1610 ReverseDepsToAdd.
back().second);
1615 ReverseDepIt = ReverseNonLocalDeps.
find(RemInst);
1616 if (ReverseDepIt != ReverseNonLocalDeps.
end()) {
1618 assert(I != RemInst &&
"Already removed NonLocalDep info for RemInst");
1620 PerInstNLInfo &INLD = NonLocalDeps[
I];
1624 for (
auto &Entry : INLD.first) {
1625 if (Entry.getResult().getInst() != RemInst)
1629 Entry.setResult(NewDirtyVal);
1632 ReverseDepsToAdd.
push_back(std::make_pair(NextI, I));
1636 ReverseNonLocalDeps.
erase(ReverseDepIt);
1639 while (!ReverseDepsToAdd.
empty()) {
1640 ReverseNonLocalDeps[ReverseDepsToAdd.
back().first].
insert(
1641 ReverseDepsToAdd.
back().second);
1649 ReverseNonLocalPtrDeps.
find(RemInst);
1650 if (ReversePtrDepIt != ReverseNonLocalPtrDeps.
end()) {
1652 ReversePtrDepsToAdd;
1656 "Already removed NonLocalPointerDeps info for RemInst");
1664 for (
auto &Entry : NLPDI) {
1665 if (Entry.getResult().getInst() != RemInst)
1669 Entry.setResult(NewDirtyVal);
1672 ReversePtrDepsToAdd.
push_back(std::make_pair(NewDirtyInst, P));
1680 ReverseNonLocalPtrDeps.
erase(ReversePtrDepIt);
1682 while (!ReversePtrDepsToAdd.
empty()) {
1683 ReverseNonLocalPtrDeps[ReversePtrDepsToAdd.
back().first].
insert(
1684 ReversePtrDepsToAdd.
back().second);
1692 assert(!NonLocalDeps.
count(RemInst) &&
"RemInst got reinserted?");
1700 void MemoryDependenceResults::verifyRemoved(
Instruction *
D)
const {
1702 for (
const auto &DepKV : LocalDeps) {
1703 assert(DepKV.first != D &&
"Inst occurs in data structures");
1704 assert(DepKV.second.getInst() != D &&
"Inst occurs in data structures");
1707 for (
const auto &DepKV : NonLocalPointerDeps) {
1708 assert(DepKV.first.getPointer() != D &&
"Inst occurs in NLPD map key");
1709 for (
const auto &Entry : DepKV.second.NonLocalDeps)
1710 assert(Entry.getResult().getInst() != D &&
"Inst occurs as NLPD value");
1713 for (
const auto &DepKV : NonLocalDeps) {
1714 assert(DepKV.first != D &&
"Inst occurs in data structures");
1715 const PerInstNLInfo &INLD = DepKV.second;
1716 for (
const auto &Entry : INLD.first)
1717 assert(Entry.getResult().getInst() != D &&
1718 "Inst occurs in data structures");
1721 for (
const auto &DepKV : ReverseLocalDeps) {
1722 assert(DepKV.first != D &&
"Inst occurs in data structures");
1724 assert(Inst != D &&
"Inst occurs in data structures");
1727 for (
const auto &DepKV : ReverseNonLocalDeps) {
1728 assert(DepKV.first != D &&
"Inst occurs in data structures");
1730 assert(Inst != D &&
"Inst occurs in data structures");
1733 for (
const auto &DepKV : ReverseNonLocalPtrDeps) {
1734 assert(DepKV.first != D &&
"Inst occurs in rev NLPD map");
1738 "Inst occurs in ReverseNonLocalPtrDeps map");
1758 "Memory Dependence Analysis",
false,
true)
1810 auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
1811 auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
1812 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
1813 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1814 auto &PV = getAnalysis<PhiValuesWrapperPass>().getResult();
1815 MemDep.emplace(AA, AC, TLI, DT, PV);
The access may reference and may modify the value stored in memory.
void invalidateCachedPointerInfo(Value *Ptr)
Invalidates cached information about the specified pointer, because it may be too conservative in mem...
A parsed version of the target data layout string in and methods for querying it. ...
void invalidateCachedPredecessors()
Clears the PredIteratorCache info.
bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Trigger the invalidation of some other analysis pass if not already handled and return whether it was...
iterator_range< use_iterator > uses()
The access neither references nor modifies the value stored in memory.
bool isStrongerThanUnordered(AtomicOrdering ao)
Provides a lazy, caching interface for making common memory aliasing information queries, backed by LLVM's alias analysis passes.
LLVM_NODISCARD ModRefInfo clearMust(const ModRefInfo MRI)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Atomic ordering constants.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
PointerTy getPointer() const
MemDepResult getInvariantGroupPointerDependency(LoadInst *LI, BasicBlock *BB)
This analysis looks for other loads and stores with invariant.group metadata and the same pointer ope...
An instruction for ordering other memory operations.
MemoryLocation getWithNewPtr(const Value *NewPtr) const
This class provides various memory handling functions that manipulate MemoryBlock instances...
void push_back(const T &Elt)
This class represents a function call, abstracting a target machine's calling convention.
bool isNonLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the block...
An immutable pass that tracks lazily created AssumptionCache objects.
static cl::opt< unsigned > BlockNumberLimit("memdep-block-number-limit", cl::Hidden, cl::init(1000), cl::desc("The number of blocks to scan during memory " "dependency analysis (default = 1000)"))
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
The two locations do not alias at all.
bool isTerminator() const
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
STATISTIC(NumFunctions, "Total number of functions")
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Analysis pass which computes a DominatorTree.
block Block Frequency true
An instruction for reading from memory.
This defines the Use class.
LLVM_NODISCARD bool isModAndRefSet(const ModRefInfo MRI)
The analysis pass which yields a PhiValues.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
const CallInst * isFreeCall(const Value *I, const TargetLibraryInfo *TLI)
isFreeCall - Returns non-null if the value is a call to the builtin free()
iterator begin()
Instruction iterator methods.
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
AnalysisUsage & addRequired()
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
ArrayRef< BasicBlock * > get(BasicBlock *BB)
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool isDef() const
Tests if this MemDepResult represents a query that is an instruction definition dependency.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
bool isClobber() const
Tests if this MemDepResult represents a query that is an instruction clobber dependency.
A Use represents the edge between a Value definition and its users.
static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase, int64_t MemLocOffs, unsigned MemLocSize, const LoadInst *LI)
Looks at a memory location for a load (specified by MemLocBase, Offs, and Size) and compares it again...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static bool isLoad(int Opcode)
unsigned getDefaultBlockScanLimit() const
Some methods limit the number of instructions they will examine.
void getNonLocalPointerDependency(Instruction *QueryInst, SmallVectorImpl< NonLocalDepResult > &Result)
Perform a full dependency query for an access to the QueryInst's specified memory location...
static MemDepResult getDef(Instruction *Inst)
get methods: These are static ctor methods for creating various MemDepResult kinds.
The access may reference the value stored in memory.
This file contains the simple types necessary to represent the attributes associated with functions a...
An analysis that produces MemoryDependenceResults for a function.
MemoryDependenceResults(AliasAnalysis &AA, AssumptionCache &AC, const TargetLibraryInfo &TLI, DominatorTree &DT, PhiValues &PV)
static MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
static bool isOrdered(const Instruction *I)
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
bool isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a function that returns a NoAlias pointer (including malloc/c...
Type * getType() const
All values are typed, get the type of this value.
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.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset...
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
An instruction for storing to memory.
Wrapper pass for the legacy pass manager.
~MemoryDependenceWrapperPass() override
AliasResult
The possible results of an alias query.
iterator find(const_arg_type_t< KeyT > Val)
uint64_t getValue() const
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal=false)
Checks whether the given location points to constant memory, or if OrLocal is true whether it points ...
static MemDepResult getUnknown()
const BasicBlock & getEntryBlock() const
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
initializer< Ty > init(const Ty &Val)
bool erase(const KeyT &Val)
A set of analyses that are preserved following a run of a transformation pass.
bool isIdenticalToWhenDefined(const Instruction *I) const
This is like isIdenticalTo, except that it ignores the SubclassOptionalData flags, which may specify conditions under which the instruction's result is undefined.
LLVM Basic Block Representation.
PointerIntPair - This class implements a pair of a pointer and small integer.
PHITransAddr - An address value which tracks and handles phi translation.
MemoryLocation getWithoutAATags() const
MemoryLocation getWithNewSize(LocationSize NewSize) const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool isPointerTy() const
True if this is an instance of PointerType.
void invalidateValue(const Value *V)
Notify PhiValues that the cached information using V is no longer valid.
A manager for alias analyses.
This is a result from a NonLocal dependence query.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
MemDepResult getSimplePointerDependencyFrom(const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB, Instruction *QueryInst, unsigned *Limit=nullptr)
Represent the analysis usage information of a pass.
static MemDepResult getNonFuncLocal()
FunctionPass class - This class is used to implement most global optimizations.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known...
Value * getPointerOperand()
self_iterator getIterator()
void setResult(const MemDepResult &R)
bool onlyReadsMemory(const CallBase *Call)
Checks if the specified call is known to only read from non-volatile memory (or not access memory at ...
uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs, and aliases.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
INITIALIZE_PASS_BEGIN(MemoryDependenceWrapperPass, "memdep", "Memory Dependence Analysis", false, true) INITIALIZE_PASS_END(MemoryDependenceWrapperPass
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...
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance...
Value * GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
A memory dependence query can return one of three different answers.
void sort(IteratorTy Start, IteratorTy End)
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)"))
void clear()
clear - Remove all information.
const Value * Ptr
The address of the start of the location.
Representation for a specific memory location.
A function analysis which provides an AssumptionCache.
The two locations precisely alias each other.
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.
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree *DT, bool MustDominate)
PHITranslateValue - PHI translate the current address up the CFG from CurBB to Pred, updating our state to reflect any needed changes.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
Module.h This file contains the declarations for the Module class.
Provides information about what library functions are available for the current target.
static MemDepResult getClobber(Instruction *Inst)
MemoryDependenceResults run(Function &F, FunctionAnalysisManager &AM)
const MemDepResult & getResult() const
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
LLVM_NODISCARD T pop_back_val()
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
void getAnalysisUsage(AnalysisUsage &AU) const override
Does not modify anything. It uses Value Numbering and Alias Analysis.
The access may modify the value stored in memory.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Target - Wrapper for Target specific information.
void releaseMemory() override
Clean up memory in between runs.
bool NeedsPHITranslationFromBlock(BasicBlock *BB) const
NeedsPHITranslationFromBlock - Return true if moving from the specified BasicBlock to its predecessor...
ModRefInfo callCapturesBefore(const Instruction *I, const MemoryLocation &MemLoc, DominatorTree *DT, OrderedBasicBlock *OBB=nullptr)
Return information about whether a particular call site modifies or reads the specified memory locati...
void setPreservesAll()
Set by analyses that do not transform their input at all.
LLVM_NODISCARD bool isNoModRef(const ModRefInfo MRI)
InstListType::iterator iterator
Instruction iterators...
bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are must-alias.
std::vector< NonLocalDepEntry > NonLocalDepInfo
bool runOnFunction(Function &) override
Pass Implementation stuff. This doesn't do any analysis eagerly.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
LLVM_NODISCARD bool isModSet(const ModRefInfo MRI)
bool isUnknown() const
Tests if this MemDepResult represents a query which cannot and/or will not be computed.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
AAMDNodes AATags
The metadata nodes which describes the aliasing of the location (each member is null if that kind of ...
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...
unsigned getAlignment() const
Return the alignment of the access that is being performed.
Instruction * getInst() const
If this is a normal dependency, returns the instruction that is depended on.
void initializeMemoryDependenceWrapperPassPass(PassRegistry &)
LLVM_NODISCARD bool empty() const
DenseMapIterator< ValueIsLoadPair, NonLocalPointerInfo, DenseMapInfo< ValueIsLoadPair >, llvm::detail::DenseMapPair< ValueIsLoadPair, NonLocalPointerInfo > > iterator
This file provides utility analysis objects describing memory locations.
bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
Handle invalidation in the new PM.
const Function * getParent() const
Return the enclosing method, or null if none.
bool mayReadFromMemory() const
Return true if this instruction may read memory.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
AnalysisUsage & addRequiredTransitive()
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
LLVM_NODISCARD bool empty() const
bool IsPotentiallyPHITranslatable() const
IsPotentiallyPHITranslatable - If this needs PHI translation, return true if we have some hope of doi...
Memory Dependence Analysis
API to communicate dependencies between analyses during invalidation.
auto upper_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range))
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Analysis pass providing the TargetLibraryInfo.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This templated class represents "all analyses that operate over <a particular IR unit>" (e...
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM Value Representation.
const NonLocalDepInfo & getNonLocalCallDependency(CallBase *QueryCall)
Perform a full dependency query for the specified call, returning the set of blocks that the value is...
void removeInstruction(Instruction *InstToRemove)
Removes an instruction from the dependence analysis, updating the dependence of instructions that pre...
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
print Instructions which execute on loop entry
This is an entry in the NonLocalDepInfo cache.
A container for analyses that lazily runs them and caches their results.
bool fitsInLegalInteger(unsigned Width) const
Returns true if the specified type fits in a native integer type supported by the CPU...
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...
Legacy analysis pass which computes a DominatorTree.
LLVM_NODISCARD bool isModOrRefSet(const ModRefInfo MRI)
static bool isVolatile(Instruction *Inst)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc)
getModRefInfo (for call sites) - Return information about whether a particular call site modifies or ...
The two locations alias, but only due to a partial overlap.
Dependence - This class represents a dependence between two memory memory references in a function...
static MemDepResult getNonLocal()
static const unsigned int NumResultsLimit
A special type used by analysis passes to provide an address that identifies that particular analysis...
A wrapper class for inspecting calls to intrinsic functions.
const BasicBlock * getParent() const
MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.