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