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