blob: 6b680000312c82dce662877b0237b8f233513225 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010030class AtomicMemTransferInst;
31class AtomicMemIntrinsic;
32class AnyMemTransferInst;
33class AnyMemIntrinsic;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010034class TargetLibraryInfo;
35
Andrew Scullcdfcccc2018-10-05 20:58:37 +010036// Represents the size of a MemoryLocation. Logically, it's an
37// Optional<uint64_t>, with a special UnknownSize value from `MemoryLocation`.
38using LocationSize = uint64_t;
39
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010040/// 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.
49class MemoryLocation {
50public:
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
Andrew Scullcdfcccc2018-10-05 20:58:37 +010066 LocationSize Size;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010067
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);
79 static MemoryLocation get(const Instruction *Inst) {
80 return *MemoryLocation::getOrNone(Inst);
81 }
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);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100101 static MemoryLocation getForSource(const AtomicMemTransferInst *MTI);
102 static MemoryLocation getForSource(const AnyMemTransferInst *MTI);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100103
104 /// Return a location representing the destination of a memory set or
105 /// transfer.
106 static MemoryLocation getForDest(const MemIntrinsic *MI);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100107 static MemoryLocation getForDest(const AtomicMemIntrinsic *MI);
108 static MemoryLocation getForDest(const AnyMemIntrinsic *MI);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100109
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,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100115 LocationSize Size = UnknownSize,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100116 const AAMDNodes &AATags = AAMDNodes())
117 : Ptr(Ptr), Size(Size), AATags(AATags) {}
118
119 MemoryLocation getWithNewPtr(const Value *NewPtr) const {
120 MemoryLocation Copy(*this);
121 Copy.Ptr = NewPtr;
122 return Copy;
123 }
124
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100125 MemoryLocation getWithNewSize(LocationSize NewSize) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100126 MemoryLocation Copy(*this);
127 Copy.Size = NewSize;
128 return Copy;
129 }
130
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.
143template <> 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) ^
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100152 DenseMapInfo<LocationSize>::getHashValue(Val.Size) ^
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100153 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