LCOV - code coverage report
Current view: top level - lib/Analysis - AliasSetTracker.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 297 306 97.1 %
Date: 2018-10-20 13:21:21 Functions: 35 37 94.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13