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