blob: c1080742e83a2508a01182a4d5b710979043cea0 [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;
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