diff options
Diffstat (limited to 'include/llvm/Analysis/MemoryLocation.h')
-rw-r--r-- | include/llvm/Analysis/MemoryLocation.h | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/include/llvm/Analysis/MemoryLocation.h b/include/llvm/Analysis/MemoryLocation.h new file mode 100644 index 0000000000000..94d938dc491f3 --- /dev/null +++ b/include/llvm/Analysis/MemoryLocation.h @@ -0,0 +1,137 @@ +//===- MemoryLocation.h - Memory location descriptions ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file provides utility analysis objects describing memory locations. +/// These are used both by the Alias Analysis infrastructure and more +/// specialized memory analysis layers. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_MEMORYLOCATION_H +#define LLVM_ANALYSIS_MEMORYLOCATION_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/Metadata.h" + +namespace llvm { + +class LoadInst; +class StoreInst; +class MemTransferInst; +class MemIntrinsic; + +/// Representation for a specific memory location. +/// +/// This abstraction can be used to represent a specific location in memory. +/// The goal of the location is to represent enough information to describe +/// abstract aliasing, modification, and reference behaviors of whatever +/// value(s) are stored in memory at the particular location. +/// +/// The primary user of this interface is LLVM's Alias Analysis, but other +/// memory analyses such as MemoryDependence can use it as well. +class MemoryLocation { +public: + /// UnknownSize - This is a special value which can be used with the + /// size arguments in alias queries to indicate that the caller does not + /// know the sizes of the potential memory references. + enum : uint64_t { UnknownSize = ~UINT64_C(0) }; + + /// The address of the start of the location. + const Value *Ptr; + + /// The maximum size of the location, in address-units, or + /// UnknownSize if the size is not known. + /// + /// Note that an unknown size does not mean the pointer aliases the entire + /// virtual address space, because there are restrictions on stepping out of + /// one object and into another. See + /// http://llvm.org/docs/LangRef.html#pointeraliasing + uint64_t Size; + + /// The metadata nodes which describes the aliasing of the location (each + /// member is null if that kind of information is unavailable). + AAMDNodes AATags; + + /// Return a location with information about the memory reference by the given + /// instruction. + static MemoryLocation get(const LoadInst *LI); + static MemoryLocation get(const StoreInst *SI); + static MemoryLocation get(const VAArgInst *VI); + static MemoryLocation get(const AtomicCmpXchgInst *CXI); + static MemoryLocation get(const AtomicRMWInst *RMWI); + static MemoryLocation get(const Instruction *Inst) { + if (auto *I = dyn_cast<LoadInst>(Inst)) + return get(I); + else if (auto *I = dyn_cast<StoreInst>(Inst)) + return get(I); + else if (auto *I = dyn_cast<VAArgInst>(Inst)) + return get(I); + else if (auto *I = dyn_cast<AtomicCmpXchgInst>(Inst)) + return get(I); + else if (auto *I = dyn_cast<AtomicRMWInst>(Inst)) + return get(I); + llvm_unreachable("unsupported memory instruction"); + } + + /// Return a location representing the source of a memory transfer. + static MemoryLocation getForSource(const MemTransferInst *MTI); + + /// Return a location representing the destination of a memory set or + /// transfer. + static MemoryLocation getForDest(const MemIntrinsic *MI); + + explicit MemoryLocation(const Value *Ptr = nullptr, + uint64_t Size = UnknownSize, + const AAMDNodes &AATags = AAMDNodes()) + : Ptr(Ptr), Size(Size), AATags(AATags) {} + + MemoryLocation getWithNewPtr(const Value *NewPtr) const { + MemoryLocation Copy(*this); + Copy.Ptr = NewPtr; + return Copy; + } + + MemoryLocation getWithNewSize(uint64_t NewSize) const { + MemoryLocation Copy(*this); + Copy.Size = NewSize; + return Copy; + } + + MemoryLocation getWithoutAATags() const { + MemoryLocation Copy(*this); + Copy.AATags = AAMDNodes(); + return Copy; + } + + bool operator==(const MemoryLocation &Other) const { + return Ptr == Other.Ptr && Size == Other.Size && AATags == Other.AATags; + } +}; + +// Specialize DenseMapInfo for MemoryLocation. +template <> struct DenseMapInfo<MemoryLocation> { + static inline MemoryLocation getEmptyKey() { + return MemoryLocation(DenseMapInfo<const Value *>::getEmptyKey(), 0); + } + static inline MemoryLocation getTombstoneKey() { + return MemoryLocation(DenseMapInfo<const Value *>::getTombstoneKey(), 0); + } + static unsigned getHashValue(const MemoryLocation &Val) { + return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^ + DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^ + DenseMapInfo<AAMDNodes>::getHashValue(Val.AATags); + } + static bool isEqual(const MemoryLocation &LHS, const MemoryLocation &RHS) { + return LHS == RHS; + } +}; +} + +#endif |