Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines two classes: AliasSetTracker and AliasSet. These interfaces
  10. // are used to classify a collection of pointer references into a maximal number
  11. // of disjoint sets. Each AliasSet object constructed by the AliasSetTracker
  12. // object refers to memory disjoint from the other sets.
  13. //
  14. // An AliasSetTracker can only be used on immutable IR.
  15. //
  16. //===----------------------------------------------------------------------===//
  17.  
  18. #ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
  19. #define LLVM_ANALYSIS_ALIASSETTRACKER_H
  20.  
  21. #include "llvm/ADT/DenseMap.h"
  22. #include "llvm/ADT/DenseMapInfo.h"
  23. #include "llvm/ADT/ilist.h"
  24. #include "llvm/ADT/ilist_node.h"
  25. #include "llvm/Analysis/MemoryLocation.h"
  26. #include "llvm/IR/Instruction.h"
  27. #include "llvm/IR/PassManager.h"
  28. #include "llvm/IR/ValueHandle.h"
  29. #include <cassert>
  30. #include <cstddef>
  31. #include <iterator>
  32. #include <vector>
  33.  
  34. namespace llvm {
  35.  
  36. class AliasResult;
  37. class AliasSetTracker;
  38. class AnyMemSetInst;
  39. class AnyMemTransferInst;
  40. class BasicBlock;
  41. class BatchAAResults;
  42. class LoadInst;
  43. enum class ModRefInfo : uint8_t;
  44. class raw_ostream;
  45. class StoreInst;
  46. class VAArgInst;
  47. class Value;
  48.  
  49. class AliasSet : public ilist_node<AliasSet> {
  50.   friend class AliasSetTracker;
  51.  
  52.   class PointerRec {
  53.     Value *Val;  // The pointer this record corresponds to.
  54.     PointerRec **PrevInList = nullptr;
  55.     PointerRec *NextInList = nullptr;
  56.     AliasSet *AS = nullptr;
  57.     LocationSize Size = LocationSize::mapEmpty();
  58.     AAMDNodes AAInfo;
  59.  
  60.     // Whether the size for this record has been set at all. This makes no
  61.     // guarantees about the size being known.
  62.     bool isSizeSet() const { return Size != LocationSize::mapEmpty(); }
  63.  
  64.   public:
  65.     PointerRec(Value *V)
  66.       : Val(V), AAInfo(DenseMapInfo<AAMDNodes>::getEmptyKey()) {}
  67.  
  68.     Value *getValue() const { return Val; }
  69.  
  70.     PointerRec *getNext() const { return NextInList; }
  71.     bool hasAliasSet() const { return AS != nullptr; }
  72.  
  73.     PointerRec** setPrevInList(PointerRec **PIL) {
  74.       PrevInList = PIL;
  75.       return &NextInList;
  76.     }
  77.  
  78.     bool updateSizeAndAAInfo(LocationSize NewSize, const AAMDNodes &NewAAInfo) {
  79.       bool SizeChanged = false;
  80.       if (NewSize != Size) {
  81.         LocationSize OldSize = Size;
  82.         Size = isSizeSet() ? Size.unionWith(NewSize) : NewSize;
  83.         SizeChanged = OldSize != Size;
  84.       }
  85.  
  86.       if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey())
  87.         // We don't have a AAInfo yet. Set it to NewAAInfo.
  88.         AAInfo = NewAAInfo;
  89.       else {
  90.         AAMDNodes Intersection(AAInfo.intersect(NewAAInfo));
  91.         SizeChanged |= Intersection != AAInfo;
  92.         AAInfo = Intersection;
  93.       }
  94.       return SizeChanged;
  95.     }
  96.  
  97.     LocationSize getSize() const {
  98.       assert(isSizeSet() && "Getting an unset size!");
  99.       return Size;
  100.     }
  101.  
  102.     /// Return the AAInfo, or null if there is no information or conflicting
  103.     /// information.
  104.     AAMDNodes getAAInfo() const {
  105.       // If we have missing or conflicting AAInfo, return null.
  106.       if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey() ||
  107.           AAInfo == DenseMapInfo<AAMDNodes>::getTombstoneKey())
  108.         return AAMDNodes();
  109.       return AAInfo;
  110.     }
  111.  
  112.     AliasSet *getAliasSet(AliasSetTracker &AST) {
  113.       assert(AS && "No AliasSet yet!");
  114.       if (AS->Forward) {
  115.         AliasSet *OldAS = AS;
  116.         AS = OldAS->getForwardedTarget(AST);
  117.         AS->addRef();
  118.         OldAS->dropRef(AST);
  119.       }
  120.       return AS;
  121.     }
  122.  
  123.     void setAliasSet(AliasSet *as) {
  124.       assert(!AS && "Already have an alias set!");
  125.       AS = as;
  126.     }
  127.  
  128.     void eraseFromList() {
  129.       if (NextInList) NextInList->PrevInList = PrevInList;
  130.       *PrevInList = NextInList;
  131.       if (AS->PtrListEnd == &NextInList) {
  132.         AS->PtrListEnd = PrevInList;
  133.         assert(*AS->PtrListEnd == nullptr && "List not terminated right!");
  134.       }
  135.       delete this;
  136.     }
  137.   };
  138.  
  139.   // Doubly linked list of nodes.
  140.   PointerRec *PtrList = nullptr;
  141.   PointerRec **PtrListEnd;
  142.   // Forwarding pointer.
  143.   AliasSet *Forward = nullptr;
  144.  
  145.   /// All instructions without a specific address in this alias set.
  146.   std::vector<AssertingVH<Instruction>> UnknownInsts;
  147.  
  148.   /// Number of nodes pointing to this AliasSet plus the number of AliasSets
  149.   /// forwarding to it.
  150.   unsigned RefCount : 27;
  151.  
  152.   // Signifies that this set should be considered to alias any pointer.
  153.   // Use when the tracker holding this set is saturated.
  154.   unsigned AliasAny : 1;
  155.  
  156.   /// The kinds of access this alias set models.
  157.   ///
  158.   /// We keep track of whether this alias set merely refers to the locations of
  159.   /// memory (and not any particular access), whether it modifies or references
  160.   /// the memory, or whether it does both. The lattice goes from "NoAccess" to
  161.   /// either RefAccess or ModAccess, then to ModRefAccess as necessary.
  162.   enum AccessLattice {
  163.     NoAccess = 0,
  164.     RefAccess = 1,
  165.     ModAccess = 2,
  166.     ModRefAccess = RefAccess | ModAccess
  167.   };
  168.   unsigned Access : 2;
  169.  
  170.   /// The kind of alias relationship between pointers of the set.
  171.   ///
  172.   /// These represent conservatively correct alias results between any members
  173.   /// of the set. We represent these independently of the values of alias
  174.   /// results in order to pack it into a single bit. Lattice goes from
  175.   /// MustAlias to MayAlias.
  176.   enum AliasLattice {
  177.     SetMustAlias = 0, SetMayAlias = 1
  178.   };
  179.   unsigned Alias : 1;
  180.  
  181.   unsigned SetSize = 0;
  182.  
  183.   void addRef() { ++RefCount; }
  184.  
  185.   void dropRef(AliasSetTracker &AST) {
  186.     assert(RefCount >= 1 && "Invalid reference count detected!");
  187.     if (--RefCount == 0)
  188.       removeFromTracker(AST);
  189.   }
  190.  
  191. public:
  192.   AliasSet(const AliasSet &) = delete;
  193.   AliasSet &operator=(const AliasSet &) = delete;
  194.  
  195.   /// Accessors...
  196.   bool isRef() const { return Access & RefAccess; }
  197.   bool isMod() const { return Access & ModAccess; }
  198.   bool isMustAlias() const { return Alias == SetMustAlias; }
  199.   bool isMayAlias()  const { return Alias == SetMayAlias; }
  200.  
  201.   /// Return true if this alias set should be ignored as part of the
  202.   /// AliasSetTracker object.
  203.   bool isForwardingAliasSet() const { return Forward; }
  204.  
  205.   /// Merge the specified alias set into this alias set.
  206.   void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA);
  207.  
  208.   // Alias Set iteration - Allow access to all of the pointers which are part of
  209.   // this alias set.
  210.   class iterator;
  211.   iterator begin() const { return iterator(PtrList); }
  212.   iterator end()   const { return iterator(); }
  213.   bool empty() const { return PtrList == nullptr; }
  214.  
  215.   // Unfortunately, ilist::size() is linear, so we have to add code to keep
  216.   // track of the list's exact size.
  217.   unsigned size() { return SetSize; }
  218.  
  219.   void print(raw_ostream &OS) const;
  220.   void dump() const;
  221.  
  222.   /// Define an iterator for alias sets... this is just a forward iterator.
  223.   class iterator {
  224.     PointerRec *CurNode;
  225.  
  226.   public:
  227.     using iterator_category = std::forward_iterator_tag;
  228.     using value_type = PointerRec;
  229.     using difference_type = std::ptrdiff_t;
  230.     using pointer = value_type *;
  231.     using reference = value_type &;
  232.  
  233.     explicit iterator(PointerRec *CN = nullptr) : CurNode(CN) {}
  234.  
  235.     bool operator==(const iterator& x) const {
  236.       return CurNode == x.CurNode;
  237.     }
  238.     bool operator!=(const iterator& x) const { return !operator==(x); }
  239.  
  240.     value_type &operator*() const {
  241.       assert(CurNode && "Dereferencing AliasSet.end()!");
  242.       return *CurNode;
  243.     }
  244.     value_type *operator->() const { return &operator*(); }
  245.  
  246.     Value *getPointer() const { return CurNode->getValue(); }
  247.     LocationSize getSize() const { return CurNode->getSize(); }
  248.     AAMDNodes getAAInfo() const { return CurNode->getAAInfo(); }
  249.  
  250.     iterator& operator++() {                // Preincrement
  251.       assert(CurNode && "Advancing past AliasSet.end()!");
  252.       CurNode = CurNode->getNext();
  253.       return *this;
  254.     }
  255.     iterator operator++(int) { // Postincrement
  256.       iterator tmp = *this; ++*this; return tmp;
  257.     }
  258.   };
  259.  
  260. private:
  261.   // Can only be created by AliasSetTracker.
  262.   AliasSet()
  263.       : PtrListEnd(&PtrList), RefCount(0),  AliasAny(false), Access(NoAccess),
  264.         Alias(SetMustAlias) {}
  265.  
  266.   PointerRec *getSomePointer() const {
  267.     return PtrList;
  268.   }
  269.  
  270.   /// Return the real alias set this represents. If this has been merged with
  271.   /// another set and is forwarding, return the ultimate destination set. This
  272.   /// also implements the union-find collapsing as well.
  273.   AliasSet *getForwardedTarget(AliasSetTracker &AST) {
  274.     if (!Forward) return this;
  275.  
  276.     AliasSet *Dest = Forward->getForwardedTarget(AST);
  277.     if (Dest != Forward) {
  278.       Dest->addRef();
  279.       Forward->dropRef(AST);
  280.       Forward = Dest;
  281.     }
  282.     return Dest;
  283.   }
  284.  
  285.   void removeFromTracker(AliasSetTracker &AST);
  286.  
  287.   void addPointer(AliasSetTracker &AST, PointerRec &Entry, LocationSize Size,
  288.                   const AAMDNodes &AAInfo, bool KnownMustAlias = false,
  289.                   bool SkipSizeUpdate = false);
  290.   void addUnknownInst(Instruction *I, BatchAAResults &AA);
  291.  
  292. public:
  293.   /// If the specified pointer "may" (or must) alias one of the members in the
  294.   /// set return the appropriate AliasResult. Otherwise return NoAlias.
  295.   AliasResult aliasesPointer(const Value *Ptr, LocationSize Size,
  296.                              const AAMDNodes &AAInfo, BatchAAResults &AA) const;
  297.   ModRefInfo aliasesUnknownInst(const Instruction *Inst,
  298.                                 BatchAAResults &AA) const;
  299. };
  300.  
  301. inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
  302.   AS.print(OS);
  303.   return OS;
  304. }
  305.  
  306. class AliasSetTracker {
  307.   BatchAAResults &AA;
  308.   ilist<AliasSet> AliasSets;
  309.  
  310.   using PointerMapType = DenseMap<AssertingVH<Value>, AliasSet::PointerRec *>;
  311.  
  312.   // Map from pointers to their node
  313.   PointerMapType PointerMap;
  314.  
  315. public:
  316.   /// Create an empty collection of AliasSets, and use the specified alias
  317.   /// analysis object to disambiguate load and store addresses.
  318.   explicit AliasSetTracker(BatchAAResults &AA) : AA(AA) {}
  319.   ~AliasSetTracker() { clear(); }
  320.  
  321.   /// These methods are used to add different types of instructions to the alias
  322.   /// sets. Adding a new instruction can result in one of three actions
  323.   /// happening:
  324.   ///
  325.   ///   1. If the instruction doesn't alias any other sets, create a new set.
  326.   ///   2. If the instruction aliases exactly one set, add it to the set
  327.   ///   3. If the instruction aliases multiple sets, merge the sets, and add
  328.   ///      the instruction to the result.
  329.   ///
  330.   /// These methods return true if inserting the instruction resulted in the
  331.   /// addition of a new alias set (i.e., the pointer did not alias anything).
  332.   ///
  333.   void add(Value *Ptr, LocationSize Size, const AAMDNodes &AAInfo); // Add a loc
  334.   void add(LoadInst *LI);
  335.   void add(StoreInst *SI);
  336.   void add(VAArgInst *VAAI);
  337.   void add(AnyMemSetInst *MSI);
  338.   void add(AnyMemTransferInst *MTI);
  339.   void add(Instruction *I);       // Dispatch to one of the other add methods...
  340.   void add(BasicBlock &BB);       // Add all instructions in basic block
  341.   void add(const AliasSetTracker &AST); // Add alias relations from another AST
  342.   void addUnknown(Instruction *I);
  343.  
  344.   void clear();
  345.  
  346.   /// Return the alias sets that are active.
  347.   const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
  348.  
  349.   /// Return the alias set which contains the specified memory location.  If
  350.   /// the memory location aliases two or more existing alias sets, will have
  351.   /// the effect of merging those alias sets before the single resulting alias
  352.   /// set is returned.
  353.   AliasSet &getAliasSetFor(const MemoryLocation &MemLoc);
  354.  
  355.   /// Return the underlying alias analysis object used by this tracker.
  356.   BatchAAResults &getAliasAnalysis() const { return AA; }
  357.  
  358.   using iterator = ilist<AliasSet>::iterator;
  359.   using const_iterator = ilist<AliasSet>::const_iterator;
  360.  
  361.   const_iterator begin() const { return AliasSets.begin(); }
  362.   const_iterator end()   const { return AliasSets.end(); }
  363.  
  364.   iterator begin() { return AliasSets.begin(); }
  365.   iterator end()   { return AliasSets.end(); }
  366.  
  367.   void print(raw_ostream &OS) const;
  368.   void dump() const;
  369.  
  370. private:
  371.   friend class AliasSet;
  372.  
  373.   // The total number of pointers contained in all "may" alias sets.
  374.   unsigned TotalMayAliasSetSize = 0;
  375.  
  376.   // A non-null value signifies this AST is saturated. A saturated AST lumps
  377.   // all pointers into a single "May" set.
  378.   AliasSet *AliasAnyAS = nullptr;
  379.  
  380.   void removeAliasSet(AliasSet *AS);
  381.  
  382.   /// Just like operator[] on the map, except that it creates an entry for the
  383.   /// pointer if it doesn't already exist.
  384.   AliasSet::PointerRec &getEntryFor(Value *V) {
  385.     AliasSet::PointerRec *&Entry = PointerMap[V];
  386.     if (!Entry)
  387.       Entry = new AliasSet::PointerRec(V);
  388.     return *Entry;
  389.   }
  390.  
  391.   AliasSet &addPointer(MemoryLocation Loc, AliasSet::AccessLattice E);
  392.   AliasSet *mergeAliasSetsForPointer(const Value *Ptr, LocationSize Size,
  393.                                      const AAMDNodes &AAInfo,
  394.                                      bool &MustAliasAll);
  395.  
  396.   /// Merge all alias sets into a single set that is considered to alias any
  397.   /// pointer.
  398.   AliasSet &mergeAllAliasSets();
  399.  
  400.   AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
  401. };
  402.  
  403. inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
  404.   AST.print(OS);
  405.   return OS;
  406. }
  407.  
  408. class AliasSetsPrinterPass : public PassInfoMixin<AliasSetsPrinterPass> {
  409.   raw_ostream &OS;
  410.  
  411. public:
  412.   explicit AliasSetsPrinterPass(raw_ostream &OS);
  413.   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
  414. };
  415.  
  416. } // end namespace llvm
  417.  
  418. #endif // LLVM_ANALYSIS_ALIASSETTRACKER_H
  419.