xref: /aosp_15_r20/external/llvm/lib/Analysis/AliasSetTracker.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the AliasSetTracker and AliasSet classes.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/AliasSetTracker.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/AliasAnalysis.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/InstIterator.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IntrinsicInst.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Type.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
27*9880d681SAndroid Build Coastguard Worker using namespace llvm;
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker /// mergeSetIn - Merge the specified alias set into this alias set.
30*9880d681SAndroid Build Coastguard Worker ///
mergeSetIn(AliasSet & AS,AliasSetTracker & AST)31*9880d681SAndroid Build Coastguard Worker void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
32*9880d681SAndroid Build Coastguard Worker   assert(!AS.Forward && "Alias set is already forwarding!");
33*9880d681SAndroid Build Coastguard Worker   assert(!Forward && "This set is a forwarding set!!");
34*9880d681SAndroid Build Coastguard Worker 
35*9880d681SAndroid Build Coastguard Worker   // Update the alias and access types of this set...
36*9880d681SAndroid Build Coastguard Worker   Access |= AS.Access;
37*9880d681SAndroid Build Coastguard Worker   Alias  |= AS.Alias;
38*9880d681SAndroid Build Coastguard Worker   Volatile |= AS.Volatile;
39*9880d681SAndroid Build Coastguard Worker 
40*9880d681SAndroid Build Coastguard Worker   if (Alias == SetMustAlias) {
41*9880d681SAndroid Build Coastguard Worker     // Check that these two merged sets really are must aliases.  Since both
42*9880d681SAndroid Build Coastguard Worker     // used to be must-alias sets, we can just check any pointer from each set
43*9880d681SAndroid Build Coastguard Worker     // for aliasing.
44*9880d681SAndroid Build Coastguard Worker     AliasAnalysis &AA = AST.getAliasAnalysis();
45*9880d681SAndroid Build Coastguard Worker     PointerRec *L = getSomePointer();
46*9880d681SAndroid Build Coastguard Worker     PointerRec *R = AS.getSomePointer();
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker     // If the pointers are not a must-alias pair, this set becomes a may alias.
49*9880d681SAndroid Build Coastguard Worker     if (AA.alias(MemoryLocation(L->getValue(), L->getSize(), L->getAAInfo()),
50*9880d681SAndroid Build Coastguard Worker                  MemoryLocation(R->getValue(), R->getSize(), R->getAAInfo())) !=
51*9880d681SAndroid Build Coastguard Worker         MustAlias)
52*9880d681SAndroid Build Coastguard Worker       Alias = SetMayAlias;
53*9880d681SAndroid Build Coastguard Worker   }
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker   bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
56*9880d681SAndroid Build Coastguard Worker   if (UnknownInsts.empty()) {            // Merge call sites...
57*9880d681SAndroid Build Coastguard Worker     if (ASHadUnknownInsts) {
58*9880d681SAndroid Build Coastguard Worker       std::swap(UnknownInsts, AS.UnknownInsts);
59*9880d681SAndroid Build Coastguard Worker       addRef();
60*9880d681SAndroid Build Coastguard Worker     }
61*9880d681SAndroid Build Coastguard Worker   } else if (ASHadUnknownInsts) {
62*9880d681SAndroid Build Coastguard Worker     UnknownInsts.insert(UnknownInsts.end(), AS.UnknownInsts.begin(), AS.UnknownInsts.end());
63*9880d681SAndroid Build Coastguard Worker     AS.UnknownInsts.clear();
64*9880d681SAndroid Build Coastguard Worker   }
65*9880d681SAndroid Build Coastguard Worker 
66*9880d681SAndroid Build Coastguard Worker   AS.Forward = this;  // Forward across AS now...
67*9880d681SAndroid Build Coastguard Worker   addRef();           // AS is now pointing to us...
68*9880d681SAndroid Build Coastguard Worker 
69*9880d681SAndroid Build Coastguard Worker   // Merge the list of constituent pointers...
70*9880d681SAndroid Build Coastguard Worker   if (AS.PtrList) {
71*9880d681SAndroid Build Coastguard Worker     *PtrListEnd = AS.PtrList;
72*9880d681SAndroid Build Coastguard Worker     AS.PtrList->setPrevInList(PtrListEnd);
73*9880d681SAndroid Build Coastguard Worker     PtrListEnd = AS.PtrListEnd;
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker     AS.PtrList = nullptr;
76*9880d681SAndroid Build Coastguard Worker     AS.PtrListEnd = &AS.PtrList;
77*9880d681SAndroid Build Coastguard Worker     assert(*AS.PtrListEnd == nullptr && "End of list is not null?");
78*9880d681SAndroid Build Coastguard Worker   }
79*9880d681SAndroid Build Coastguard Worker   if (ASHadUnknownInsts)
80*9880d681SAndroid Build Coastguard Worker     AS.dropRef(AST);
81*9880d681SAndroid Build Coastguard Worker }
82*9880d681SAndroid Build Coastguard Worker 
removeAliasSet(AliasSet * AS)83*9880d681SAndroid Build Coastguard Worker void AliasSetTracker::removeAliasSet(AliasSet *AS) {
84*9880d681SAndroid Build Coastguard Worker   if (AliasSet *Fwd = AS->Forward) {
85*9880d681SAndroid Build Coastguard Worker     Fwd->dropRef(*this);
86*9880d681SAndroid Build Coastguard Worker     AS->Forward = nullptr;
87*9880d681SAndroid Build Coastguard Worker   }
88*9880d681SAndroid Build Coastguard Worker   AliasSets.erase(AS);
89*9880d681SAndroid Build Coastguard Worker }
90*9880d681SAndroid Build Coastguard Worker 
removeFromTracker(AliasSetTracker & AST)91*9880d681SAndroid Build Coastguard Worker void AliasSet::removeFromTracker(AliasSetTracker &AST) {
92*9880d681SAndroid Build Coastguard Worker   assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!");
93*9880d681SAndroid Build Coastguard Worker   AST.removeAliasSet(this);
94*9880d681SAndroid Build Coastguard Worker }
95*9880d681SAndroid Build Coastguard Worker 
addPointer(AliasSetTracker & AST,PointerRec & Entry,uint64_t Size,const AAMDNodes & AAInfo,bool KnownMustAlias)96*9880d681SAndroid Build Coastguard Worker void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
97*9880d681SAndroid Build Coastguard Worker                           uint64_t Size, const AAMDNodes &AAInfo,
98*9880d681SAndroid Build Coastguard Worker                           bool KnownMustAlias) {
99*9880d681SAndroid Build Coastguard Worker   assert(!Entry.hasAliasSet() && "Entry already in set!");
100*9880d681SAndroid Build Coastguard Worker 
101*9880d681SAndroid Build Coastguard Worker   // Check to see if we have to downgrade to _may_ alias.
102*9880d681SAndroid Build Coastguard Worker   if (isMustAlias() && !KnownMustAlias)
103*9880d681SAndroid Build Coastguard Worker     if (PointerRec *P = getSomePointer()) {
104*9880d681SAndroid Build Coastguard Worker       AliasAnalysis &AA = AST.getAliasAnalysis();
105*9880d681SAndroid Build Coastguard Worker       AliasResult Result =
106*9880d681SAndroid Build Coastguard Worker           AA.alias(MemoryLocation(P->getValue(), P->getSize(), P->getAAInfo()),
107*9880d681SAndroid Build Coastguard Worker                    MemoryLocation(Entry.getValue(), Size, AAInfo));
108*9880d681SAndroid Build Coastguard Worker       if (Result != MustAlias)
109*9880d681SAndroid Build Coastguard Worker         Alias = SetMayAlias;
110*9880d681SAndroid Build Coastguard Worker       else                  // First entry of must alias must have maximum size!
111*9880d681SAndroid Build Coastguard Worker         P->updateSizeAndAAInfo(Size, AAInfo);
112*9880d681SAndroid Build Coastguard Worker       assert(Result != NoAlias && "Cannot be part of must set!");
113*9880d681SAndroid Build Coastguard Worker     }
114*9880d681SAndroid Build Coastguard Worker 
115*9880d681SAndroid Build Coastguard Worker   Entry.setAliasSet(this);
116*9880d681SAndroid Build Coastguard Worker   Entry.updateSizeAndAAInfo(Size, AAInfo);
117*9880d681SAndroid Build Coastguard Worker 
118*9880d681SAndroid Build Coastguard Worker   // Add it to the end of the list...
119*9880d681SAndroid Build Coastguard Worker   assert(*PtrListEnd == nullptr && "End of list is not null?");
120*9880d681SAndroid Build Coastguard Worker   *PtrListEnd = &Entry;
121*9880d681SAndroid Build Coastguard Worker   PtrListEnd = Entry.setPrevInList(PtrListEnd);
122*9880d681SAndroid Build Coastguard Worker   assert(*PtrListEnd == nullptr && "End of list is not null?");
123*9880d681SAndroid Build Coastguard Worker   addRef();               // Entry points to alias set.
124*9880d681SAndroid Build Coastguard Worker }
125*9880d681SAndroid Build Coastguard Worker 
addUnknownInst(Instruction * I,AliasAnalysis & AA)126*9880d681SAndroid Build Coastguard Worker void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) {
127*9880d681SAndroid Build Coastguard Worker   if (UnknownInsts.empty())
128*9880d681SAndroid Build Coastguard Worker     addRef();
129*9880d681SAndroid Build Coastguard Worker   UnknownInsts.emplace_back(I);
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   if (!I->mayWriteToMemory()) {
132*9880d681SAndroid Build Coastguard Worker     Alias = SetMayAlias;
133*9880d681SAndroid Build Coastguard Worker     Access |= RefAccess;
134*9880d681SAndroid Build Coastguard Worker     return;
135*9880d681SAndroid Build Coastguard Worker   }
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker   // FIXME: This should use mod/ref information to make this not suck so bad
138*9880d681SAndroid Build Coastguard Worker   Alias = SetMayAlias;
139*9880d681SAndroid Build Coastguard Worker   Access = ModRefAccess;
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker 
142*9880d681SAndroid Build Coastguard Worker /// aliasesPointer - Return true if the specified pointer "may" (or must)
143*9880d681SAndroid Build Coastguard Worker /// alias one of the members in the set.
144*9880d681SAndroid Build Coastguard Worker ///
aliasesPointer(const Value * Ptr,uint64_t Size,const AAMDNodes & AAInfo,AliasAnalysis & AA) const145*9880d681SAndroid Build Coastguard Worker bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size,
146*9880d681SAndroid Build Coastguard Worker                               const AAMDNodes &AAInfo,
147*9880d681SAndroid Build Coastguard Worker                               AliasAnalysis &AA) const {
148*9880d681SAndroid Build Coastguard Worker   if (Alias == SetMustAlias) {
149*9880d681SAndroid Build Coastguard Worker     assert(UnknownInsts.empty() && "Illegal must alias set!");
150*9880d681SAndroid Build Coastguard Worker 
151*9880d681SAndroid Build Coastguard Worker     // If this is a set of MustAliases, only check to see if the pointer aliases
152*9880d681SAndroid Build Coastguard Worker     // SOME value in the set.
153*9880d681SAndroid Build Coastguard Worker     PointerRec *SomePtr = getSomePointer();
154*9880d681SAndroid Build Coastguard Worker     assert(SomePtr && "Empty must-alias set??");
155*9880d681SAndroid Build Coastguard Worker     return AA.alias(MemoryLocation(SomePtr->getValue(), SomePtr->getSize(),
156*9880d681SAndroid Build Coastguard Worker                                    SomePtr->getAAInfo()),
157*9880d681SAndroid Build Coastguard Worker                     MemoryLocation(Ptr, Size, AAInfo));
158*9880d681SAndroid Build Coastguard Worker   }
159*9880d681SAndroid Build Coastguard Worker 
160*9880d681SAndroid Build Coastguard Worker   // If this is a may-alias set, we have to check all of the pointers in the set
161*9880d681SAndroid Build Coastguard Worker   // to be sure it doesn't alias the set...
162*9880d681SAndroid Build Coastguard Worker   for (iterator I = begin(), E = end(); I != E; ++I)
163*9880d681SAndroid Build Coastguard Worker     if (AA.alias(MemoryLocation(Ptr, Size, AAInfo),
164*9880d681SAndroid Build Coastguard Worker                  MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo())))
165*9880d681SAndroid Build Coastguard Worker       return true;
166*9880d681SAndroid Build Coastguard Worker 
167*9880d681SAndroid Build Coastguard Worker   // Check the unknown instructions...
168*9880d681SAndroid Build Coastguard Worker   if (!UnknownInsts.empty()) {
169*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i)
170*9880d681SAndroid Build Coastguard Worker       if (AA.getModRefInfo(UnknownInsts[i],
171*9880d681SAndroid Build Coastguard Worker                            MemoryLocation(Ptr, Size, AAInfo)) != MRI_NoModRef)
172*9880d681SAndroid Build Coastguard Worker         return true;
173*9880d681SAndroid Build Coastguard Worker   }
174*9880d681SAndroid Build Coastguard Worker 
175*9880d681SAndroid Build Coastguard Worker   return false;
176*9880d681SAndroid Build Coastguard Worker }
177*9880d681SAndroid Build Coastguard Worker 
aliasesUnknownInst(const Instruction * Inst,AliasAnalysis & AA) const178*9880d681SAndroid Build Coastguard Worker bool AliasSet::aliasesUnknownInst(const Instruction *Inst,
179*9880d681SAndroid Build Coastguard Worker                                   AliasAnalysis &AA) const {
180*9880d681SAndroid Build Coastguard Worker   if (!Inst->mayReadOrWriteMemory())
181*9880d681SAndroid Build Coastguard Worker     return false;
182*9880d681SAndroid Build Coastguard Worker 
183*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
184*9880d681SAndroid Build Coastguard Worker     ImmutableCallSite C1(getUnknownInst(i)), C2(Inst);
185*9880d681SAndroid Build Coastguard Worker     if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != MRI_NoModRef ||
186*9880d681SAndroid Build Coastguard Worker         AA.getModRefInfo(C2, C1) != MRI_NoModRef)
187*9880d681SAndroid Build Coastguard Worker       return true;
188*9880d681SAndroid Build Coastguard Worker   }
189*9880d681SAndroid Build Coastguard Worker 
190*9880d681SAndroid Build Coastguard Worker   for (iterator I = begin(), E = end(); I != E; ++I)
191*9880d681SAndroid Build Coastguard Worker     if (AA.getModRefInfo(Inst, MemoryLocation(I.getPointer(), I.getSize(),
192*9880d681SAndroid Build Coastguard Worker                                               I.getAAInfo())) != MRI_NoModRef)
193*9880d681SAndroid Build Coastguard Worker       return true;
194*9880d681SAndroid Build Coastguard Worker 
195*9880d681SAndroid Build Coastguard Worker   return false;
196*9880d681SAndroid Build Coastguard Worker }
197*9880d681SAndroid Build Coastguard Worker 
clear()198*9880d681SAndroid Build Coastguard Worker void AliasSetTracker::clear() {
199*9880d681SAndroid Build Coastguard Worker   // Delete all the PointerRec entries.
200*9880d681SAndroid Build Coastguard Worker   for (PointerMapType::iterator I = PointerMap.begin(), E = PointerMap.end();
201*9880d681SAndroid Build Coastguard Worker        I != E; ++I)
202*9880d681SAndroid Build Coastguard Worker     I->second->eraseFromList();
203*9880d681SAndroid Build Coastguard Worker 
204*9880d681SAndroid Build Coastguard Worker   PointerMap.clear();
205*9880d681SAndroid Build Coastguard Worker 
206*9880d681SAndroid Build Coastguard Worker   // The alias sets should all be clear now.
207*9880d681SAndroid Build Coastguard Worker   AliasSets.clear();
208*9880d681SAndroid Build Coastguard Worker }
209*9880d681SAndroid Build Coastguard Worker 
210*9880d681SAndroid Build Coastguard Worker 
211*9880d681SAndroid Build Coastguard Worker /// mergeAliasSetsForPointer - Given a pointer, merge all alias sets that may
212*9880d681SAndroid Build Coastguard Worker /// alias the pointer. Return the unified set, or nullptr if no set that aliases
213*9880d681SAndroid Build Coastguard Worker /// the pointer was found.
mergeAliasSetsForPointer(const Value * Ptr,uint64_t Size,const AAMDNodes & AAInfo)214*9880d681SAndroid Build Coastguard Worker AliasSet *AliasSetTracker::mergeAliasSetsForPointer(const Value *Ptr,
215*9880d681SAndroid Build Coastguard Worker                                                     uint64_t Size,
216*9880d681SAndroid Build Coastguard Worker                                                     const AAMDNodes &AAInfo) {
217*9880d681SAndroid Build Coastguard Worker   AliasSet *FoundSet = nullptr;
218*9880d681SAndroid Build Coastguard Worker   for (iterator I = begin(), E = end(); I != E;) {
219*9880d681SAndroid Build Coastguard Worker     iterator Cur = I++;
220*9880d681SAndroid Build Coastguard Worker     if (Cur->Forward || !Cur->aliasesPointer(Ptr, Size, AAInfo, AA)) continue;
221*9880d681SAndroid Build Coastguard Worker 
222*9880d681SAndroid Build Coastguard Worker     if (!FoundSet) {      // If this is the first alias set ptr can go into.
223*9880d681SAndroid Build Coastguard Worker       FoundSet = &*Cur;   // Remember it.
224*9880d681SAndroid Build Coastguard Worker     } else {              // Otherwise, we must merge the sets.
225*9880d681SAndroid Build Coastguard Worker       FoundSet->mergeSetIn(*Cur, *this);     // Merge in contents.
226*9880d681SAndroid Build Coastguard Worker     }
227*9880d681SAndroid Build Coastguard Worker   }
228*9880d681SAndroid Build Coastguard Worker 
229*9880d681SAndroid Build Coastguard Worker   return FoundSet;
230*9880d681SAndroid Build Coastguard Worker }
231*9880d681SAndroid Build Coastguard Worker 
232*9880d681SAndroid Build Coastguard Worker /// containsPointer - Return true if the specified location is represented by
233*9880d681SAndroid Build Coastguard Worker /// this alias set, false otherwise.  This does not modify the AST object or
234*9880d681SAndroid Build Coastguard Worker /// alias sets.
containsPointer(const Value * Ptr,uint64_t Size,const AAMDNodes & AAInfo) const235*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::containsPointer(const Value *Ptr, uint64_t Size,
236*9880d681SAndroid Build Coastguard Worker                                       const AAMDNodes &AAInfo) const {
237*9880d681SAndroid Build Coastguard Worker   for (const AliasSet &AS : *this)
238*9880d681SAndroid Build Coastguard Worker     if (!AS.Forward && AS.aliasesPointer(Ptr, Size, AAInfo, AA))
239*9880d681SAndroid Build Coastguard Worker       return true;
240*9880d681SAndroid Build Coastguard Worker   return false;
241*9880d681SAndroid Build Coastguard Worker }
242*9880d681SAndroid Build Coastguard Worker 
containsUnknown(const Instruction * Inst) const243*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::containsUnknown(const Instruction *Inst) const {
244*9880d681SAndroid Build Coastguard Worker   for (const AliasSet &AS : *this)
245*9880d681SAndroid Build Coastguard Worker     if (!AS.Forward && AS.aliasesUnknownInst(Inst, AA))
246*9880d681SAndroid Build Coastguard Worker       return true;
247*9880d681SAndroid Build Coastguard Worker   return false;
248*9880d681SAndroid Build Coastguard Worker }
249*9880d681SAndroid Build Coastguard Worker 
findAliasSetForUnknownInst(Instruction * Inst)250*9880d681SAndroid Build Coastguard Worker AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) {
251*9880d681SAndroid Build Coastguard Worker   AliasSet *FoundSet = nullptr;
252*9880d681SAndroid Build Coastguard Worker   for (iterator I = begin(), E = end(); I != E;) {
253*9880d681SAndroid Build Coastguard Worker     iterator Cur = I++;
254*9880d681SAndroid Build Coastguard Worker     if (Cur->Forward || !Cur->aliasesUnknownInst(Inst, AA))
255*9880d681SAndroid Build Coastguard Worker       continue;
256*9880d681SAndroid Build Coastguard Worker     if (!FoundSet)            // If this is the first alias set ptr can go into.
257*9880d681SAndroid Build Coastguard Worker       FoundSet = &*Cur;       // Remember it.
258*9880d681SAndroid Build Coastguard Worker     else if (!Cur->Forward)   // Otherwise, we must merge the sets.
259*9880d681SAndroid Build Coastguard Worker       FoundSet->mergeSetIn(*Cur, *this);     // Merge in contents.
260*9880d681SAndroid Build Coastguard Worker   }
261*9880d681SAndroid Build Coastguard Worker   return FoundSet;
262*9880d681SAndroid Build Coastguard Worker }
263*9880d681SAndroid Build Coastguard Worker 
264*9880d681SAndroid Build Coastguard Worker 
265*9880d681SAndroid Build Coastguard Worker 
266*9880d681SAndroid Build Coastguard Worker 
267*9880d681SAndroid Build Coastguard Worker /// getAliasSetForPointer - Return the alias set that the specified pointer
268*9880d681SAndroid Build Coastguard Worker /// lives in.
getAliasSetForPointer(Value * Pointer,uint64_t Size,const AAMDNodes & AAInfo,bool * New)269*9880d681SAndroid Build Coastguard Worker AliasSet &AliasSetTracker::getAliasSetForPointer(Value *Pointer, uint64_t Size,
270*9880d681SAndroid Build Coastguard Worker                                                  const AAMDNodes &AAInfo,
271*9880d681SAndroid Build Coastguard Worker                                                  bool *New) {
272*9880d681SAndroid Build Coastguard Worker   AliasSet::PointerRec &Entry = getEntryFor(Pointer);
273*9880d681SAndroid Build Coastguard Worker 
274*9880d681SAndroid Build Coastguard Worker   // Check to see if the pointer is already known.
275*9880d681SAndroid Build Coastguard Worker   if (Entry.hasAliasSet()) {
276*9880d681SAndroid Build Coastguard Worker     // If the size changed, we may need to merge several alias sets.
277*9880d681SAndroid Build Coastguard Worker     // Note that we can *not* return the result of mergeAliasSetsForPointer
278*9880d681SAndroid Build Coastguard Worker     // due to a quirk of alias analysis behavior. Since alias(undef, undef)
279*9880d681SAndroid Build Coastguard Worker     // is NoAlias, mergeAliasSetsForPointer(undef, ...) will not find the
280*9880d681SAndroid Build Coastguard Worker     // the right set for undef, even if it exists.
281*9880d681SAndroid Build Coastguard Worker     if (Entry.updateSizeAndAAInfo(Size, AAInfo))
282*9880d681SAndroid Build Coastguard Worker       mergeAliasSetsForPointer(Pointer, Size, AAInfo);
283*9880d681SAndroid Build Coastguard Worker     // Return the set!
284*9880d681SAndroid Build Coastguard Worker     return *Entry.getAliasSet(*this)->getForwardedTarget(*this);
285*9880d681SAndroid Build Coastguard Worker   }
286*9880d681SAndroid Build Coastguard Worker 
287*9880d681SAndroid Build Coastguard Worker   if (AliasSet *AS = mergeAliasSetsForPointer(Pointer, Size, AAInfo)) {
288*9880d681SAndroid Build Coastguard Worker     // Add it to the alias set it aliases.
289*9880d681SAndroid Build Coastguard Worker     AS->addPointer(*this, Entry, Size, AAInfo);
290*9880d681SAndroid Build Coastguard Worker     return *AS;
291*9880d681SAndroid Build Coastguard Worker   }
292*9880d681SAndroid Build Coastguard Worker 
293*9880d681SAndroid Build Coastguard Worker   if (New) *New = true;
294*9880d681SAndroid Build Coastguard Worker   // Otherwise create a new alias set to hold the loaded pointer.
295*9880d681SAndroid Build Coastguard Worker   AliasSets.push_back(new AliasSet());
296*9880d681SAndroid Build Coastguard Worker   AliasSets.back().addPointer(*this, Entry, Size, AAInfo);
297*9880d681SAndroid Build Coastguard Worker   return AliasSets.back();
298*9880d681SAndroid Build Coastguard Worker }
299*9880d681SAndroid Build Coastguard Worker 
add(Value * Ptr,uint64_t Size,const AAMDNodes & AAInfo)300*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::add(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo) {
301*9880d681SAndroid Build Coastguard Worker   bool NewPtr;
302*9880d681SAndroid Build Coastguard Worker   addPointer(Ptr, Size, AAInfo, AliasSet::NoAccess, NewPtr);
303*9880d681SAndroid Build Coastguard Worker   return NewPtr;
304*9880d681SAndroid Build Coastguard Worker }
305*9880d681SAndroid Build Coastguard Worker 
306*9880d681SAndroid Build Coastguard Worker 
add(LoadInst * LI)307*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::add(LoadInst *LI) {
308*9880d681SAndroid Build Coastguard Worker   if (isStrongerThanMonotonic(LI->getOrdering())) return addUnknown(LI);
309*9880d681SAndroid Build Coastguard Worker 
310*9880d681SAndroid Build Coastguard Worker   AAMDNodes AAInfo;
311*9880d681SAndroid Build Coastguard Worker   LI->getAAMetadata(AAInfo);
312*9880d681SAndroid Build Coastguard Worker 
313*9880d681SAndroid Build Coastguard Worker   AliasSet::AccessLattice Access = AliasSet::RefAccess;
314*9880d681SAndroid Build Coastguard Worker   bool NewPtr;
315*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = LI->getModule()->getDataLayout();
316*9880d681SAndroid Build Coastguard Worker   AliasSet &AS = addPointer(LI->getOperand(0),
317*9880d681SAndroid Build Coastguard Worker                             DL.getTypeStoreSize(LI->getType()),
318*9880d681SAndroid Build Coastguard Worker                             AAInfo, Access, NewPtr);
319*9880d681SAndroid Build Coastguard Worker   if (LI->isVolatile()) AS.setVolatile();
320*9880d681SAndroid Build Coastguard Worker   return NewPtr;
321*9880d681SAndroid Build Coastguard Worker }
322*9880d681SAndroid Build Coastguard Worker 
add(StoreInst * SI)323*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::add(StoreInst *SI) {
324*9880d681SAndroid Build Coastguard Worker   if (isStrongerThanMonotonic(SI->getOrdering())) return addUnknown(SI);
325*9880d681SAndroid Build Coastguard Worker 
326*9880d681SAndroid Build Coastguard Worker   AAMDNodes AAInfo;
327*9880d681SAndroid Build Coastguard Worker   SI->getAAMetadata(AAInfo);
328*9880d681SAndroid Build Coastguard Worker 
329*9880d681SAndroid Build Coastguard Worker   AliasSet::AccessLattice Access = AliasSet::ModAccess;
330*9880d681SAndroid Build Coastguard Worker   bool NewPtr;
331*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = SI->getModule()->getDataLayout();
332*9880d681SAndroid Build Coastguard Worker   Value *Val = SI->getOperand(0);
333*9880d681SAndroid Build Coastguard Worker   AliasSet &AS = addPointer(SI->getOperand(1),
334*9880d681SAndroid Build Coastguard Worker                             DL.getTypeStoreSize(Val->getType()),
335*9880d681SAndroid Build Coastguard Worker                             AAInfo, Access, NewPtr);
336*9880d681SAndroid Build Coastguard Worker   if (SI->isVolatile()) AS.setVolatile();
337*9880d681SAndroid Build Coastguard Worker   return NewPtr;
338*9880d681SAndroid Build Coastguard Worker }
339*9880d681SAndroid Build Coastguard Worker 
add(VAArgInst * VAAI)340*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::add(VAArgInst *VAAI) {
341*9880d681SAndroid Build Coastguard Worker   AAMDNodes AAInfo;
342*9880d681SAndroid Build Coastguard Worker   VAAI->getAAMetadata(AAInfo);
343*9880d681SAndroid Build Coastguard Worker 
344*9880d681SAndroid Build Coastguard Worker   bool NewPtr;
345*9880d681SAndroid Build Coastguard Worker   addPointer(VAAI->getOperand(0), MemoryLocation::UnknownSize, AAInfo,
346*9880d681SAndroid Build Coastguard Worker              AliasSet::ModRefAccess, NewPtr);
347*9880d681SAndroid Build Coastguard Worker   return NewPtr;
348*9880d681SAndroid Build Coastguard Worker }
349*9880d681SAndroid Build Coastguard Worker 
add(MemSetInst * MSI)350*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::add(MemSetInst *MSI) {
351*9880d681SAndroid Build Coastguard Worker   AAMDNodes AAInfo;
352*9880d681SAndroid Build Coastguard Worker   MSI->getAAMetadata(AAInfo);
353*9880d681SAndroid Build Coastguard Worker 
354*9880d681SAndroid Build Coastguard Worker   bool NewPtr;
355*9880d681SAndroid Build Coastguard Worker   uint64_t Len;
356*9880d681SAndroid Build Coastguard Worker 
357*9880d681SAndroid Build Coastguard Worker   if (ConstantInt *C = dyn_cast<ConstantInt>(MSI->getLength()))
358*9880d681SAndroid Build Coastguard Worker     Len = C->getZExtValue();
359*9880d681SAndroid Build Coastguard Worker   else
360*9880d681SAndroid Build Coastguard Worker     Len = MemoryLocation::UnknownSize;
361*9880d681SAndroid Build Coastguard Worker 
362*9880d681SAndroid Build Coastguard Worker   AliasSet &AS =
363*9880d681SAndroid Build Coastguard Worker       addPointer(MSI->getRawDest(), Len, AAInfo, AliasSet::ModAccess, NewPtr);
364*9880d681SAndroid Build Coastguard Worker   if (MSI->isVolatile())
365*9880d681SAndroid Build Coastguard Worker     AS.setVolatile();
366*9880d681SAndroid Build Coastguard Worker   return NewPtr;
367*9880d681SAndroid Build Coastguard Worker }
368*9880d681SAndroid Build Coastguard Worker 
addUnknown(Instruction * Inst)369*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::addUnknown(Instruction *Inst) {
370*9880d681SAndroid Build Coastguard Worker   if (isa<DbgInfoIntrinsic>(Inst))
371*9880d681SAndroid Build Coastguard Worker     return true; // Ignore DbgInfo Intrinsics.
372*9880d681SAndroid Build Coastguard Worker   if (!Inst->mayReadOrWriteMemory())
373*9880d681SAndroid Build Coastguard Worker     return true; // doesn't alias anything
374*9880d681SAndroid Build Coastguard Worker 
375*9880d681SAndroid Build Coastguard Worker   AliasSet *AS = findAliasSetForUnknownInst(Inst);
376*9880d681SAndroid Build Coastguard Worker   if (AS) {
377*9880d681SAndroid Build Coastguard Worker     AS->addUnknownInst(Inst, AA);
378*9880d681SAndroid Build Coastguard Worker     return false;
379*9880d681SAndroid Build Coastguard Worker   }
380*9880d681SAndroid Build Coastguard Worker   AliasSets.push_back(new AliasSet());
381*9880d681SAndroid Build Coastguard Worker   AS = &AliasSets.back();
382*9880d681SAndroid Build Coastguard Worker   AS->addUnknownInst(Inst, AA);
383*9880d681SAndroid Build Coastguard Worker   return true;
384*9880d681SAndroid Build Coastguard Worker }
385*9880d681SAndroid Build Coastguard Worker 
add(Instruction * I)386*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::add(Instruction *I) {
387*9880d681SAndroid Build Coastguard Worker   // Dispatch to one of the other add methods.
388*9880d681SAndroid Build Coastguard Worker   if (LoadInst *LI = dyn_cast<LoadInst>(I))
389*9880d681SAndroid Build Coastguard Worker     return add(LI);
390*9880d681SAndroid Build Coastguard Worker   if (StoreInst *SI = dyn_cast<StoreInst>(I))
391*9880d681SAndroid Build Coastguard Worker     return add(SI);
392*9880d681SAndroid Build Coastguard Worker   if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
393*9880d681SAndroid Build Coastguard Worker     return add(VAAI);
394*9880d681SAndroid Build Coastguard Worker   if (MemSetInst *MSI = dyn_cast<MemSetInst>(I))
395*9880d681SAndroid Build Coastguard Worker     return add(MSI);
396*9880d681SAndroid Build Coastguard Worker   return addUnknown(I);
397*9880d681SAndroid Build Coastguard Worker   // FIXME: add support of memcpy and memmove.
398*9880d681SAndroid Build Coastguard Worker }
399*9880d681SAndroid Build Coastguard Worker 
add(BasicBlock & BB)400*9880d681SAndroid Build Coastguard Worker void AliasSetTracker::add(BasicBlock &BB) {
401*9880d681SAndroid Build Coastguard Worker   for (auto &I : BB)
402*9880d681SAndroid Build Coastguard Worker     add(&I);
403*9880d681SAndroid Build Coastguard Worker }
404*9880d681SAndroid Build Coastguard Worker 
add(const AliasSetTracker & AST)405*9880d681SAndroid Build Coastguard Worker void AliasSetTracker::add(const AliasSetTracker &AST) {
406*9880d681SAndroid Build Coastguard Worker   assert(&AA == &AST.AA &&
407*9880d681SAndroid Build Coastguard Worker          "Merging AliasSetTracker objects with different Alias Analyses!");
408*9880d681SAndroid Build Coastguard Worker 
409*9880d681SAndroid Build Coastguard Worker   // Loop over all of the alias sets in AST, adding the pointers contained
410*9880d681SAndroid Build Coastguard Worker   // therein into the current alias sets.  This can cause alias sets to be
411*9880d681SAndroid Build Coastguard Worker   // merged together in the current AST.
412*9880d681SAndroid Build Coastguard Worker   for (const AliasSet &AS : AST) {
413*9880d681SAndroid Build Coastguard Worker     if (AS.Forward)
414*9880d681SAndroid Build Coastguard Worker       continue; // Ignore forwarding alias sets
415*9880d681SAndroid Build Coastguard Worker 
416*9880d681SAndroid Build Coastguard Worker     // If there are any call sites in the alias set, add them to this AST.
417*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = AS.UnknownInsts.size(); i != e; ++i)
418*9880d681SAndroid Build Coastguard Worker       add(AS.UnknownInsts[i]);
419*9880d681SAndroid Build Coastguard Worker 
420*9880d681SAndroid Build Coastguard Worker     // Loop over all of the pointers in this alias set.
421*9880d681SAndroid Build Coastguard Worker     bool X;
422*9880d681SAndroid Build Coastguard Worker     for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) {
423*9880d681SAndroid Build Coastguard Worker       AliasSet &NewAS = addPointer(ASI.getPointer(), ASI.getSize(),
424*9880d681SAndroid Build Coastguard Worker                                    ASI.getAAInfo(),
425*9880d681SAndroid Build Coastguard Worker                                    (AliasSet::AccessLattice)AS.Access, X);
426*9880d681SAndroid Build Coastguard Worker       if (AS.isVolatile()) NewAS.setVolatile();
427*9880d681SAndroid Build Coastguard Worker     }
428*9880d681SAndroid Build Coastguard Worker   }
429*9880d681SAndroid Build Coastguard Worker }
430*9880d681SAndroid Build Coastguard Worker 
431*9880d681SAndroid Build Coastguard Worker /// remove - Remove the specified (potentially non-empty) alias set from the
432*9880d681SAndroid Build Coastguard Worker /// tracker.
remove(AliasSet & AS)433*9880d681SAndroid Build Coastguard Worker void AliasSetTracker::remove(AliasSet &AS) {
434*9880d681SAndroid Build Coastguard Worker   // Drop all call sites.
435*9880d681SAndroid Build Coastguard Worker   if (!AS.UnknownInsts.empty())
436*9880d681SAndroid Build Coastguard Worker     AS.dropRef(*this);
437*9880d681SAndroid Build Coastguard Worker   AS.UnknownInsts.clear();
438*9880d681SAndroid Build Coastguard Worker 
439*9880d681SAndroid Build Coastguard Worker   // Clear the alias set.
440*9880d681SAndroid Build Coastguard Worker   unsigned NumRefs = 0;
441*9880d681SAndroid Build Coastguard Worker   while (!AS.empty()) {
442*9880d681SAndroid Build Coastguard Worker     AliasSet::PointerRec *P = AS.PtrList;
443*9880d681SAndroid Build Coastguard Worker 
444*9880d681SAndroid Build Coastguard Worker     Value *ValToRemove = P->getValue();
445*9880d681SAndroid Build Coastguard Worker 
446*9880d681SAndroid Build Coastguard Worker     // Unlink and delete entry from the list of values.
447*9880d681SAndroid Build Coastguard Worker     P->eraseFromList();
448*9880d681SAndroid Build Coastguard Worker 
449*9880d681SAndroid Build Coastguard Worker     // Remember how many references need to be dropped.
450*9880d681SAndroid Build Coastguard Worker     ++NumRefs;
451*9880d681SAndroid Build Coastguard Worker 
452*9880d681SAndroid Build Coastguard Worker     // Finally, remove the entry.
453*9880d681SAndroid Build Coastguard Worker     PointerMap.erase(ValToRemove);
454*9880d681SAndroid Build Coastguard Worker   }
455*9880d681SAndroid Build Coastguard Worker 
456*9880d681SAndroid Build Coastguard Worker   // Stop using the alias set, removing it.
457*9880d681SAndroid Build Coastguard Worker   AS.RefCount -= NumRefs;
458*9880d681SAndroid Build Coastguard Worker   if (AS.RefCount == 0)
459*9880d681SAndroid Build Coastguard Worker     AS.removeFromTracker(*this);
460*9880d681SAndroid Build Coastguard Worker }
461*9880d681SAndroid Build Coastguard Worker 
462*9880d681SAndroid Build Coastguard Worker bool
remove(Value * Ptr,uint64_t Size,const AAMDNodes & AAInfo)463*9880d681SAndroid Build Coastguard Worker AliasSetTracker::remove(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo) {
464*9880d681SAndroid Build Coastguard Worker   AliasSet *AS = mergeAliasSetsForPointer(Ptr, Size, AAInfo);
465*9880d681SAndroid Build Coastguard Worker   if (!AS) return false;
466*9880d681SAndroid Build Coastguard Worker   remove(*AS);
467*9880d681SAndroid Build Coastguard Worker   return true;
468*9880d681SAndroid Build Coastguard Worker }
469*9880d681SAndroid Build Coastguard Worker 
remove(LoadInst * LI)470*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::remove(LoadInst *LI) {
471*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = LI->getModule()->getDataLayout();
472*9880d681SAndroid Build Coastguard Worker   uint64_t Size = DL.getTypeStoreSize(LI->getType());
473*9880d681SAndroid Build Coastguard Worker 
474*9880d681SAndroid Build Coastguard Worker   AAMDNodes AAInfo;
475*9880d681SAndroid Build Coastguard Worker   LI->getAAMetadata(AAInfo);
476*9880d681SAndroid Build Coastguard Worker 
477*9880d681SAndroid Build Coastguard Worker   AliasSet *AS = mergeAliasSetsForPointer(LI->getOperand(0), Size, AAInfo);
478*9880d681SAndroid Build Coastguard Worker   if (!AS) return false;
479*9880d681SAndroid Build Coastguard Worker   remove(*AS);
480*9880d681SAndroid Build Coastguard Worker   return true;
481*9880d681SAndroid Build Coastguard Worker }
482*9880d681SAndroid Build Coastguard Worker 
remove(StoreInst * SI)483*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::remove(StoreInst *SI) {
484*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = SI->getModule()->getDataLayout();
485*9880d681SAndroid Build Coastguard Worker   uint64_t Size = DL.getTypeStoreSize(SI->getOperand(0)->getType());
486*9880d681SAndroid Build Coastguard Worker 
487*9880d681SAndroid Build Coastguard Worker   AAMDNodes AAInfo;
488*9880d681SAndroid Build Coastguard Worker   SI->getAAMetadata(AAInfo);
489*9880d681SAndroid Build Coastguard Worker 
490*9880d681SAndroid Build Coastguard Worker   AliasSet *AS = mergeAliasSetsForPointer(SI->getOperand(1), Size, AAInfo);
491*9880d681SAndroid Build Coastguard Worker   if (!AS) return false;
492*9880d681SAndroid Build Coastguard Worker   remove(*AS);
493*9880d681SAndroid Build Coastguard Worker   return true;
494*9880d681SAndroid Build Coastguard Worker }
495*9880d681SAndroid Build Coastguard Worker 
remove(VAArgInst * VAAI)496*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::remove(VAArgInst *VAAI) {
497*9880d681SAndroid Build Coastguard Worker   AAMDNodes AAInfo;
498*9880d681SAndroid Build Coastguard Worker   VAAI->getAAMetadata(AAInfo);
499*9880d681SAndroid Build Coastguard Worker 
500*9880d681SAndroid Build Coastguard Worker   AliasSet *AS = mergeAliasSetsForPointer(VAAI->getOperand(0),
501*9880d681SAndroid Build Coastguard Worker                                           MemoryLocation::UnknownSize, AAInfo);
502*9880d681SAndroid Build Coastguard Worker   if (!AS) return false;
503*9880d681SAndroid Build Coastguard Worker   remove(*AS);
504*9880d681SAndroid Build Coastguard Worker   return true;
505*9880d681SAndroid Build Coastguard Worker }
506*9880d681SAndroid Build Coastguard Worker 
remove(MemSetInst * MSI)507*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::remove(MemSetInst *MSI) {
508*9880d681SAndroid Build Coastguard Worker   AAMDNodes AAInfo;
509*9880d681SAndroid Build Coastguard Worker   MSI->getAAMetadata(AAInfo);
510*9880d681SAndroid Build Coastguard Worker   uint64_t Len;
511*9880d681SAndroid Build Coastguard Worker 
512*9880d681SAndroid Build Coastguard Worker   if (ConstantInt *C = dyn_cast<ConstantInt>(MSI->getLength()))
513*9880d681SAndroid Build Coastguard Worker     Len = C->getZExtValue();
514*9880d681SAndroid Build Coastguard Worker   else
515*9880d681SAndroid Build Coastguard Worker     Len = MemoryLocation::UnknownSize;
516*9880d681SAndroid Build Coastguard Worker 
517*9880d681SAndroid Build Coastguard Worker   AliasSet *AS = mergeAliasSetsForPointer(MSI->getRawDest(), Len, AAInfo);
518*9880d681SAndroid Build Coastguard Worker   if (!AS)
519*9880d681SAndroid Build Coastguard Worker     return false;
520*9880d681SAndroid Build Coastguard Worker   remove(*AS);
521*9880d681SAndroid Build Coastguard Worker   return true;
522*9880d681SAndroid Build Coastguard Worker }
523*9880d681SAndroid Build Coastguard Worker 
removeUnknown(Instruction * I)524*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::removeUnknown(Instruction *I) {
525*9880d681SAndroid Build Coastguard Worker   if (!I->mayReadOrWriteMemory())
526*9880d681SAndroid Build Coastguard Worker     return false; // doesn't alias anything
527*9880d681SAndroid Build Coastguard Worker 
528*9880d681SAndroid Build Coastguard Worker   AliasSet *AS = findAliasSetForUnknownInst(I);
529*9880d681SAndroid Build Coastguard Worker   if (!AS) return false;
530*9880d681SAndroid Build Coastguard Worker   remove(*AS);
531*9880d681SAndroid Build Coastguard Worker   return true;
532*9880d681SAndroid Build Coastguard Worker }
533*9880d681SAndroid Build Coastguard Worker 
remove(Instruction * I)534*9880d681SAndroid Build Coastguard Worker bool AliasSetTracker::remove(Instruction *I) {
535*9880d681SAndroid Build Coastguard Worker   // Dispatch to one of the other remove methods...
536*9880d681SAndroid Build Coastguard Worker   if (LoadInst *LI = dyn_cast<LoadInst>(I))
537*9880d681SAndroid Build Coastguard Worker     return remove(LI);
538*9880d681SAndroid Build Coastguard Worker   if (StoreInst *SI = dyn_cast<StoreInst>(I))
539*9880d681SAndroid Build Coastguard Worker     return remove(SI);
540*9880d681SAndroid Build Coastguard Worker   if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
541*9880d681SAndroid Build Coastguard Worker     return remove(VAAI);
542*9880d681SAndroid Build Coastguard Worker   if (MemSetInst *MSI = dyn_cast<MemSetInst>(I))
543*9880d681SAndroid Build Coastguard Worker     return remove(MSI);
544*9880d681SAndroid Build Coastguard Worker   return removeUnknown(I);
545*9880d681SAndroid Build Coastguard Worker   // FIXME: add support of memcpy and memmove.
546*9880d681SAndroid Build Coastguard Worker }
547*9880d681SAndroid Build Coastguard Worker 
548*9880d681SAndroid Build Coastguard Worker 
549*9880d681SAndroid Build Coastguard Worker // deleteValue method - This method is used to remove a pointer value from the
550*9880d681SAndroid Build Coastguard Worker // AliasSetTracker entirely.  It should be used when an instruction is deleted
551*9880d681SAndroid Build Coastguard Worker // from the program to update the AST.  If you don't use this, you would have
552*9880d681SAndroid Build Coastguard Worker // dangling pointers to deleted instructions.
553*9880d681SAndroid Build Coastguard Worker //
deleteValue(Value * PtrVal)554*9880d681SAndroid Build Coastguard Worker void AliasSetTracker::deleteValue(Value *PtrVal) {
555*9880d681SAndroid Build Coastguard Worker   // If this is a call instruction, remove the callsite from the appropriate
556*9880d681SAndroid Build Coastguard Worker   // AliasSet (if present).
557*9880d681SAndroid Build Coastguard Worker   if (Instruction *Inst = dyn_cast<Instruction>(PtrVal)) {
558*9880d681SAndroid Build Coastguard Worker     if (Inst->mayReadOrWriteMemory()) {
559*9880d681SAndroid Build Coastguard Worker       // Scan all the alias sets to see if this call site is contained.
560*9880d681SAndroid Build Coastguard Worker       for (iterator I = begin(), E = end(); I != E;) {
561*9880d681SAndroid Build Coastguard Worker         iterator Cur = I++;
562*9880d681SAndroid Build Coastguard Worker         if (!Cur->Forward)
563*9880d681SAndroid Build Coastguard Worker           Cur->removeUnknownInst(*this, Inst);
564*9880d681SAndroid Build Coastguard Worker       }
565*9880d681SAndroid Build Coastguard Worker     }
566*9880d681SAndroid Build Coastguard Worker   }
567*9880d681SAndroid Build Coastguard Worker 
568*9880d681SAndroid Build Coastguard Worker   // First, look up the PointerRec for this pointer.
569*9880d681SAndroid Build Coastguard Worker   PointerMapType::iterator I = PointerMap.find_as(PtrVal);
570*9880d681SAndroid Build Coastguard Worker   if (I == PointerMap.end()) return;  // Noop
571*9880d681SAndroid Build Coastguard Worker 
572*9880d681SAndroid Build Coastguard Worker   // If we found one, remove the pointer from the alias set it is in.
573*9880d681SAndroid Build Coastguard Worker   AliasSet::PointerRec *PtrValEnt = I->second;
574*9880d681SAndroid Build Coastguard Worker   AliasSet *AS = PtrValEnt->getAliasSet(*this);
575*9880d681SAndroid Build Coastguard Worker 
576*9880d681SAndroid Build Coastguard Worker   // Unlink and delete from the list of values.
577*9880d681SAndroid Build Coastguard Worker   PtrValEnt->eraseFromList();
578*9880d681SAndroid Build Coastguard Worker 
579*9880d681SAndroid Build Coastguard Worker   // Stop using the alias set.
580*9880d681SAndroid Build Coastguard Worker   AS->dropRef(*this);
581*9880d681SAndroid Build Coastguard Worker 
582*9880d681SAndroid Build Coastguard Worker   PointerMap.erase(I);
583*9880d681SAndroid Build Coastguard Worker }
584*9880d681SAndroid Build Coastguard Worker 
585*9880d681SAndroid Build Coastguard Worker // copyValue - This method should be used whenever a preexisting value in the
586*9880d681SAndroid Build Coastguard Worker // program is copied or cloned, introducing a new value.  Note that it is ok for
587*9880d681SAndroid Build Coastguard Worker // clients that use this method to introduce the same value multiple times: if
588*9880d681SAndroid Build Coastguard Worker // the tracker already knows about a value, it will ignore the request.
589*9880d681SAndroid Build Coastguard Worker //
copyValue(Value * From,Value * To)590*9880d681SAndroid Build Coastguard Worker void AliasSetTracker::copyValue(Value *From, Value *To) {
591*9880d681SAndroid Build Coastguard Worker   // First, look up the PointerRec for this pointer.
592*9880d681SAndroid Build Coastguard Worker   PointerMapType::iterator I = PointerMap.find_as(From);
593*9880d681SAndroid Build Coastguard Worker   if (I == PointerMap.end())
594*9880d681SAndroid Build Coastguard Worker     return;  // Noop
595*9880d681SAndroid Build Coastguard Worker   assert(I->second->hasAliasSet() && "Dead entry?");
596*9880d681SAndroid Build Coastguard Worker 
597*9880d681SAndroid Build Coastguard Worker   AliasSet::PointerRec &Entry = getEntryFor(To);
598*9880d681SAndroid Build Coastguard Worker   if (Entry.hasAliasSet()) return;    // Already in the tracker!
599*9880d681SAndroid Build Coastguard Worker 
600*9880d681SAndroid Build Coastguard Worker   // Add it to the alias set it aliases...
601*9880d681SAndroid Build Coastguard Worker   I = PointerMap.find_as(From);
602*9880d681SAndroid Build Coastguard Worker   AliasSet *AS = I->second->getAliasSet(*this);
603*9880d681SAndroid Build Coastguard Worker   AS->addPointer(*this, Entry, I->second->getSize(),
604*9880d681SAndroid Build Coastguard Worker                  I->second->getAAInfo(),
605*9880d681SAndroid Build Coastguard Worker                  true);
606*9880d681SAndroid Build Coastguard Worker }
607*9880d681SAndroid Build Coastguard Worker 
608*9880d681SAndroid Build Coastguard Worker 
609*9880d681SAndroid Build Coastguard Worker 
610*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
611*9880d681SAndroid Build Coastguard Worker //               AliasSet/AliasSetTracker Printing Support
612*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
613*9880d681SAndroid Build Coastguard Worker 
print(raw_ostream & OS) const614*9880d681SAndroid Build Coastguard Worker void AliasSet::print(raw_ostream &OS) const {
615*9880d681SAndroid Build Coastguard Worker   OS << "  AliasSet[" << (const void*)this << ", " << RefCount << "] ";
616*9880d681SAndroid Build Coastguard Worker   OS << (Alias == SetMustAlias ? "must" : "may") << " alias, ";
617*9880d681SAndroid Build Coastguard Worker   switch (Access) {
618*9880d681SAndroid Build Coastguard Worker   case NoAccess:     OS << "No access "; break;
619*9880d681SAndroid Build Coastguard Worker   case RefAccess:    OS << "Ref       "; break;
620*9880d681SAndroid Build Coastguard Worker   case ModAccess:    OS << "Mod       "; break;
621*9880d681SAndroid Build Coastguard Worker   case ModRefAccess: OS << "Mod/Ref   "; break;
622*9880d681SAndroid Build Coastguard Worker   default: llvm_unreachable("Bad value for Access!");
623*9880d681SAndroid Build Coastguard Worker   }
624*9880d681SAndroid Build Coastguard Worker   if (isVolatile()) OS << "[volatile] ";
625*9880d681SAndroid Build Coastguard Worker   if (Forward)
626*9880d681SAndroid Build Coastguard Worker     OS << " forwarding to " << (void*)Forward;
627*9880d681SAndroid Build Coastguard Worker 
628*9880d681SAndroid Build Coastguard Worker 
629*9880d681SAndroid Build Coastguard Worker   if (!empty()) {
630*9880d681SAndroid Build Coastguard Worker     OS << "Pointers: ";
631*9880d681SAndroid Build Coastguard Worker     for (iterator I = begin(), E = end(); I != E; ++I) {
632*9880d681SAndroid Build Coastguard Worker       if (I != begin()) OS << ", ";
633*9880d681SAndroid Build Coastguard Worker       I.getPointer()->printAsOperand(OS << "(");
634*9880d681SAndroid Build Coastguard Worker       OS << ", " << I.getSize() << ")";
635*9880d681SAndroid Build Coastguard Worker     }
636*9880d681SAndroid Build Coastguard Worker   }
637*9880d681SAndroid Build Coastguard Worker   if (!UnknownInsts.empty()) {
638*9880d681SAndroid Build Coastguard Worker     OS << "\n    " << UnknownInsts.size() << " Unknown instructions: ";
639*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
640*9880d681SAndroid Build Coastguard Worker       if (i) OS << ", ";
641*9880d681SAndroid Build Coastguard Worker       UnknownInsts[i]->printAsOperand(OS);
642*9880d681SAndroid Build Coastguard Worker     }
643*9880d681SAndroid Build Coastguard Worker   }
644*9880d681SAndroid Build Coastguard Worker   OS << "\n";
645*9880d681SAndroid Build Coastguard Worker }
646*9880d681SAndroid Build Coastguard Worker 
print(raw_ostream & OS) const647*9880d681SAndroid Build Coastguard Worker void AliasSetTracker::print(raw_ostream &OS) const {
648*9880d681SAndroid Build Coastguard Worker   OS << "Alias Set Tracker: " << AliasSets.size() << " alias sets for "
649*9880d681SAndroid Build Coastguard Worker      << PointerMap.size() << " pointer values.\n";
650*9880d681SAndroid Build Coastguard Worker   for (const AliasSet &AS : *this)
651*9880d681SAndroid Build Coastguard Worker     AS.print(OS);
652*9880d681SAndroid Build Coastguard Worker   OS << "\n";
653*9880d681SAndroid Build Coastguard Worker }
654*9880d681SAndroid Build Coastguard Worker 
655*9880d681SAndroid Build Coastguard Worker #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const656*9880d681SAndroid Build Coastguard Worker LLVM_DUMP_METHOD void AliasSet::dump() const { print(dbgs()); }
dump() const657*9880d681SAndroid Build Coastguard Worker LLVM_DUMP_METHOD void AliasSetTracker::dump() const { print(dbgs()); }
658*9880d681SAndroid Build Coastguard Worker #endif
659*9880d681SAndroid Build Coastguard Worker 
660*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
661*9880d681SAndroid Build Coastguard Worker //                     ASTCallbackVH Class Implementation
662*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
663*9880d681SAndroid Build Coastguard Worker 
deleted()664*9880d681SAndroid Build Coastguard Worker void AliasSetTracker::ASTCallbackVH::deleted() {
665*9880d681SAndroid Build Coastguard Worker   assert(AST && "ASTCallbackVH called with a null AliasSetTracker!");
666*9880d681SAndroid Build Coastguard Worker   AST->deleteValue(getValPtr());
667*9880d681SAndroid Build Coastguard Worker   // this now dangles!
668*9880d681SAndroid Build Coastguard Worker }
669*9880d681SAndroid Build Coastguard Worker 
allUsesReplacedWith(Value * V)670*9880d681SAndroid Build Coastguard Worker void AliasSetTracker::ASTCallbackVH::allUsesReplacedWith(Value *V) {
671*9880d681SAndroid Build Coastguard Worker   AST->copyValue(getValPtr(), V);
672*9880d681SAndroid Build Coastguard Worker }
673*9880d681SAndroid Build Coastguard Worker 
ASTCallbackVH(Value * V,AliasSetTracker * ast)674*9880d681SAndroid Build Coastguard Worker AliasSetTracker::ASTCallbackVH::ASTCallbackVH(Value *V, AliasSetTracker *ast)
675*9880d681SAndroid Build Coastguard Worker   : CallbackVH(V), AST(ast) {}
676*9880d681SAndroid Build Coastguard Worker 
677*9880d681SAndroid Build Coastguard Worker AliasSetTracker::ASTCallbackVH &
operator =(Value * V)678*9880d681SAndroid Build Coastguard Worker AliasSetTracker::ASTCallbackVH::operator=(Value *V) {
679*9880d681SAndroid Build Coastguard Worker   return *this = ASTCallbackVH(V, AST);
680*9880d681SAndroid Build Coastguard Worker }
681*9880d681SAndroid Build Coastguard Worker 
682*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
683*9880d681SAndroid Build Coastguard Worker //                            AliasSetPrinter Pass
684*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
685*9880d681SAndroid Build Coastguard Worker 
686*9880d681SAndroid Build Coastguard Worker namespace {
687*9880d681SAndroid Build Coastguard Worker   class AliasSetPrinter : public FunctionPass {
688*9880d681SAndroid Build Coastguard Worker     AliasSetTracker *Tracker;
689*9880d681SAndroid Build Coastguard Worker   public:
690*9880d681SAndroid Build Coastguard Worker     static char ID; // Pass identification, replacement for typeid
AliasSetPrinter()691*9880d681SAndroid Build Coastguard Worker     AliasSetPrinter() : FunctionPass(ID) {
692*9880d681SAndroid Build Coastguard Worker       initializeAliasSetPrinterPass(*PassRegistry::getPassRegistry());
693*9880d681SAndroid Build Coastguard Worker     }
694*9880d681SAndroid Build Coastguard Worker 
getAnalysisUsage(AnalysisUsage & AU) const695*9880d681SAndroid Build Coastguard Worker     void getAnalysisUsage(AnalysisUsage &AU) const override {
696*9880d681SAndroid Build Coastguard Worker       AU.setPreservesAll();
697*9880d681SAndroid Build Coastguard Worker       AU.addRequired<AAResultsWrapperPass>();
698*9880d681SAndroid Build Coastguard Worker     }
699*9880d681SAndroid Build Coastguard Worker 
runOnFunction(Function & F)700*9880d681SAndroid Build Coastguard Worker     bool runOnFunction(Function &F) override {
701*9880d681SAndroid Build Coastguard Worker       auto &AAWP = getAnalysis<AAResultsWrapperPass>();
702*9880d681SAndroid Build Coastguard Worker       Tracker = new AliasSetTracker(AAWP.getAAResults());
703*9880d681SAndroid Build Coastguard Worker 
704*9880d681SAndroid Build Coastguard Worker       for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
705*9880d681SAndroid Build Coastguard Worker         Tracker->add(&*I);
706*9880d681SAndroid Build Coastguard Worker       Tracker->print(errs());
707*9880d681SAndroid Build Coastguard Worker       delete Tracker;
708*9880d681SAndroid Build Coastguard Worker       return false;
709*9880d681SAndroid Build Coastguard Worker     }
710*9880d681SAndroid Build Coastguard Worker   };
711*9880d681SAndroid Build Coastguard Worker }
712*9880d681SAndroid Build Coastguard Worker 
713*9880d681SAndroid Build Coastguard Worker char AliasSetPrinter::ID = 0;
714*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(AliasSetPrinter, "print-alias-sets",
715*9880d681SAndroid Build Coastguard Worker                 "Alias Set Printer", false, true)
716*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
717*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(AliasSetPrinter, "print-alias-sets",
718*9880d681SAndroid Build Coastguard Worker                 "Alias Set Printer", false, true)
719