LLVM  mainline
AliasSetTracker.cpp
Go to the documentation of this file.
00001 //===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the AliasSetTracker and AliasSet classes.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/Analysis/AliasSetTracker.h"
00015 #include "llvm/Analysis/AliasAnalysis.h"
00016 #include "llvm/IR/DataLayout.h"
00017 #include "llvm/IR/InstIterator.h"
00018 #include "llvm/IR/Instructions.h"
00019 #include "llvm/IR/IntrinsicInst.h"
00020 #include "llvm/IR/Module.h"
00021 #include "llvm/IR/LLVMContext.h"
00022 #include "llvm/IR/Type.h"
00023 #include "llvm/Pass.h"
00024 #include "llvm/Support/Debug.h"
00025 #include "llvm/Support/ErrorHandling.h"
00026 #include "llvm/Support/raw_ostream.h"
00027 using namespace llvm;
00028 
00029 /// mergeSetIn - Merge the specified alias set into this alias set.
00030 ///
00031 void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
00032   assert(!AS.Forward && "Alias set is already forwarding!");
00033   assert(!Forward && "This set is a forwarding set!!");
00034 
00035   // Update the alias and access types of this set...
00036   Access |= AS.Access;
00037   Alias  |= AS.Alias;
00038   Volatile |= AS.Volatile;
00039 
00040   if (Alias == SetMustAlias) {
00041     // Check that these two merged sets really are must aliases.  Since both
00042     // used to be must-alias sets, we can just check any pointer from each set
00043     // for aliasing.
00044     AliasAnalysis &AA = AST.getAliasAnalysis();
00045     PointerRec *L = getSomePointer();
00046     PointerRec *R = AS.getSomePointer();
00047 
00048     // If the pointers are not a must-alias pair, this set becomes a may alias.
00049     if (AA.alias(MemoryLocation(L->getValue(), L->getSize(), L->getAAInfo()),
00050                  MemoryLocation(R->getValue(), R->getSize(), R->getAAInfo())) !=
00051         MustAlias)
00052       Alias = SetMayAlias;
00053   }
00054 
00055   bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
00056   if (UnknownInsts.empty()) {            // Merge call sites...
00057     if (ASHadUnknownInsts) {
00058       std::swap(UnknownInsts, AS.UnknownInsts);
00059       addRef();
00060     }
00061   } else if (ASHadUnknownInsts) {
00062     UnknownInsts.insert(UnknownInsts.end(), AS.UnknownInsts.begin(), AS.UnknownInsts.end());
00063     AS.UnknownInsts.clear();
00064   }
00065 
00066   AS.Forward = this;  // Forward across AS now...
00067   addRef();           // AS is now pointing to us...
00068 
00069   // Merge the list of constituent pointers...
00070   if (AS.PtrList) {
00071     *PtrListEnd = AS.PtrList;
00072     AS.PtrList->setPrevInList(PtrListEnd);
00073     PtrListEnd = AS.PtrListEnd;
00074 
00075     AS.PtrList = nullptr;
00076     AS.PtrListEnd = &AS.PtrList;
00077     assert(*AS.PtrListEnd == nullptr && "End of list is not null?");
00078   }
00079   if (ASHadUnknownInsts)
00080     AS.dropRef(AST);
00081 }
00082 
00083 void AliasSetTracker::removeAliasSet(AliasSet *AS) {
00084   if (AliasSet *Fwd = AS->Forward) {
00085     Fwd->dropRef(*this);
00086     AS->Forward = nullptr;
00087   }
00088   AliasSets.erase(AS);
00089 }
00090 
00091 void AliasSet::removeFromTracker(AliasSetTracker &AST) {
00092   assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!");
00093   AST.removeAliasSet(this);
00094 }
00095 
00096 void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
00097                           uint64_t Size, const AAMDNodes &AAInfo,
00098                           bool KnownMustAlias) {
00099   assert(!Entry.hasAliasSet() && "Entry already in set!");
00100 
00101   // Check to see if we have to downgrade to _may_ alias.
00102   if (isMustAlias() && !KnownMustAlias)
00103     if (PointerRec *P = getSomePointer()) {
00104       AliasAnalysis &AA = AST.getAliasAnalysis();
00105       AliasResult Result =
00106           AA.alias(MemoryLocation(P->getValue(), P->getSize(), P->getAAInfo()),
00107                    MemoryLocation(Entry.getValue(), Size, AAInfo));
00108       if (Result != MustAlias)
00109         Alias = SetMayAlias;
00110       else                  // First entry of must alias must have maximum size!
00111         P->updateSizeAndAAInfo(Size, AAInfo);
00112       assert(Result != NoAlias && "Cannot be part of must set!");
00113     }
00114 
00115   Entry.setAliasSet(this);
00116   Entry.updateSizeAndAAInfo(Size, AAInfo);
00117 
00118   // Add it to the end of the list...
00119   assert(*PtrListEnd == nullptr && "End of list is not null?");
00120   *PtrListEnd = &Entry;
00121   PtrListEnd = Entry.setPrevInList(PtrListEnd);
00122   assert(*PtrListEnd == nullptr && "End of list is not null?");
00123   addRef();               // Entry points to alias set.
00124 }
00125 
00126 void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) {
00127   if (UnknownInsts.empty())
00128     addRef();
00129   UnknownInsts.emplace_back(I);
00130 
00131   if (!I->mayWriteToMemory()) {
00132     Alias = SetMayAlias;
00133     Access |= RefAccess;
00134     return;
00135   }
00136 
00137   // FIXME: This should use mod/ref information to make this not suck so bad
00138   Alias = SetMayAlias;
00139   Access = ModRefAccess;
00140 }
00141 
00142 /// aliasesPointer - Return true if the specified pointer "may" (or must)
00143 /// alias one of the members in the set.
00144 ///
00145 bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size,
00146                               const AAMDNodes &AAInfo,
00147                               AliasAnalysis &AA) const {
00148   if (Alias == SetMustAlias) {
00149     assert(UnknownInsts.empty() && "Illegal must alias set!");
00150 
00151     // If this is a set of MustAliases, only check to see if the pointer aliases
00152     // SOME value in the set.
00153     PointerRec *SomePtr = getSomePointer();
00154     assert(SomePtr && "Empty must-alias set??");
00155     return AA.alias(MemoryLocation(SomePtr->getValue(), SomePtr->getSize(),
00156                                    SomePtr->getAAInfo()),
00157                     MemoryLocation(Ptr, Size, AAInfo));
00158   }
00159 
00160   // If this is a may-alias set, we have to check all of the pointers in the set
00161   // to be sure it doesn't alias the set...
00162   for (iterator I = begin(), E = end(); I != E; ++I)
00163     if (AA.alias(MemoryLocation(Ptr, Size, AAInfo),
00164                  MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo())))
00165       return true;
00166 
00167   // Check the unknown instructions...
00168   if (!UnknownInsts.empty()) {
00169     for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i)
00170       if (AA.getModRefInfo(UnknownInsts[i],
00171                            MemoryLocation(Ptr, Size, AAInfo)) != MRI_NoModRef)
00172         return true;
00173   }
00174 
00175   return false;
00176 }
00177 
00178 bool AliasSet::aliasesUnknownInst(const Instruction *Inst,
00179                                   AliasAnalysis &AA) const {
00180   if (!Inst->mayReadOrWriteMemory())
00181     return false;
00182 
00183   for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
00184     ImmutableCallSite C1(getUnknownInst(i)), C2(Inst);
00185     if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != MRI_NoModRef ||
00186         AA.getModRefInfo(C2, C1) != MRI_NoModRef)
00187       return true;
00188   }
00189 
00190   for (iterator I = begin(), E = end(); I != E; ++I)
00191     if (AA.getModRefInfo(Inst, MemoryLocation(I.getPointer(), I.getSize(),
00192                                               I.getAAInfo())) != MRI_NoModRef)
00193       return true;
00194 
00195   return false;
00196 }
00197 
00198 void AliasSetTracker::clear() {
00199   // Delete all the PointerRec entries.
00200   for (PointerMapType::iterator I = PointerMap.begin(), E = PointerMap.end();
00201        I != E; ++I)
00202     I->second->eraseFromList();
00203   
00204   PointerMap.clear();
00205   
00206   // The alias sets should all be clear now.
00207   AliasSets.clear();
00208 }
00209 
00210 
00211 /// findAliasSetForPointer - Given a pointer, find the one alias set to put the
00212 /// instruction referring to the pointer into.  If there are multiple alias sets
00213 /// that may alias the pointer, merge them together and return the unified set.
00214 ///
00215 AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr,
00216                                                   uint64_t Size,
00217                                                   const AAMDNodes &AAInfo) {
00218   AliasSet *FoundSet = nullptr;
00219   for (iterator I = begin(), E = end(); I != E;) {
00220     iterator Cur = I++;
00221     if (Cur->Forward || !Cur->aliasesPointer(Ptr, Size, AAInfo, AA)) continue;
00222     
00223     if (!FoundSet) {      // If this is the first alias set ptr can go into.
00224       FoundSet = &*Cur;   // Remember it.
00225     } else {              // Otherwise, we must merge the sets.
00226       FoundSet->mergeSetIn(*Cur, *this);     // Merge in contents.
00227     }
00228   }
00229 
00230   return FoundSet;
00231 }
00232 
00233 /// containsPointer - Return true if the specified location is represented by
00234 /// this alias set, false otherwise.  This does not modify the AST object or
00235 /// alias sets.
00236 bool AliasSetTracker::containsPointer(const Value *Ptr, uint64_t Size,
00237                                       const AAMDNodes &AAInfo) const {
00238   for (const_iterator I = begin(), E = end(); I != E; ++I)
00239     if (!I->Forward && I->aliasesPointer(Ptr, Size, AAInfo, AA))
00240       return true;
00241   return false;
00242 }
00243 
00244 bool AliasSetTracker::containsUnknown(const Instruction *Inst) const {
00245   for (const_iterator I = begin(), E = end(); I != E; ++I)
00246     if (!I->Forward && I->aliasesUnknownInst(Inst, AA))
00247       return true;
00248   return false;
00249 }
00250 
00251 AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) {
00252   AliasSet *FoundSet = nullptr;
00253   for (iterator I = begin(), E = end(); I != E;) {
00254     iterator Cur = I++;
00255     if (Cur->Forward || !Cur->aliasesUnknownInst(Inst, AA))
00256       continue;
00257     if (!FoundSet)            // If this is the first alias set ptr can go into.
00258       FoundSet = &*Cur;       // Remember it.
00259     else if (!Cur->Forward)   // Otherwise, we must merge the sets.
00260       FoundSet->mergeSetIn(*Cur, *this);     // Merge in contents.
00261   }
00262   return FoundSet;
00263 }
00264 
00265 
00266 
00267 
00268 /// getAliasSetForPointer - Return the alias set that the specified pointer
00269 /// lives in.
00270 AliasSet &AliasSetTracker::getAliasSetForPointer(Value *Pointer, uint64_t Size,
00271                                                  const AAMDNodes &AAInfo,
00272                                                  bool *New) {
00273   AliasSet::PointerRec &Entry = getEntryFor(Pointer);
00274 
00275   // Check to see if the pointer is already known.
00276   if (Entry.hasAliasSet()) {
00277     Entry.updateSizeAndAAInfo(Size, AAInfo);
00278     // Return the set!
00279     return *Entry.getAliasSet(*this)->getForwardedTarget(*this);
00280   }
00281   
00282   if (AliasSet *AS = findAliasSetForPointer(Pointer, Size, AAInfo)) {
00283     // Add it to the alias set it aliases.
00284     AS->addPointer(*this, Entry, Size, AAInfo);
00285     return *AS;
00286   }
00287   
00288   if (New) *New = true;
00289   // Otherwise create a new alias set to hold the loaded pointer.
00290   AliasSets.push_back(new AliasSet());
00291   AliasSets.back().addPointer(*this, Entry, Size, AAInfo);
00292   return AliasSets.back();
00293 }
00294 
00295 bool AliasSetTracker::add(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo) {
00296   bool NewPtr;
00297   addPointer(Ptr, Size, AAInfo, AliasSet::NoAccess, NewPtr);
00298   return NewPtr;
00299 }
00300 
00301 
00302 bool AliasSetTracker::add(LoadInst *LI) {
00303   if (LI->getOrdering() > Monotonic) return addUnknown(LI);
00304 
00305   AAMDNodes AAInfo;
00306   LI->getAAMetadata(AAInfo);
00307 
00308   AliasSet::AccessLattice Access = AliasSet::RefAccess;
00309   bool NewPtr;
00310   const DataLayout &DL = LI->getModule()->getDataLayout();
00311   AliasSet &AS = addPointer(LI->getOperand(0),
00312                             DL.getTypeStoreSize(LI->getType()),
00313                             AAInfo, Access, NewPtr);
00314   if (LI->isVolatile()) AS.setVolatile();
00315   return NewPtr;
00316 }
00317 
00318 bool AliasSetTracker::add(StoreInst *SI) {
00319   if (SI->getOrdering() > Monotonic) return addUnknown(SI);
00320 
00321   AAMDNodes AAInfo;
00322   SI->getAAMetadata(AAInfo);
00323 
00324   AliasSet::AccessLattice Access = AliasSet::ModAccess;
00325   bool NewPtr;
00326   const DataLayout &DL = SI->getModule()->getDataLayout();
00327   Value *Val = SI->getOperand(0);
00328   AliasSet &AS = addPointer(SI->getOperand(1),
00329                             DL.getTypeStoreSize(Val->getType()),
00330                             AAInfo, Access, NewPtr);
00331   if (SI->isVolatile()) AS.setVolatile();
00332   return NewPtr;
00333 }
00334 
00335 bool AliasSetTracker::add(VAArgInst *VAAI) {
00336   AAMDNodes AAInfo;
00337   VAAI->getAAMetadata(AAInfo);
00338 
00339   bool NewPtr;
00340   addPointer(VAAI->getOperand(0), MemoryLocation::UnknownSize, AAInfo,
00341              AliasSet::ModRefAccess, NewPtr);
00342   return NewPtr;
00343 }
00344 
00345 
00346 bool AliasSetTracker::addUnknown(Instruction *Inst) {
00347   if (isa<DbgInfoIntrinsic>(Inst)) 
00348     return true; // Ignore DbgInfo Intrinsics.
00349   if (!Inst->mayReadOrWriteMemory())
00350     return true; // doesn't alias anything
00351 
00352   AliasSet *AS = findAliasSetForUnknownInst(Inst);
00353   if (AS) {
00354     AS->addUnknownInst(Inst, AA);
00355     return false;
00356   }
00357   AliasSets.push_back(new AliasSet());
00358   AS = &AliasSets.back();
00359   AS->addUnknownInst(Inst, AA);
00360   return true;
00361 }
00362 
00363 bool AliasSetTracker::add(Instruction *I) {
00364   // Dispatch to one of the other add methods.
00365   if (LoadInst *LI = dyn_cast<LoadInst>(I))
00366     return add(LI);
00367   if (StoreInst *SI = dyn_cast<StoreInst>(I))
00368     return add(SI);
00369   if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
00370     return add(VAAI);
00371   return addUnknown(I);
00372 }
00373 
00374 void AliasSetTracker::add(BasicBlock &BB) {
00375   for (auto &I : BB)
00376     add(&I);
00377 }
00378 
00379 void AliasSetTracker::add(const AliasSetTracker &AST) {
00380   assert(&AA == &AST.AA &&
00381          "Merging AliasSetTracker objects with different Alias Analyses!");
00382 
00383   // Loop over all of the alias sets in AST, adding the pointers contained
00384   // therein into the current alias sets.  This can cause alias sets to be
00385   // merged together in the current AST.
00386   for (const_iterator I = AST.begin(), E = AST.end(); I != E; ++I) {
00387     if (I->Forward) continue;   // Ignore forwarding alias sets
00388     
00389     AliasSet &AS = const_cast<AliasSet&>(*I);
00390 
00391     // If there are any call sites in the alias set, add them to this AST.
00392     for (unsigned i = 0, e = AS.UnknownInsts.size(); i != e; ++i)
00393       add(AS.UnknownInsts[i]);
00394 
00395     // Loop over all of the pointers in this alias set.
00396     bool X;
00397     for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) {
00398       AliasSet &NewAS = addPointer(ASI.getPointer(), ASI.getSize(),
00399                                    ASI.getAAInfo(),
00400                                    (AliasSet::AccessLattice)AS.Access, X);
00401       if (AS.isVolatile()) NewAS.setVolatile();
00402     }
00403   }
00404 }
00405 
00406 /// remove - Remove the specified (potentially non-empty) alias set from the
00407 /// tracker.
00408 void AliasSetTracker::remove(AliasSet &AS) {
00409   // Drop all call sites.
00410   if (!AS.UnknownInsts.empty())
00411     AS.dropRef(*this);
00412   AS.UnknownInsts.clear();
00413   
00414   // Clear the alias set.
00415   unsigned NumRefs = 0;
00416   while (!AS.empty()) {
00417     AliasSet::PointerRec *P = AS.PtrList;
00418 
00419     Value *ValToRemove = P->getValue();
00420     
00421     // Unlink and delete entry from the list of values.
00422     P->eraseFromList();
00423     
00424     // Remember how many references need to be dropped.
00425     ++NumRefs;
00426 
00427     // Finally, remove the entry.
00428     PointerMap.erase(ValToRemove);
00429   }
00430   
00431   // Stop using the alias set, removing it.
00432   AS.RefCount -= NumRefs;
00433   if (AS.RefCount == 0)
00434     AS.removeFromTracker(*this);
00435 }
00436 
00437 bool
00438 AliasSetTracker::remove(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo) {
00439   AliasSet *AS = findAliasSetForPointer(Ptr, Size, AAInfo);
00440   if (!AS) return false;
00441   remove(*AS);
00442   return true;
00443 }
00444 
00445 bool AliasSetTracker::remove(LoadInst *LI) {
00446   const DataLayout &DL = LI->getModule()->getDataLayout();
00447   uint64_t Size = DL.getTypeStoreSize(LI->getType());
00448 
00449   AAMDNodes AAInfo;
00450   LI->getAAMetadata(AAInfo);
00451 
00452   AliasSet *AS = findAliasSetForPointer(LI->getOperand(0), Size, AAInfo);
00453   if (!AS) return false;
00454   remove(*AS);
00455   return true;
00456 }
00457 
00458 bool AliasSetTracker::remove(StoreInst *SI) {
00459   const DataLayout &DL = SI->getModule()->getDataLayout();
00460   uint64_t Size = DL.getTypeStoreSize(SI->getOperand(0)->getType());
00461 
00462   AAMDNodes AAInfo;
00463   SI->getAAMetadata(AAInfo);
00464 
00465   AliasSet *AS = findAliasSetForPointer(SI->getOperand(1), Size, AAInfo);
00466   if (!AS) return false;
00467   remove(*AS);
00468   return true;
00469 }
00470 
00471 bool AliasSetTracker::remove(VAArgInst *VAAI) {
00472   AAMDNodes AAInfo;
00473   VAAI->getAAMetadata(AAInfo);
00474 
00475   AliasSet *AS = findAliasSetForPointer(VAAI->getOperand(0),
00476                                         MemoryLocation::UnknownSize, AAInfo);
00477   if (!AS) return false;
00478   remove(*AS);
00479   return true;
00480 }
00481 
00482 bool AliasSetTracker::removeUnknown(Instruction *I) {
00483   if (!I->mayReadOrWriteMemory())
00484     return false; // doesn't alias anything
00485 
00486   AliasSet *AS = findAliasSetForUnknownInst(I);
00487   if (!AS) return false;
00488   remove(*AS);
00489   return true;
00490 }
00491 
00492 bool AliasSetTracker::remove(Instruction *I) {
00493   // Dispatch to one of the other remove methods...
00494   if (LoadInst *LI = dyn_cast<LoadInst>(I))
00495     return remove(LI);
00496   if (StoreInst *SI = dyn_cast<StoreInst>(I))
00497     return remove(SI);
00498   if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
00499     return remove(VAAI);
00500   return removeUnknown(I);
00501 }
00502 
00503 
00504 // deleteValue method - This method is used to remove a pointer value from the
00505 // AliasSetTracker entirely.  It should be used when an instruction is deleted
00506 // from the program to update the AST.  If you don't use this, you would have
00507 // dangling pointers to deleted instructions.
00508 //
00509 void AliasSetTracker::deleteValue(Value *PtrVal) {
00510   // If this is a call instruction, remove the callsite from the appropriate
00511   // AliasSet (if present).
00512   if (Instruction *Inst = dyn_cast<Instruction>(PtrVal)) {
00513     if (Inst->mayReadOrWriteMemory()) {
00514       // Scan all the alias sets to see if this call site is contained.
00515       for (iterator I = begin(), E = end(); I != E;) {
00516         iterator Cur = I++;
00517         if (!Cur->Forward)
00518           Cur->removeUnknownInst(*this, Inst);
00519       }
00520     }
00521   }
00522 
00523   // First, look up the PointerRec for this pointer.
00524   PointerMapType::iterator I = PointerMap.find_as(PtrVal);
00525   if (I == PointerMap.end()) return;  // Noop
00526 
00527   // If we found one, remove the pointer from the alias set it is in.
00528   AliasSet::PointerRec *PtrValEnt = I->second;
00529   AliasSet *AS = PtrValEnt->getAliasSet(*this);
00530 
00531   // Unlink and delete from the list of values.
00532   PtrValEnt->eraseFromList();
00533   
00534   // Stop using the alias set.
00535   AS->dropRef(*this);
00536   
00537   PointerMap.erase(I);
00538 }
00539 
00540 // copyValue - This method should be used whenever a preexisting value in the
00541 // program is copied or cloned, introducing a new value.  Note that it is ok for
00542 // clients that use this method to introduce the same value multiple times: if
00543 // the tracker already knows about a value, it will ignore the request.
00544 //
00545 void AliasSetTracker::copyValue(Value *From, Value *To) {
00546   // First, look up the PointerRec for this pointer.
00547   PointerMapType::iterator I = PointerMap.find_as(From);
00548   if (I == PointerMap.end())
00549     return;  // Noop
00550   assert(I->second->hasAliasSet() && "Dead entry?");
00551 
00552   AliasSet::PointerRec &Entry = getEntryFor(To);
00553   if (Entry.hasAliasSet()) return;    // Already in the tracker!
00554 
00555   // Add it to the alias set it aliases...
00556   I = PointerMap.find_as(From);
00557   AliasSet *AS = I->second->getAliasSet(*this);
00558   AS->addPointer(*this, Entry, I->second->getSize(),
00559                  I->second->getAAInfo(),
00560                  true);
00561 }
00562 
00563 
00564 
00565 //===----------------------------------------------------------------------===//
00566 //               AliasSet/AliasSetTracker Printing Support
00567 //===----------------------------------------------------------------------===//
00568 
00569 void AliasSet::print(raw_ostream &OS) const {
00570   OS << "  AliasSet[" << (const void*)this << ", " << RefCount << "] ";
00571   OS << (Alias == SetMustAlias ? "must" : "may") << " alias, ";
00572   switch (Access) {
00573   case NoAccess:     OS << "No access "; break;
00574   case RefAccess:    OS << "Ref       "; break;
00575   case ModAccess:    OS << "Mod       "; break;
00576   case ModRefAccess: OS << "Mod/Ref   "; break;
00577   default: llvm_unreachable("Bad value for Access!");
00578   }
00579   if (isVolatile()) OS << "[volatile] ";
00580   if (Forward)
00581     OS << " forwarding to " << (void*)Forward;
00582 
00583 
00584   if (!empty()) {
00585     OS << "Pointers: ";
00586     for (iterator I = begin(), E = end(); I != E; ++I) {
00587       if (I != begin()) OS << ", ";
00588       I.getPointer()->printAsOperand(OS << "(");
00589       OS << ", " << I.getSize() << ")";
00590     }
00591   }
00592   if (!UnknownInsts.empty()) {
00593     OS << "\n    " << UnknownInsts.size() << " Unknown instructions: ";
00594     for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
00595       if (i) OS << ", ";
00596       UnknownInsts[i]->printAsOperand(OS);
00597     }
00598   }
00599   OS << "\n";
00600 }
00601 
00602 void AliasSetTracker::print(raw_ostream &OS) const {
00603   OS << "Alias Set Tracker: " << AliasSets.size() << " alias sets for "
00604      << PointerMap.size() << " pointer values.\n";
00605   for (const_iterator I = begin(), E = end(); I != E; ++I)
00606     I->print(OS);
00607   OS << "\n";
00608 }
00609 
00610 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
00611 void AliasSet::dump() const { print(dbgs()); }
00612 void AliasSetTracker::dump() const { print(dbgs()); }
00613 #endif
00614 
00615 //===----------------------------------------------------------------------===//
00616 //                     ASTCallbackVH Class Implementation
00617 //===----------------------------------------------------------------------===//
00618 
00619 void AliasSetTracker::ASTCallbackVH::deleted() {
00620   assert(AST && "ASTCallbackVH called with a null AliasSetTracker!");
00621   AST->deleteValue(getValPtr());
00622   // this now dangles!
00623 }
00624 
00625 void AliasSetTracker::ASTCallbackVH::allUsesReplacedWith(Value *V) {
00626   AST->copyValue(getValPtr(), V);
00627 }
00628 
00629 AliasSetTracker::ASTCallbackVH::ASTCallbackVH(Value *V, AliasSetTracker *ast)
00630   : CallbackVH(V), AST(ast) {}
00631 
00632 AliasSetTracker::ASTCallbackVH &
00633 AliasSetTracker::ASTCallbackVH::operator=(Value *V) {
00634   return *this = ASTCallbackVH(V, AST);
00635 }
00636 
00637 //===----------------------------------------------------------------------===//
00638 //                            AliasSetPrinter Pass
00639 //===----------------------------------------------------------------------===//
00640 
00641 namespace {
00642   class AliasSetPrinter : public FunctionPass {
00643     AliasSetTracker *Tracker;
00644   public:
00645     static char ID; // Pass identification, replacement for typeid
00646     AliasSetPrinter() : FunctionPass(ID) {
00647       initializeAliasSetPrinterPass(*PassRegistry::getPassRegistry());
00648     }
00649 
00650     void getAnalysisUsage(AnalysisUsage &AU) const override {
00651       AU.setPreservesAll();
00652       AU.addRequired<AAResultsWrapperPass>();
00653     }
00654 
00655     bool runOnFunction(Function &F) override {
00656       auto &AAWP = getAnalysis<AAResultsWrapperPass>();
00657       Tracker = new AliasSetTracker(AAWP.getAAResults());
00658 
00659       for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
00660         Tracker->add(&*I);
00661       Tracker->print(errs());
00662       delete Tracker;
00663       return false;
00664     }
00665   };
00666 }
00667 
00668 char AliasSetPrinter::ID = 0;
00669 INITIALIZE_PASS_BEGIN(AliasSetPrinter, "print-alias-sets",
00670                 "Alias Set Printer", false, true)
00671 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
00672 INITIALIZE_PASS_END(AliasSetPrinter, "print-alias-sets",
00673                 "Alias Set Printer", false, true)