17#include "llvm/Config/llvm-config.h"
39 cl::desc(
"The maximum number of pointers may-alias "
40 "sets may contain before degradation"));
45 assert(!AS.Forward &&
"Alias set is already forwarding!");
46 assert(!Forward &&
"This set is a forwarding set!!");
48 bool WasMustAlias = (Alias == SetMustAlias);
53 if (Alias == SetMustAlias) {
57 PointerRec *L = getSomePointer();
58 PointerRec *R = AS.getSomePointer();
67 if (Alias == SetMayAlias) {
69 AST.TotalMayAliasSetSize +=
size();
70 if (AS.Alias == SetMustAlias)
71 AST.TotalMayAliasSetSize += AS.
size();
74 bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
75 if (UnknownInsts.empty()) {
76 if (ASHadUnknownInsts) {
80 }
else if (ASHadUnknownInsts) {
82 AS.UnknownInsts.clear();
92 *PtrListEnd = AS.PtrList;
93 AS.PtrList->setPrevInList(PtrListEnd);
94 PtrListEnd = AS.PtrListEnd;
97 AS.PtrListEnd = &AS.PtrList;
98 assert(*AS.PtrListEnd ==
nullptr &&
"End of list is not null?");
100 if (ASHadUnknownInsts)
104void AliasSetTracker::removeAliasSet(
AliasSet *AS) {
107 AS->Forward =
nullptr;
109 if (AS->Alias == AliasSet::SetMayAlias)
110 TotalMayAliasSetSize -= AS->
size();
115 if (AS == AliasAnyAS) {
116 AliasAnyAS =
nullptr;
117 assert(AliasSets.empty() &&
"Tracker not empty");
122 assert(RefCount == 0 &&
"Cannot remove non-dead alias set from tracker!");
123 AST.removeAliasSet(
this);
128 bool KnownMustAlias,
bool SkipSizeUpdate) {
129 assert(!Entry.hasAliasSet() &&
"Entry already in set!");
133 if (PointerRec *
P = getSomePointer()) {
134 if (!KnownMustAlias) {
141 AST.TotalMayAliasSetSize +=
size();
144 }
else if (!SkipSizeUpdate)
145 P->updateSizeAndAAInfo(
Size, AAInfo);
148 Entry.setAliasSet(
this);
149 Entry.updateSizeAndAAInfo(
Size, AAInfo);
153 assert(*PtrListEnd ==
nullptr &&
"End of list is not null?");
154 *PtrListEnd = &Entry;
155 PtrListEnd = Entry.setPrevInList(PtrListEnd);
156 assert(*PtrListEnd ==
nullptr &&
"End of list is not null?");
160 if (Alias == SetMayAlias)
161 AST.TotalMayAliasSetSize++;
165 if (UnknownInsts.empty())
167 UnknownInsts.emplace_back(
I);
171 using namespace PatternMatch;
172 bool MayWriteMemory =
I->mayWriteToMemory() && !
isGuard(
I) &&
173 !(
I->use_empty() &&
match(
I, m_Intrinsic<Intrinsic::invariant_start>()));
174 if (!MayWriteMemory) {
182 Access = ModRefAccess;
195 if (Alias == SetMustAlias) {
196 assert(UnknownInsts.empty() &&
"Illegal must alias set!");
200 PointerRec *SomePtr = getSomePointer();
201 assert(SomePtr &&
"Empty must-alias set??");
203 SomePtr->getAAInfo()),
218 if (!UnknownInsts.empty()) {
238 const auto *C1 = dyn_cast<CallBase>(UnknownInst);
239 const auto *C2 = dyn_cast<CallBase>(Inst);
260 for (
auto &
I : PointerMap)
261 I.second->eraseFromList();
276 bool &MustAliasAll) {
288 MustAliasAll =
false;
324 AliasSet::PointerRec &Entry = getEntryFor(Pointer);
332 if (Entry.hasAliasSet()) {
333 Entry.updateSizeAndAAInfo(
Size, AAInfo);
334 assert(Entry.getAliasSet(*
this) == AliasAnyAS &&
335 "Entry in saturated AST must belong to only alias set");
337 AliasAnyAS->addPointer(*
this, Entry,
Size, AAInfo);
342 bool MustAliasAll =
false;
344 if (Entry.hasAliasSet()) {
350 if (Entry.updateSizeAndAAInfo(
Size, AAInfo))
351 mergeAliasSetsForPointer(Pointer,
Size, AAInfo, MustAliasAll);
353 return *Entry.getAliasSet(*this)->getForwardedTarget(*
this);
357 mergeAliasSetsForPointer(Pointer,
Size, AAInfo, MustAliasAll)) {
359 AS->addPointer(*
this, Entry,
Size, AAInfo, MustAliasAll);
364 AliasSets.push_back(
new AliasSet());
365 AliasSets.back().addPointer(*
this, Entry,
Size, AAInfo,
true);
366 return AliasSets.back();
400 if (isa<DbgInfoIntrinsic>(Inst))
403 if (
auto *II = dyn_cast<IntrinsicInst>(Inst)) {
406 switch (II->getIntrinsicID()) {
410 case Intrinsic::assume:
411 case Intrinsic::experimental_noalias_scope_decl:
412 case Intrinsic::sideeffect:
413 case Intrinsic::pseudoprobe:
420 if (
AliasSet *AS = findAliasSetForUnknownInst(Inst)) {
421 AS->addUnknownInst(Inst, AA);
424 AliasSets.push_back(
new AliasSet());
425 AliasSets.back().addUnknownInst(Inst, AA);
430 if (
LoadInst *LI = dyn_cast<LoadInst>(
I))
442 if (
auto *Call = dyn_cast<CallBase>(
I))
443 if (Call->onlyAccessesArgMemory()) {
446 return AliasSet::ModRefAccess;
448 return AliasSet::ModAccess;
450 return AliasSet::RefAccess;
452 return AliasSet::NoAccess;
460 using namespace PatternMatch;
461 if (Call->use_empty() &&
462 match(Call, m_Intrinsic<Intrinsic::invariant_start>()))
465 for (
auto IdxArgPair :
enumerate(Call->args())) {
466 int ArgIdx = IdxArgPair.index();
467 const Value *
Arg = IdxArgPair.value();
468 if (!
Arg->getType()->isPointerTy())
475 addPointer(ArgLoc, getAccessFromModRef(ArgMask));
490 "Merging AliasSetTracker objects with different Alias Analyses!");
507 (AliasSet::AccessLattice)AS.Access);
511AliasSet &AliasSetTracker::mergeAllAliasSets() {
513 "Full merge should happen once, when the saturation threshold is "
518 std::vector<AliasSet *> ASVector;
521 ASVector.push_back(&AS);
525 AliasSets.push_back(
new AliasSet());
526 AliasAnyAS = &AliasSets.back();
527 AliasAnyAS->Alias = AliasSet::SetMayAlias;
528 AliasAnyAS->Access = AliasSet::ModRefAccess;
529 AliasAnyAS->AliasAny =
true;
531 for (
auto *Cur : ASVector) {
535 Cur->Forward = AliasAnyAS;
536 AliasAnyAS->addRef();
537 FwdTo->dropRef(*
this);
549 AliasSet::AccessLattice
E) {
556 return mergeAllAliasSets();
567 OS <<
" AliasSet[" << (
const void*)
this <<
", " << RefCount <<
"] ";
568 OS << (Alias == SetMustAlias ?
"must" :
"may") <<
" alias, ";
570 case NoAccess:
OS <<
"No access ";
break;
571 case RefAccess:
OS <<
"Ref ";
break;
572 case ModAccess:
OS <<
"Mod ";
break;
573 case ModRefAccess:
OS <<
"Mod/Ref ";
break;
577 OS <<
" forwarding to " << (
void*)Forward;
583 I.getPointer()->printAsOperand(
OS <<
"(");
585 OS <<
", unknown after)";
587 OS <<
", unknown before-or-after)";
589 OS <<
", " <<
I.getSize() <<
")";
592 if (!UnknownInsts.empty()) {
594 OS <<
"\n " << UnknownInsts.size() <<
" Unknown instructions: ";
598 I->printAsOperand(
OS);
607 OS <<
"Alias Set Tracker: " << AliasSets.size();
609 OS <<
" (Saturated)";
610 OS <<
" alias sets for " << PointerMap.
size() <<
" pointer values.\n";
616#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
632 OS <<
"Alias sets for function '" <<
F.getName() <<
"':\n";
unsigned const MachineRegisterInfo * MRI
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static cl::opt< unsigned > SaturationThreshold("alias-set-saturation-threshold", cl::Hidden, cl::init(250), cl::desc("The maximum number of pointers may-alias " "sets may contain before degradation"))
Atomic ordering constants.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file provides utility analysis objects describing memory locations.
print must be executed print the must be executed context for all instructions
This header defines various interfaces for pass management in LLVM.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A manager for alias analyses.
The possible results of an alias query.
@ MayAlias
The two locations may or may not alias.
@ NoAlias
The two locations do not alias at all.
@ MustAlias
The two locations precisely alias each other.
BatchAAResults & getAliasAnalysis() const
Return the underlying alias analysis object used by this tracker.
AliasSet & getAliasSetFor(const MemoryLocation &MemLoc)
Return the alias set which contains the specified memory location.
void addUnknown(Instruction *I)
void print(raw_ostream &OS) const
void add(Value *Ptr, LocationSize Size, const AAMDNodes &AAInfo)
These methods are used to add different types of instructions to the alias sets.
Define an iterator for alias sets... this is just a forward iterator.
void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA)
Merge the specified alias set into this alias set.
void print(raw_ostream &OS) const
ModRefInfo aliasesUnknownInst(const Instruction *Inst, BatchAAResults &AA) const
AliasResult aliasesPointer(const Value *Ptr, LocationSize Size, const AAMDNodes &AAInfo, BatchAAResults &AA) const
If the specified pointer "may" (or must) alias one of the members in the set return the appropriate A...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
AliasSetsPrinterPass(raw_ostream &OS)
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents any memset intrinsic.
LLVM Basic Block Representation.
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)
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx)
bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
MemoryEffects getMemoryEffects(const CallBase *Call)
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
An instruction for reading from memory.
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static constexpr LocationSize afterPointer()
Any location after the base pointer (but still within the underlying object).
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Representation for a specific memory location.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
static MemoryLocation getForSource(const MemTransferInst *MTI)
Return a location representing the source of a memory transfer.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known.
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 MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
static MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
An instruction for storing to memory.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool match(Val *V, const Pattern &P)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are are tuples (A,...
bool isStrongerThanMonotonic(AtomicOrdering AO)
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool isGuard(const User *U)
Returns true iff U has semantics of a guard expressed in a form of call of llvm.experimental....
bool isModSet(const ModRefInfo MRI)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isModOrRefSet(const ModRefInfo MRI)
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.
@ NoModRef
The access neither references nor modifies the value stored in memory.
bool isModAndRefSet(const ModRefInfo MRI)
bool isNoModRef(const ModRefInfo MRI)
bool isRefSet(const ModRefInfo MRI)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...