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