32 cl::desc(
"The maximum number of pointers may-alias "
33 "sets may contain before degradation"));
38 assert(!AS.Forward &&
"Alias set is already forwarding!");
39 assert(!Forward &&
"This set is a forwarding set!!");
41 bool WasMustAlias = (Alias == SetMustAlias);
45 Volatile |= AS.Volatile;
47 if (Alias == SetMustAlias) {
52 PointerRec *
L = getSomePointer();
53 PointerRec *R = AS.getSomePointer();
62 if (Alias == SetMayAlias) {
64 AST.TotalMayAliasSetSize +=
size();
65 if (AS.Alias == SetMustAlias)
66 AST.TotalMayAliasSetSize += AS.
size();
69 bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
70 if (UnknownInsts.empty()) {
71 if (ASHadUnknownInsts) {
75 }
else if (ASHadUnknownInsts) {
76 UnknownInsts.insert(UnknownInsts.end(), AS.UnknownInsts.begin(), AS.UnknownInsts.end());
77 AS.UnknownInsts.clear();
87 *PtrListEnd = AS.PtrList;
88 AS.PtrList->setPrevInList(PtrListEnd);
89 PtrListEnd = AS.PtrListEnd;
92 AS.PtrListEnd = &AS.PtrList;
93 assert(*AS.PtrListEnd ==
nullptr &&
"End of list is not null?");
95 if (ASHadUnknownInsts)
99 void AliasSetTracker::removeAliasSet(
AliasSet *AS) {
102 AS->Forward =
nullptr;
105 if (AS->Alias == AliasSet::SetMayAlias)
106 TotalMayAliasSetSize -= AS->
size();
113 assert(RefCount == 0 &&
"Cannot remove non-dead alias set from tracker!");
114 AST.removeAliasSet(
this);
119 bool KnownMustAlias) {
120 assert(!Entry.hasAliasSet() &&
"Entry already in set!");
124 if (PointerRec *
P = getSomePointer()) {
131 AST.TotalMayAliasSetSize +=
size();
134 P->updateSizeAndAAInfo(Size, AAInfo);
139 Entry.setAliasSet(
this);
140 Entry.updateSizeAndAAInfo(Size, AAInfo);
144 assert(*PtrListEnd ==
nullptr &&
"End of list is not null?");
145 *PtrListEnd = &Entry;
146 PtrListEnd = Entry.setPrevInList(PtrListEnd);
147 assert(*PtrListEnd ==
nullptr &&
"End of list is not null?");
151 if (Alias == SetMayAlias)
152 AST.TotalMayAliasSetSize++;
156 if (UnknownInsts.empty())
158 UnknownInsts.emplace_back(I);
168 Access = ModRefAccess;
180 if (Alias == SetMustAlias) {
181 assert(UnknownInsts.empty() &&
"Illegal must alias set!");
185 PointerRec *SomePtr = getSomePointer();
186 assert(SomePtr &&
"Empty must-alias set??");
188 SomePtr->getAAInfo()),
200 if (!UnknownInsts.empty()) {
201 for (
unsigned i = 0, e = UnknownInsts.size();
i != e; ++
i)
219 for (
unsigned i = 0, e = UnknownInsts.size();
i != e; ++
i) {
238 I->second->eraseFromList();
256 if (Cur->Forward || !Cur->aliasesPointer(Ptr, Size, AAInfo, AA))
continue;
279 if (Cur->Forward || !Cur->aliasesUnknownInst(Inst, AA))
283 else if (!Cur->Forward)
293 AliasSet::PointerRec &Entry = getEntryFor(Pointer);
301 if (Entry.hasAliasSet()) {
302 Entry.updateSizeAndAAInfo(Size, AAInfo);
303 assert(Entry.getAliasSet(*
this) == AliasAnyAS &&
304 "Entry in saturated AST must belong to only alias set");
306 AliasAnyAS->addPointer(*
this, Entry, Size, AAInfo);
312 if (Entry.hasAliasSet()) {
318 if (Entry.updateSizeAndAAInfo(Size, AAInfo))
319 mergeAliasSetsForPointer(Pointer, Size, AAInfo);
321 return *Entry.getAliasSet(*this)->getForwardedTarget(*
this);
324 if (
AliasSet *AS = mergeAliasSetsForPointer(Pointer, Size, AAInfo)) {
326 AS->addPointer(*
this, Entry, Size, AAInfo);
331 AliasSets.push_back(
new AliasSet());
332 AliasSets.back().addPointer(*
this, Entry, Size, AAInfo);
333 return AliasSets.back();
337 addPointer(Ptr, Size, AAInfo, AliasSet::NoAccess);
346 AliasSet::AccessLattice Access = AliasSet::RefAccess;
359 AliasSet::AccessLattice Access = AliasSet::ModAccess;
372 AliasSet::ModRefAccess);
382 Len =
C->getZExtValue();
387 addPointer(MSI->
getRawDest(), Len, AAInfo, AliasSet::ModAccess);
398 Len =
C->getZExtValue();
403 addPointer(MTI->
getRawSource(), Len, AAInfo, AliasSet::RefAccess);
408 addPointer(MTI->
getRawDest(), Len, AAInfo, AliasSet::ModAccess);
414 if (isa<DbgInfoIntrinsic>(Inst))
417 if (
auto *II = dyn_cast<IntrinsicInst>(Inst)) {
420 switch (II->getIntrinsicID()) {
424 case Intrinsic::assume:
431 AliasSet *AS = findAliasSetForUnknownInst(Inst);
433 AS->addUnknownInst(Inst, AA);
436 AliasSets.push_back(
new AliasSet());
437 AS = &AliasSets.back();
438 AS->addUnknownInst(Inst, AA);
443 if (
LoadInst *LI = dyn_cast<LoadInst>(I))
447 if (
VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
449 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(I))
463 "Merging AliasSetTracker objects with different Alias Analyses!");
473 for (
unsigned i = 0, e = AS.UnknownInsts.size();
i != e; ++
i)
474 add(AS.UnknownInsts[
i]);
479 addPointer(ASI.getPointer(), ASI.getSize(), ASI.getAAInfo(),
480 (AliasSet::AccessLattice)AS.Access);
494 if (
Instruction *Inst = dyn_cast<Instruction>(PtrVal)) {
500 Cur->removeUnknownInst(*
this, Inst);
507 if (I == PointerMap.
end())
return;
510 AliasSet::PointerRec *PtrValEnt = I->second;
511 AliasSet *AS = PtrValEnt->getAliasSet(*
this);
514 PtrValEnt->eraseFromList();
516 if (AS->Alias == AliasSet::SetMayAlias) {
518 TotalMayAliasSetSize--;
535 if (I == PointerMap.
end())
537 assert(I->second->hasAliasSet() &&
"Dead entry?");
539 AliasSet::PointerRec &Entry = getEntryFor(To);
540 if (Entry.hasAliasSet())
return;
545 AliasSet *AS = I->second->getAliasSet(*
this);
546 AS->addPointer(*
this, Entry, I->second->getSize(),
547 I->second->getAAInfo(),
551 AliasSet &AliasSetTracker::mergeAllAliasSets() {
553 "Full merge should happen once, when the saturation threshold is "
558 std::vector<AliasSet *> ASVector;
561 ASVector.push_back(&*I);
565 AliasSets.push_back(
new AliasSet());
566 AliasAnyAS = &AliasSets.back();
567 AliasAnyAS->Alias = AliasSet::SetMayAlias;
568 AliasAnyAS->Access = AliasSet::ModRefAccess;
569 AliasAnyAS->AliasAny =
true;
571 for (
auto Cur : ASVector) {
576 Cur->Forward = AliasAnyAS;
577 AliasAnyAS->addRef();
578 FwdTo->dropRef(*
this);
591 AliasSet::AccessLattice
E) {
599 return mergeAllAliasSets();
610 OS <<
" AliasSet[" << (
const void*)
this <<
", " << RefCount <<
"] ";
611 OS << (Alias == SetMustAlias ?
"must" :
"may") <<
" alias, ";
613 case NoAccess: OS <<
"No access ";
break;
614 case RefAccess: OS <<
"Ref ";
break;
615 case ModAccess: OS <<
"Mod ";
break;
616 case ModRefAccess: OS <<
"Mod/Ref ";
break;
621 OS <<
" forwarding to " << (
void*)Forward;
627 if (I !=
begin()) OS <<
", ";
629 OS <<
", " << I.getSize() <<
")";
632 if (!UnknownInsts.empty()) {
633 OS <<
"\n " << UnknownInsts.size() <<
" Unknown instructions: ";
634 for (
unsigned i = 0, e = UnknownInsts.size();
i != e; ++
i) {
636 UnknownInsts[
i]->printAsOperand(OS);
643 OS <<
"Alias Set Tracker: " << AliasSets.size() <<
" alias sets for "
644 << PointerMap.
size() <<
" pointer values.\n";
650 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
659 void AliasSetTracker::ASTCallbackVH::deleted() {
660 assert(AST &&
"ASTCallbackVH called with a null AliasSetTracker!");
665 void AliasSetTracker::ASTCallbackVH::allUsesReplacedWith(
Value *V) {
672 AliasSetTracker::ASTCallbackVH &
673 AliasSetTracker::ASTCallbackVH::operator=(
Value *V) {
674 return *
this = ASTCallbackVH(V, AST);
695 bool runOnFunction(
Function &
F)
override {
696 auto &AAWP = getAnalysis<AAResultsWrapperPass>();
698 errs() <<
"Alias sets for function '" << F.
getName() <<
"':\n";
701 Tracker->print(
errs());
710 "Alias Set Printer",
false,
true)
The two locations precisely alias each other.
void mergeSetIn(AliasSet &AS, AliasSetTracker &AST)
Merge the specified alias set into this alias set.
A parsed version of the target data layout string in and methods for querying it. ...
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...
bool isVolatile() const
Return true if this is a store to a volatile memory location.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Define an iterator for alias sets... this is just a forward iterator.
This class wraps the llvm.memset intrinsic.
The two locations do not alias at all.
An instruction for reading from memory.
print alias Alias Set Printer
StringRef getName() const
Return a constant reference to the value's name.
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
inst_iterator inst_begin(Function *F)
const_iterator end() const
void initializeAliasSetPrinterPass(PassRegistry &)
bool aliasesPointer(const Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo, AliasAnalysis &AA) const
Return true if the specified pointer "may" (or must) alias one of the members in the set...
const_iterator begin() const
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.
An instruction for storing to memory.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
bool aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA) const
The access neither references nor modifies the value stored in memory.
initializer< Ty > init(const Ty &Val)
bool erase(const KeyT &Val)
LLVM Basic Block Representation.
bool isVolatile() const
Return true if this alias set contains volatile loads or stores.
Value * getRawDest() const
AliasResult
The possible results of an alias query.
Represent the analysis usage information of a pass.
print alias Alias Set false
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
void print(raw_ostream &OS) const
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"))
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
Representation for a specific memory location.
INITIALIZE_PASS_BEGIN(AliasSetPrinter,"print-alias-sets","Alias Set Printer", false, true) INITIALIZE_PASS_END(AliasSetPrinter
Iterator for intrusive lists based on ilist_node.
AtomicOrdering getOrdering() const
Returns the ordering effect of this store.
This is the shared class of boolean and integer constants.
static bool isStrongerThanMonotonic(AtomicOrdering ao)
AliasAnalysis & getAliasAnalysis() const
Return the underlying alias analysis object used by this tracker.
void copyValue(Value *From, Value *To)
This method should be used whenever a preexisting value in the program is copied or cloned...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
bool isVolatile() const
Return true if this is a load from a volatile memory location.
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Value * getLength() const
bool containsUnknown(const Instruction *I) const
Return true if the specified instruction "may" (or must) alias one of the members in any of the sets...
AtomicOrdering getOrdering() const
Returns the ordering effect of this fence.
void add(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo)
These methods are used to add different types of instructions to the alias sets.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
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.
ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc)
getModRefInfo (for call sites) - Return information about whether a particular call site modifies or ...
void setPreservesAll()
Set by analyses that do not transform their input at all.
void print(raw_ostream &OS) const
ilist< AliasSet >::iterator iterator
This class wraps the llvm.memcpy/memmove intrinsics.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
AliasSet & getAliasSetForPointer(Value *P, uint64_t Size, const AAMDNodes &AAInfo)
Return the alias set that the specified pointer lives in.
void getAAMetadata(AAMDNodes &N, bool Merge=false) const
Fills the AAMDNodes structure with AA metadata from this instruction.
ImmutableCallSite - establish a view to a call site for examination.
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
iterator find_as(const LookupKeyT &Val)
Alternate version of find() which allows a different, and possibly less expensive, key type.
Value * getRawSource() const
Return the arguments to the instruction.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream...
Value handle with callbacks on RAUW and destruction.
inst_iterator inst_end(Function *F)
void addUnknown(Instruction *I)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
void deleteValue(Value *PtrVal)
This method is used to remove a pointer value from the AliasSetTracker entirely.