Home | History | Annotate | Download | only in Analysis
      1 //===- MemoryLocation.h - Memory location descriptions ----------*- C++ -*-===//
      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 /// \file
     10 /// This file provides utility analysis objects describing memory locations.
     11 /// These are used both by the Alias Analysis infrastructure and more
     12 /// specialized memory analysis layers.
     13 ///
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef LLVM_ANALYSIS_MEMORYLOCATION_H
     17 #define LLVM_ANALYSIS_MEMORYLOCATION_H
     18 
     19 #include "llvm/ADT/DenseMapInfo.h"
     20 #include "llvm/IR/CallSite.h"
     21 #include "llvm/IR/Metadata.h"
     22 
     23 namespace llvm {
     24 
     25 class LoadInst;
     26 class StoreInst;
     27 class MemTransferInst;
     28 class MemIntrinsic;
     29 class TargetLibraryInfo;
     30 
     31 /// Representation for a specific memory location.
     32 ///
     33 /// This abstraction can be used to represent a specific location in memory.
     34 /// The goal of the location is to represent enough information to describe
     35 /// abstract aliasing, modification, and reference behaviors of whatever
     36 /// value(s) are stored in memory at the particular location.
     37 ///
     38 /// The primary user of this interface is LLVM's Alias Analysis, but other
     39 /// memory analyses such as MemoryDependence can use it as well.
     40 class MemoryLocation {
     41 public:
     42   /// UnknownSize - This is a special value which can be used with the
     43   /// size arguments in alias queries to indicate that the caller does not
     44   /// know the sizes of the potential memory references.
     45   enum : uint64_t { UnknownSize = ~UINT64_C(0) };
     46 
     47   /// The address of the start of the location.
     48   const Value *Ptr;
     49 
     50   /// The maximum size of the location, in address-units, or
     51   /// UnknownSize if the size is not known.
     52   ///
     53   /// Note that an unknown size does not mean the pointer aliases the entire
     54   /// virtual address space, because there are restrictions on stepping out of
     55   /// one object and into another. See
     56   /// http://llvm.org/docs/LangRef.html#pointeraliasing
     57   uint64_t Size;
     58 
     59   /// The metadata nodes which describes the aliasing of the location (each
     60   /// member is null if that kind of information is unavailable).
     61   AAMDNodes AATags;
     62 
     63   /// Return a location with information about the memory reference by the given
     64   /// instruction.
     65   static MemoryLocation get(const LoadInst *LI);
     66   static MemoryLocation get(const StoreInst *SI);
     67   static MemoryLocation get(const VAArgInst *VI);
     68   static MemoryLocation get(const AtomicCmpXchgInst *CXI);
     69   static MemoryLocation get(const AtomicRMWInst *RMWI);
     70   static MemoryLocation get(const Instruction *Inst) {
     71     if (auto *I = dyn_cast<LoadInst>(Inst))
     72       return get(I);
     73     else if (auto *I = dyn_cast<StoreInst>(Inst))
     74       return get(I);
     75     else if (auto *I = dyn_cast<VAArgInst>(Inst))
     76       return get(I);
     77     else if (auto *I = dyn_cast<AtomicCmpXchgInst>(Inst))
     78       return get(I);
     79     else if (auto *I = dyn_cast<AtomicRMWInst>(Inst))
     80       return get(I);
     81     llvm_unreachable("unsupported memory instruction");
     82   }
     83 
     84   /// Return a location representing the source of a memory transfer.
     85   static MemoryLocation getForSource(const MemTransferInst *MTI);
     86 
     87   /// Return a location representing the destination of a memory set or
     88   /// transfer.
     89   static MemoryLocation getForDest(const MemIntrinsic *MI);
     90 
     91   /// Return a location representing a particular argument of a call.
     92   static MemoryLocation getForArgument(ImmutableCallSite CS, unsigned ArgIdx,
     93                                        const TargetLibraryInfo &TLI);
     94 
     95   explicit MemoryLocation(const Value *Ptr = nullptr,
     96                           uint64_t Size = UnknownSize,
     97                           const AAMDNodes &AATags = AAMDNodes())
     98       : Ptr(Ptr), Size(Size), AATags(AATags) {}
     99 
    100   MemoryLocation getWithNewPtr(const Value *NewPtr) const {
    101     MemoryLocation Copy(*this);
    102     Copy.Ptr = NewPtr;
    103     return Copy;
    104   }
    105 
    106   MemoryLocation getWithNewSize(uint64_t NewSize) const {
    107     MemoryLocation Copy(*this);
    108     Copy.Size = NewSize;
    109     return Copy;
    110   }
    111 
    112   MemoryLocation getWithoutAATags() const {
    113     MemoryLocation Copy(*this);
    114     Copy.AATags = AAMDNodes();
    115     return Copy;
    116   }
    117 
    118   bool operator==(const MemoryLocation &Other) const {
    119     return Ptr == Other.Ptr && Size == Other.Size && AATags == Other.AATags;
    120   }
    121 };
    122 
    123 // Specialize DenseMapInfo for MemoryLocation.
    124 template <> struct DenseMapInfo<MemoryLocation> {
    125   static inline MemoryLocation getEmptyKey() {
    126     return MemoryLocation(DenseMapInfo<const Value *>::getEmptyKey(), 0);
    127   }
    128   static inline MemoryLocation getTombstoneKey() {
    129     return MemoryLocation(DenseMapInfo<const Value *>::getTombstoneKey(), 0);
    130   }
    131   static unsigned getHashValue(const MemoryLocation &Val) {
    132     return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^
    133            DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^
    134            DenseMapInfo<AAMDNodes>::getHashValue(Val.AATags);
    135   }
    136   static bool isEqual(const MemoryLocation &LHS, const MemoryLocation &RHS) {
    137     return LHS == RHS;
    138   }
    139 };
    140 }
    141 
    142 #endif
    143