Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:11

0001 //===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines two classes: AliasSetTracker and AliasSet. These interfaces
0010 // are used to classify a collection of memory locations into a maximal number
0011 // of disjoint sets. Each AliasSet object constructed by the AliasSetTracker
0012 // object refers to memory disjoint from the other sets.
0013 //
0014 // An AliasSetTracker can only be used on immutable IR.
0015 //
0016 //===----------------------------------------------------------------------===//
0017 
0018 #ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
0019 #define LLVM_ANALYSIS_ALIASSETTRACKER_H
0020 
0021 #include "llvm/ADT/DenseMap.h"
0022 #include "llvm/ADT/SmallVector.h"
0023 #include "llvm/ADT/ilist.h"
0024 #include "llvm/ADT/ilist_node.h"
0025 #include "llvm/Analysis/MemoryLocation.h"
0026 #include "llvm/IR/PassManager.h"
0027 #include "llvm/IR/ValueHandle.h"
0028 #include <cassert>
0029 #include <vector>
0030 
0031 namespace llvm {
0032 
0033 class AliasResult;
0034 class AliasSetTracker;
0035 class AnyMemSetInst;
0036 class AnyMemTransferInst;
0037 class BasicBlock;
0038 class BatchAAResults;
0039 class Function;
0040 class Instruction;
0041 class StoreInst;
0042 class LoadInst;
0043 enum class ModRefInfo : uint8_t;
0044 class raw_ostream;
0045 class VAArgInst;
0046 class Value;
0047 
0048 class AliasSet : public ilist_node<AliasSet> {
0049   friend class AliasSetTracker;
0050 
0051   // Forwarding pointer.
0052   AliasSet *Forward = nullptr;
0053 
0054   /// Memory locations in this alias set.
0055   SmallVector<MemoryLocation, 0> MemoryLocs;
0056 
0057   /// All instructions without a specific address in this alias set.
0058   std::vector<AssertingVH<Instruction>> UnknownInsts;
0059 
0060   /// Number of nodes pointing to this AliasSet plus the number of AliasSets
0061   /// forwarding to it.
0062   unsigned RefCount : 27;
0063 
0064   // Signifies that this set should be considered to alias any pointer.
0065   // Use when the tracker holding this set is saturated.
0066   unsigned AliasAny : 1;
0067 
0068   /// The kinds of access this alias set models.
0069   ///
0070   /// We keep track of whether this alias set merely refers to the locations of
0071   /// memory (and not any particular access), whether it modifies or references
0072   /// the memory, or whether it does both. The lattice goes from "NoAccess" to
0073   /// either RefAccess or ModAccess, then to ModRefAccess as necessary.
0074   enum AccessLattice {
0075     NoAccess = 0,
0076     RefAccess = 1,
0077     ModAccess = 2,
0078     ModRefAccess = RefAccess | ModAccess
0079   };
0080   unsigned Access : 2;
0081 
0082   /// The kind of alias relationship between pointers of the set.
0083   ///
0084   /// These represent conservatively correct alias results between any members
0085   /// of the set. We represent these independently of the values of alias
0086   /// results in order to pack it into a single bit. Lattice goes from
0087   /// MustAlias to MayAlias.
0088   enum AliasLattice {
0089     SetMustAlias = 0, SetMayAlias = 1
0090   };
0091   unsigned Alias : 1;
0092 
0093   void addRef() { ++RefCount; }
0094 
0095   void dropRef(AliasSetTracker &AST) {
0096     assert(RefCount >= 1 && "Invalid reference count detected!");
0097     if (--RefCount == 0)
0098       removeFromTracker(AST);
0099   }
0100 
0101 public:
0102   AliasSet(const AliasSet &) = delete;
0103   AliasSet &operator=(const AliasSet &) = delete;
0104 
0105   /// Accessors...
0106   bool isRef() const { return Access & RefAccess; }
0107   bool isMod() const { return Access & ModAccess; }
0108   bool isMustAlias() const { return Alias == SetMustAlias; }
0109   bool isMayAlias()  const { return Alias == SetMayAlias; }
0110 
0111   /// Return true if this alias set should be ignored as part of the
0112   /// AliasSetTracker object.
0113   bool isForwardingAliasSet() const { return Forward; }
0114 
0115   /// Merge the specified alias set into this alias set.
0116   void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA);
0117 
0118   // Alias Set iteration - Allow access to all of the memory locations which are
0119   // part of this alias set.
0120   using iterator = SmallVectorImpl<MemoryLocation>::const_iterator;
0121   iterator begin() const { return MemoryLocs.begin(); }
0122   iterator end() const { return MemoryLocs.end(); }
0123 
0124   unsigned size() const { return MemoryLocs.size(); }
0125 
0126   /// Retrieve the pointer values for the memory locations in this alias set.
0127   /// The order matches that of the memory locations, but duplicate pointer
0128   /// values are omitted.
0129   using PointerVector = SmallVector<const Value *, 8>;
0130   PointerVector getPointers() const;
0131 
0132   void print(raw_ostream &OS) const;
0133   void dump() const;
0134 
0135 private:
0136   // Can only be created by AliasSetTracker.
0137   AliasSet()
0138       : RefCount(0), AliasAny(false), Access(NoAccess), Alias(SetMustAlias) {}
0139 
0140   void removeFromTracker(AliasSetTracker &AST);
0141 
0142   void addMemoryLocation(AliasSetTracker &AST, const MemoryLocation &MemLoc,
0143                          bool KnownMustAlias = false);
0144   void addUnknownInst(Instruction *I, BatchAAResults &AA);
0145 
0146 public:
0147   /// If the specified memory location "may" (or must) alias one of the members
0148   /// in the set return the appropriate AliasResult. Otherwise return NoAlias.
0149   AliasResult aliasesMemoryLocation(const MemoryLocation &MemLoc,
0150                                     BatchAAResults &AA) const;
0151 
0152   ModRefInfo aliasesUnknownInst(const Instruction *Inst,
0153                                 BatchAAResults &AA) const;
0154 };
0155 
0156 inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
0157   AS.print(OS);
0158   return OS;
0159 }
0160 
0161 class AliasSetTracker {
0162   BatchAAResults &AA;
0163   ilist<AliasSet> AliasSets;
0164 
0165   using PointerMapType = DenseMap<AssertingVH<const Value>, AliasSet *>;
0166 
0167   // Map from pointer values to the alias set holding one or more memory
0168   // locations with that pointer value.
0169   PointerMapType PointerMap;
0170 
0171 public:
0172   /// Create an empty collection of AliasSets, and use the specified alias
0173   /// analysis object to disambiguate load and store addresses.
0174   explicit AliasSetTracker(BatchAAResults &AA) : AA(AA) {}
0175   ~AliasSetTracker() { clear(); }
0176 
0177   /// These methods are used to add different types of instructions to the alias
0178   /// sets. Adding a new instruction can result in one of three actions
0179   /// happening:
0180   ///
0181   ///   1. If the instruction doesn't alias any other sets, create a new set.
0182   ///   2. If the instruction aliases exactly one set, add it to the set
0183   ///   3. If the instruction aliases multiple sets, merge the sets, and add
0184   ///      the instruction to the result.
0185   ///
0186   void add(const MemoryLocation &Loc);
0187   void add(LoadInst *LI);
0188   void add(StoreInst *SI);
0189   void add(VAArgInst *VAAI);
0190   void add(AnyMemSetInst *MSI);
0191   void add(AnyMemTransferInst *MTI);
0192   void add(Instruction *I);       // Dispatch to one of the other add methods...
0193   void add(BasicBlock &BB);       // Add all instructions in basic block
0194   void add(const AliasSetTracker &AST); // Add alias relations from another AST
0195   void addUnknown(Instruction *I);
0196 
0197   void clear();
0198 
0199   /// Return the alias sets that are active.
0200   const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
0201 
0202   /// Return the alias set which contains the specified memory location.  If
0203   /// the memory location aliases two or more existing alias sets, will have
0204   /// the effect of merging those alias sets before the single resulting alias
0205   /// set is returned.
0206   AliasSet &getAliasSetFor(const MemoryLocation &MemLoc);
0207 
0208   /// Return the underlying alias analysis object used by this tracker.
0209   BatchAAResults &getAliasAnalysis() const { return AA; }
0210 
0211   using iterator = ilist<AliasSet>::iterator;
0212   using const_iterator = ilist<AliasSet>::const_iterator;
0213 
0214   const_iterator begin() const { return AliasSets.begin(); }
0215   const_iterator end()   const { return AliasSets.end(); }
0216 
0217   iterator begin() { return AliasSets.begin(); }
0218   iterator end()   { return AliasSets.end(); }
0219 
0220   void print(raw_ostream &OS) const;
0221   void dump() const;
0222 
0223 private:
0224   friend class AliasSet;
0225 
0226   // The total number of memory locations contained in all alias sets.
0227   unsigned TotalAliasSetSize = 0;
0228 
0229   // A non-null value signifies this AST is saturated. A saturated AST lumps
0230   // all elements into a single "May" set.
0231   AliasSet *AliasAnyAS = nullptr;
0232 
0233   void removeAliasSet(AliasSet *AS);
0234 
0235   // Update an alias set field to point to its real destination. If the field is
0236   // pointing to a set that has been merged with another set and is forwarding,
0237   // the field is updated to point to the set obtained by following the
0238   // forwarding links. The Forward fields of intermediate alias sets are
0239   // collapsed as well, and alias set reference counts are updated to reflect
0240   // the new situation.
0241   void collapseForwardingIn(AliasSet *&AS) {
0242     if (AS->Forward) {
0243       collapseForwardingIn(AS->Forward);
0244       // Swap out AS for AS->Forward, while updating reference counts.
0245       AliasSet *NewAS = AS->Forward;
0246       NewAS->addRef();
0247       AS->dropRef(*this);
0248       AS = NewAS;
0249     }
0250   }
0251 
0252   AliasSet &addMemoryLocation(MemoryLocation Loc, AliasSet::AccessLattice E);
0253   AliasSet *mergeAliasSetsForMemoryLocation(const MemoryLocation &MemLoc,
0254                                             AliasSet *PtrAS,
0255                                             bool &MustAliasAll);
0256 
0257   /// Merge all alias sets into a single set that is considered to alias
0258   /// any memory location or instruction.
0259   AliasSet &mergeAllAliasSets();
0260 
0261   AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
0262 };
0263 
0264 inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
0265   AST.print(OS);
0266   return OS;
0267 }
0268 
0269 class AliasSetsPrinterPass : public PassInfoMixin<AliasSetsPrinterPass> {
0270   raw_ostream &OS;
0271 
0272 public:
0273   explicit AliasSetsPrinterPass(raw_ostream &OS);
0274   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0275   static bool isRequired() { return true; }
0276 };
0277 
0278 } // end namespace llvm
0279 
0280 #endif // LLVM_ANALYSIS_ALIASSETTRACKER_H