18 #include "llvm/Config/llvm-config.h" 46 cl::desc(
"The maximum number of pointers may-alias " 47 "sets may contain before degradation"));
52 assert(!AS.Forward &&
"Alias set is already forwarding!");
53 assert(!Forward &&
"This set is a forwarding set!!");
55 bool WasMustAlias = (Alias == SetMustAlias);
60 if (Alias == SetMustAlias) {
65 PointerRec *L = getSomePointer();
66 PointerRec *R = AS.getSomePointer();
75 if (Alias == SetMayAlias) {
77 AST.TotalMayAliasSetSize +=
size();
78 if (AS.Alias == SetMustAlias)
79 AST.TotalMayAliasSetSize += AS.
size();
82 bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
83 if (UnknownInsts.empty()) {
84 if (ASHadUnknownInsts) {
88 }
else if (ASHadUnknownInsts) {
89 UnknownInsts.insert(UnknownInsts.end(), AS.UnknownInsts.begin(), AS.UnknownInsts.end());
90 AS.UnknownInsts.clear();
100 *PtrListEnd = AS.PtrList;
101 AS.PtrList->setPrevInList(PtrListEnd);
102 PtrListEnd = AS.PtrListEnd;
104 AS.PtrList =
nullptr;
105 AS.PtrListEnd = &AS.PtrList;
106 assert(*AS.PtrListEnd ==
nullptr &&
"End of list is not null?");
108 if (ASHadUnknownInsts)
112 void AliasSetTracker::removeAliasSet(
AliasSet *AS) {
115 AS->Forward =
nullptr;
117 if (AS->Alias == AliasSet::SetMayAlias)
118 TotalMayAliasSetSize -= AS->
size();
124 assert(RefCount == 0 &&
"Cannot remove non-dead alias set from tracker!");
125 AST.removeAliasSet(
this);
130 bool KnownMustAlias) {
131 assert(!Entry.hasAliasSet() &&
"Entry already in set!");
135 if (PointerRec *
P = getSomePointer()) {
142 AST.TotalMayAliasSetSize +=
size();
145 P->updateSizeAndAAInfo(Size, AAInfo);
150 Entry.setAliasSet(
this);
151 Entry.updateSizeAndAAInfo(Size, AAInfo);
155 assert(*PtrListEnd ==
nullptr &&
"End of list is not null?");
156 *PtrListEnd = &Entry;
157 PtrListEnd = Entry.setPrevInList(PtrListEnd);
158 assert(*PtrListEnd ==
nullptr &&
"End of list is not null?");
162 if (Alias == SetMayAlias)
163 AST.TotalMayAliasSetSize++;
167 if (UnknownInsts.empty())
169 UnknownInsts.emplace_back(I);
175 !(I->
use_empty() &&
match(I, m_Intrinsic<Intrinsic::invariant_start>()));
176 if (!MayWriteMemory) {
184 Access = ModRefAccess;
196 if (Alias == SetMustAlias) {
197 assert(UnknownInsts.empty() &&
"Illegal must alias set!");
201 PointerRec *SomePtr = getSomePointer();
202 assert(SomePtr &&
"Empty must-alias set??");
204 SomePtr->getAAInfo()),
216 if (!UnknownInsts.empty()) {
217 for (
unsigned i = 0, e = UnknownInsts.size(); i != e; ++i)
218 if (
auto *Inst = getUnknownInst(i))
234 "Instruction must either read or write memory.");
236 for (
unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
237 if (
auto *UnknownInst = getUnknownInst(i)) {
248 Inst,
MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()))))
259 if (!UnknownInsts.empty())
267 "where's the instruction which added this pointer?");
272 return cast<Instruction>(*(Addr->
user_begin()));
274 if (1 != UnknownInsts.size())
276 return cast<Instruction>(UnknownInsts[0]);
283 I->second->eraseFromList();
295 AliasSet *AliasSetTracker::mergeAliasSetsForPointer(
const Value *Ptr,
301 if (Cur->Forward || !Cur->aliasesPointer(Ptr, Size, AAInfo, AA))
continue;
317 if (Cur->Forward || !Cur->aliasesUnknownInst(Inst, AA))
333 AliasSet::PointerRec &Entry = getEntryFor(Pointer);
341 if (Entry.hasAliasSet()) {
342 Entry.updateSizeAndAAInfo(Size, AAInfo);
343 assert(Entry.getAliasSet(*
this) == AliasAnyAS &&
344 "Entry in saturated AST must belong to only alias set");
346 AliasAnyAS->addPointer(*
this, Entry, Size, AAInfo);
352 if (Entry.hasAliasSet()) {
358 if (Entry.updateSizeAndAAInfo(Size, AAInfo))
359 mergeAliasSetsForPointer(Pointer, Size, AAInfo);
361 return *Entry.getAliasSet(*this)->getForwardedTarget(*
this);
364 if (
AliasSet *AS = mergeAliasSetsForPointer(Pointer, Size, AAInfo)) {
366 AS->addPointer(*
this, Entry, Size, AAInfo);
371 AliasSets.push_back(
new AliasSet());
372 AliasSets.back().addPointer(*
this, Entry, Size, AAInfo);
373 return AliasSets.back();
378 addPointer(
MemoryLocation(Ptr, Size, AAInfo), AliasSet::NoAccess);
383 return addUnknown(LI);
389 return addUnknown(SI);
407 if (isa<DbgInfoIntrinsic>(Inst))
410 if (
auto *II = dyn_cast<IntrinsicInst>(Inst)) {
413 switch (II->getIntrinsicID()) {
425 AliasSet *AS = findAliasSetForUnknownInst(Inst);
427 AS->addUnknownInst(Inst, AA);
430 AliasSets.push_back(
new AliasSet());
431 AS = &AliasSets.back();
432 AS->addUnknownInst(Inst, AA);
437 if (
LoadInst *LI = dyn_cast<LoadInst>(I))
441 if (
VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
449 if (
auto *Call = dyn_cast<CallBase>(I))
450 if (Call->onlyAccessesArgMemory()) {
453 return AliasSet::ModRefAccess;
455 return AliasSet::ModAccess;
457 return AliasSet::RefAccess;
459 return AliasSet::NoAccess;
468 if (Call->use_empty() &&
469 match(Call, m_Intrinsic<Intrinsic::invariant_start>()))
472 for (
auto IdxArgPair :
enumerate(Call->args())) {
473 int ArgIdx = IdxArgPair.index();
474 const Value *
Arg = IdxArgPair.value();
482 addPointer(ArgLoc, getAccessFromModRef(ArgMask));
487 return addUnknown(I);
497 "Merging AliasSetTracker objects with different Alias Analyses!");
507 for (
unsigned i = 0, e = AS.UnknownInsts.size(); i != e; ++i)
508 if (
auto *Inst = AS.getUnknownInst(i))
515 (AliasSet::AccessLattice)AS.Access);
527 if (I == PointerMap.end())
return;
530 AliasSet::PointerRec *PtrValEnt = I->second;
531 AliasSet *AS = PtrValEnt->getAliasSet(*
this);
534 PtrValEnt->eraseFromList();
536 if (AS->Alias == AliasSet::SetMayAlias) {
538 TotalMayAliasSetSize--;
555 if (I == PointerMap.end())
557 assert(I->second->hasAliasSet() &&
"Dead entry?");
559 AliasSet::PointerRec &Entry = getEntryFor(To);
560 if (Entry.hasAliasSet())
return;
563 I = PointerMap.find_as(From);
565 AliasSet *AS = I->second->getAliasSet(*
this);
566 AS->addPointer(*
this, Entry, I->second->getSize(),
567 I->second->getAAInfo(),
571 AliasSet &AliasSetTracker::mergeAllAliasSets() {
573 "Full merge should happen once, when the saturation threshold is " 578 std::vector<AliasSet *> ASVector;
581 ASVector.push_back(&*I);
585 AliasSets.push_back(
new AliasSet());
586 AliasAnyAS = &AliasSets.back();
587 AliasAnyAS->Alias = AliasSet::SetMayAlias;
588 AliasAnyAS->Access = AliasSet::ModRefAccess;
589 AliasAnyAS->AliasAny =
true;
591 for (
auto Cur : ASVector) {
595 Cur->Forward = AliasAnyAS;
596 AliasAnyAS->addRef();
597 FwdTo->dropRef(*
this);
602 AliasAnyAS->mergeSetIn(*Cur, *
this);
609 AliasSet::AccessLattice
E) {
616 return mergeAllAliasSets();
627 OS <<
" AliasSet[" << (
const void*)
this <<
", " << RefCount <<
"] ";
628 OS << (Alias == SetMustAlias ?
"must" :
"may") <<
" alias, ";
630 case NoAccess: OS <<
"No access ";
break;
631 case RefAccess: OS <<
"Ref ";
break;
632 case ModAccess: OS <<
"Mod ";
break;
633 case ModRefAccess: OS <<
"Mod/Ref ";
break;
637 OS <<
" forwarding to " << (
void*)Forward;
642 if (I !=
begin()) OS <<
", ";
647 OS <<
", " << I.getSize() <<
")";
650 if (!UnknownInsts.empty()) {
651 OS <<
"\n " << UnknownInsts.size() <<
" Unknown instructions: ";
652 for (
unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
654 if (
auto *I = getUnknownInst(i)) {
666 OS <<
"Alias Set Tracker: " << AliasSets.size() <<
" alias sets for " 667 << PointerMap.size() <<
" pointer values.\n";
673 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 682 void AliasSetTracker::ASTCallbackVH::deleted() {
683 assert(AST &&
"ASTCallbackVH called with a null AliasSetTracker!");
688 void AliasSetTracker::ASTCallbackVH::allUsesReplacedWith(
Value *V) {
695 AliasSetTracker::ASTCallbackVH &
696 AliasSetTracker::ASTCallbackVH::operator=(
Value *V) {
697 return *
this = ASTCallbackVH(V, AST);
722 auto &AAWP = getAnalysis<AAResultsWrapperPass>();
724 errs() <<
"Alias sets for function '" << F.
getName() <<
"':\n";
727 Tracker->print(
errs());
738 "Alias Set Printer",
false,
true)
void mergeSetIn(AliasSet &AS, AliasSetTracker &AST)
Merge the specified alias set into this alias set.
INITIALIZE_PASS_BEGIN(AliasSetPrinter, "print-alias-sets", "Alias Set Printer", false, true) INITIALIZE_PASS_END(AliasSetPrinter
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Atomic ordering constants.
This class represents lattice values for constants.
Define an iterator for alias sets... this is just a forward iterator.
static constexpr LocationSize unknown()
void add(Value *Ptr, LocationSize Size, const AAMDNodes &AAInfo)
These methods are used to add different types of instructions to the alias sets.
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"))
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
The two locations do not alias at all.
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
block Block Frequency true
An instruction for reading from memory.
print alias Alias Set Printer
LLVM_NODISCARD ModRefInfo clearMod(const ModRefInfo MRI)
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
bool match(Val *V, const Pattern &P)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
inst_iterator inst_begin(Function *F)
void initializeAliasSetPrinterPass(PassRegistry &)
static MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
FunctionModRefBehavior getModRefBehavior(const CallBase *Call)
Return the behavior of the given call site.
Type * getType() const
All values are typed, get the type of this value.
friend class AliasSetTracker
bool aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA) const
static MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
Instruction * getUniqueInstruction()
If this alias set is known to contain a single instruction and only a single unique instruction...
An instruction for storing to memory.
bool isStrongerThanMonotonic(AtomicOrdering ao)
AliasResult
The possible results of an alias query.
static bool runOnFunction(Function &F, bool PostInlining)
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)
void print(raw_ostream &OS) const
unsigned const MachineRegisterInfo * MRI
LLVM Basic Block Representation.
AliasAnalysis & getAliasAnalysis() const
Return the underlying alias analysis object used by this tracker.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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.
Represent the analysis usage information of a pass.
AliasSet & getAliasSetFor(const MemoryLocation &MemLoc)
Return the alias set which contains the specified memory location.
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
FunctionPass class - This class is used to implement most global optimizations.
This class represents any memset intrinsic.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known...
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const Value * Ptr
The address of the start of the location.
Representation for a specific memory location.
The two locations precisely alias each other.
Iterator for intrusive lists based on ilist_node.
BlockVerifier::State From
void print(raw_ostream &OS) const
void copyValue(Value *From, Value *To)
This method should be used whenever a preexisting value in the program is copied or cloned...
Module.h This file contains the declarations for the Module class.
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
bool isGuard(const User *U)
Returns true iff U has semantics of a guard.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
void setPreservesAll()
Set by analyses that do not transform their input at all.
LLVM_NODISCARD bool isNoModRef(const ModRefInfo MRI)
amdgpu Simplify well known AMD library false Value Value * Arg
LLVM_NODISCARD bool isModSet(const ModRefInfo MRI)
AAMDNodes AATags
The metadata nodes which describes the aliasing of the location (each member is null if that kind of ...
AtomicOrdering getOrdering() const
Returns the ordering constraint of this store instruction.
This file provides utility analysis objects describing memory locations.
StringRef getName() const
Return a constant reference to the value's name.
LLVM_NODISCARD ModRefInfo intersectModRef(const ModRefInfo MRI1, const ModRefInfo MRI2)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx)
Get the ModRef info associated with a pointer argument of a call.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
LLVM Value Representation.
LLVM_NODISCARD ModRefInfo createModRefInfo(const FunctionModRefBehavior FMRB)
This class implements an extremely fast bulk output stream that can only output to a stream...
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
Value handle with callbacks on RAUW and destruction.
inst_iterator inst_end(Function *F)
bool aliasesPointer(const Value *Ptr, LocationSize Size, const AAMDNodes &AAInfo, AliasAnalysis &AA) const
Return true if the specified pointer "may" (or must) alias one of the members in the set...
LLVM_NODISCARD bool isModOrRefSet(const ModRefInfo MRI)
void addUnknown(Instruction *I)
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 ...
void deleteValue(Value *PtrVal)
This method is used to remove a pointer value from the AliasSetTracker entirely.
detail::enumerator< R > enumerate(R &&TheRange)
Given an input range, returns a new range whose values are are pair (A,B) such that A is the 0-based ...
static MemoryLocation getForSource(const MemTransferInst *MTI)
Return a location representing the source of a memory transfer.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
LLVM_NODISCARD bool isRefSet(const ModRefInfo MRI)