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 24namespace llvm { 25 26class LoadInst; 27class StoreInst; 28class MemTransferInst; 29class MemIntrinsic; 30class 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. 41class MemoryLocation { 42public: 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. 131template <> 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