• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
24 namespace llvm {
25 
26 class LoadInst;
27 class StoreInst;
28 class MemTransferInst;
29 class MemIntrinsic;
30 class AtomicMemTransferInst;
31 class AtomicMemIntrinsic;
32 class AnyMemTransferInst;
33 class AnyMemIntrinsic;
34 class TargetLibraryInfo;
35 
36 // Represents the size of a MemoryLocation. Logically, it's an
37 // Optional<uint64_t>, with a special UnknownSize value from `MemoryLocation`.
38 using LocationSize = uint64_t;
39 
40 /// 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.
49 class MemoryLocation {
50 public:
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
66   LocationSize Size;
67 
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);
get(const Instruction * Inst)79   static MemoryLocation get(const Instruction *Inst) {
80     return *MemoryLocation::getOrNone(Inst);
81   }
getOrNone(const Instruction * Inst)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);
101   static MemoryLocation getForSource(const AtomicMemTransferInst *MTI);
102   static MemoryLocation getForSource(const AnyMemTransferInst *MTI);
103 
104   /// Return a location representing the destination of a memory set or
105   /// transfer.
106   static MemoryLocation getForDest(const MemIntrinsic *MI);
107   static MemoryLocation getForDest(const AtomicMemIntrinsic *MI);
108   static MemoryLocation getForDest(const AnyMemIntrinsic *MI);
109 
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,
115                           LocationSize Size = UnknownSize,
116                           const AAMDNodes &AATags = AAMDNodes())
Ptr(Ptr)117       : Ptr(Ptr), Size(Size), AATags(AATags) {}
118 
getWithNewPtr(const Value * NewPtr)119   MemoryLocation getWithNewPtr(const Value *NewPtr) const {
120     MemoryLocation Copy(*this);
121     Copy.Ptr = NewPtr;
122     return Copy;
123   }
124 
getWithNewSize(LocationSize NewSize)125   MemoryLocation getWithNewSize(LocationSize NewSize) const {
126     MemoryLocation Copy(*this);
127     Copy.Size = NewSize;
128     return Copy;
129   }
130 
getWithoutAATags()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.
143 template <> 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) ^
152            DenseMapInfo<LocationSize>::getHashValue(Val.Size) ^
153            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
162