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