LLVM 17.0.0git
ExecutorAddress.h
Go to the documentation of this file.
1//===------ ExecutorAddress.h - Executing process address -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Represents an address in the executing program.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
14#define LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
15
17#include "llvm/ADT/identity.h"
21
22#include <cassert>
23#include <type_traits>
24
25namespace llvm {
26namespace orc {
27
29
30/// Represents an address in the executor process.
32public:
33 /// A wrap/unwrap function that leaves pointers unmodified.
34 template <typename T> using rawPtr = llvm::identity<T *>;
35
36 /// Default wrap function to use on this host.
37 template <typename T> using defaultWrap = rawPtr<T>;
38
39 /// Default unwrap function to use on this host.
40 template <typename T> using defaultUnwrap = rawPtr<T>;
41
42 /// Merges a tag into the raw address value:
43 /// P' = P | (TagValue << TagOffset).
44 class Tag {
45 public:
46 constexpr Tag(uintptr_t TagValue, uintptr_t TagOffset)
47 : TagMask(TagValue << TagOffset) {}
48
49 template <typename T> constexpr T *operator()(T *P) {
50 return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(P) | TagMask);
51 }
52
53 private:
54 uintptr_t TagMask;
55 };
56
57 /// Strips a tag of the given length from the given offset within the pointer:
58 /// P' = P & ~(((1 << TagLen) -1) << TagOffset)
59 class Untag {
60 public:
61 constexpr Untag(uintptr_t TagLen, uintptr_t TagOffset)
62 : UntagMask(~(((uintptr_t(1) << TagLen) - 1) << TagOffset)) {}
63
64 template <typename T> constexpr T *operator()(T *P) {
65 return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(P) & UntagMask);
66 }
67
68 private:
69 uintptr_t UntagMask;
70 };
71
72 ExecutorAddr() = default;
73
74 /// Create an ExecutorAddr from the given value.
75 explicit constexpr ExecutorAddr(uint64_t Addr) : Addr(Addr) {}
76
77 /// Create an ExecutorAddr from the given pointer.
78 /// Warning: This should only be used when JITing in-process.
79 template <typename T, typename UnwrapFn = defaultUnwrap<T>>
80 static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap = UnwrapFn()) {
81 return ExecutorAddr(
82 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Unwrap(Ptr))));
83 }
84
85 /// Cast this ExecutorAddr to a pointer of the given type.
86 /// Warning: This should only be used when JITing in-process.
87 template <typename T, typename WrapFn = defaultWrap<std::remove_pointer_t<T>>>
88 std::enable_if_t<std::is_pointer<T>::value, T>
89 toPtr(WrapFn &&Wrap = WrapFn()) const {
90 uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
91 assert(IntPtr == Addr && "ExecutorAddr value out of range for uintptr_t");
92 return Wrap(reinterpret_cast<T>(IntPtr));
93 }
94
95 /// Cast this ExecutorAddr to a pointer of the given function type.
96 /// Warning: This should only be used when JITing in-process.
97 template <typename T, typename WrapFn = defaultWrap<T>>
98 std::enable_if_t<std::is_function<T>::value, T *>
99 toPtr(WrapFn &&Wrap = WrapFn()) const {
100 uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
101 assert(IntPtr == Addr && "ExecutorAddr value out of range for uintptr_t");
102 return Wrap(reinterpret_cast<T *>(IntPtr));
103 }
104
105 uint64_t getValue() const { return Addr; }
106 void setValue(uint64_t Addr) { this->Addr = Addr; }
107 bool isNull() const { return Addr == 0; }
108
109 explicit operator bool() const { return Addr != 0; }
110
111 friend bool operator==(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
112 return LHS.Addr == RHS.Addr;
113 }
114
115 friend bool operator!=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
116 return LHS.Addr != RHS.Addr;
117 }
118
119 friend bool operator<(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
120 return LHS.Addr < RHS.Addr;
121 }
122
123 friend bool operator<=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
124 return LHS.Addr <= RHS.Addr;
125 }
126
127 friend bool operator>(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
128 return LHS.Addr > RHS.Addr;
129 }
130
131 friend bool operator>=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
132 return LHS.Addr >= RHS.Addr;
133 }
134
136 ++Addr;
137 return *this;
138 }
140 --Addr;
141 return *this;
142 }
143 ExecutorAddr operator++(int) { return ExecutorAddr(Addr++); }
144 ExecutorAddr operator--(int) { return ExecutorAddr(Addr--); }
145
147 Addr += Delta;
148 return *this;
149 }
150
152 Addr -= Delta;
153 return *this;
154 }
155
156private:
157 uint64_t Addr = 0;
158};
159
160/// Subtracting two addresses yields an offset.
162 const ExecutorAddr &RHS) {
163 return ExecutorAddrDiff(LHS.getValue() - RHS.getValue());
164}
165
166/// Adding an offset and an address yields an address.
168 const ExecutorAddrDiff &RHS) {
169 return ExecutorAddr(LHS.getValue() + RHS);
170}
171
172/// Adding an address and an offset yields an address.
174 const ExecutorAddr &RHS) {
175 return ExecutorAddr(LHS + RHS.getValue());
176}
177
178/// Subtracting an offset from an address yields an address.
180 const ExecutorAddrDiff &RHS) {
181 return ExecutorAddr(LHS.getValue() - RHS);
182}
183
184/// Taking the modulus of an address and a diff yields a diff.
186 const ExecutorAddrDiff &RHS) {
187 return ExecutorAddrDiff(LHS.getValue() % RHS);
188}
189
190/// Represents an address range in the exceutor process.
192 ExecutorAddrRange() = default;
194 : Start(Start), End(End) {}
196 : Start(Start), End(Start + Size) {}
197
198 bool empty() const { return Start == End; }
199 ExecutorAddrDiff size() const { return End - Start; }
200
201 friend bool operator==(const ExecutorAddrRange &LHS,
202 const ExecutorAddrRange &RHS) {
203 return LHS.Start == RHS.Start && LHS.End == RHS.End;
204 }
205 friend bool operator!=(const ExecutorAddrRange &LHS,
206 const ExecutorAddrRange &RHS) {
207 return !(LHS == RHS);
208 }
209 friend bool operator<(const ExecutorAddrRange &LHS,
210 const ExecutorAddrRange &RHS) {
211 return LHS.Start < RHS.Start ||
212 (LHS.Start == RHS.Start && LHS.End < RHS.End);
213 }
214 friend bool operator<=(const ExecutorAddrRange &LHS,
215 const ExecutorAddrRange &RHS) {
216 return LHS.Start < RHS.Start ||
217 (LHS.Start == RHS.Start && LHS.End <= RHS.End);
218 }
219 friend bool operator>(const ExecutorAddrRange &LHS,
220 const ExecutorAddrRange &RHS) {
221 return LHS.Start > RHS.Start ||
222 (LHS.Start == RHS.Start && LHS.End > RHS.End);
223 }
224 friend bool operator>=(const ExecutorAddrRange &LHS,
225 const ExecutorAddrRange &RHS) {
226 return LHS.Start > RHS.Start ||
227 (LHS.Start == RHS.Start && LHS.End >= RHS.End);
228 }
229
230 bool contains(ExecutorAddr Addr) const { return Start <= Addr && Addr < End; }
232 return !(Other.End <= Start || End <= Other.Start);
233 }
234
237};
238
240 return OS << formatv("{0:x}", A.getValue());
241}
242
244 return OS << formatv("{0:x} -- {1:x}", R.Start.getValue(), R.End.getValue());
245}
246
247namespace shared {
248
250
251/// SPS serializatior for ExecutorAddr.
253public:
254 static size_t size(const ExecutorAddr &EA) {
256 }
257
258 static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddr &EA) {
260 }
261
262 static bool deserialize(SPSInputBuffer &BIB, ExecutorAddr &EA) {
263 uint64_t Tmp;
265 return false;
266 EA = ExecutorAddr(Tmp);
267 return true;
268 }
269};
270
272
273/// Serialization traits for address ranges.
274template <>
276public:
277 static size_t size(const ExecutorAddrRange &Value) {
279 Value.End);
280 }
281
284 BOB, Value.Start, Value.End);
285 }
286
289 BIB, Value.Start, Value.End);
290 }
291};
292
294
295} // End namespace shared.
296} // End namespace orc.
297
298// Provide DenseMapInfo for ExecutorAddrs.
299template <> struct DenseMapInfo<orc::ExecutorAddr> {
302 }
305 }
306
307 static unsigned getHashValue(const orc::ExecutorAddr &Addr) {
309 }
310
311 static bool isEqual(const orc::ExecutorAddr &LHS,
312 const orc::ExecutorAddr &RHS) {
313 return DenseMapInfo<uint64_t>::isEqual(LHS.getValue(), RHS.getValue());
314 }
315};
316
317} // End namespace llvm.
318
319#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file defines DenseMapInfo traits for DenseMap.
uint64_t Addr
uint64_t Size
#define P(N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Value * RHS
Value * LHS
LLVM Value Representation.
Definition: Value.h:74
Merges a tag into the raw address value: P' = P | (TagValue << TagOffset).
constexpr Tag(uintptr_t TagValue, uintptr_t TagOffset)
constexpr T * operator()(T *P)
Strips a tag of the given length from the given offset within the pointer: P' = P & ~(((1 << TagLen) ...
constexpr Untag(uintptr_t TagLen, uintptr_t TagOffset)
constexpr T * operator()(T *P)
Represents an address in the executor process.
ExecutorAddr & operator++()
friend bool operator==(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
ExecutorAddr operator--(int)
ExecutorAddr & operator-=(const ExecutorAddrDiff &Delta)
uint64_t getValue() const
void setValue(uint64_t Addr)
std::enable_if_t< std::is_function< T >::value, T * > toPtr(WrapFn &&Wrap=WrapFn()) const
Cast this ExecutorAddr to a pointer of the given function type.
ExecutorAddr operator++(int)
friend bool operator>(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap=UnwrapFn())
Create an ExecutorAddr from the given pointer.
friend bool operator>=(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
ExecutorAddr & operator--()
constexpr ExecutorAddr(uint64_t Addr)
Create an ExecutorAddr from the given value.
friend bool operator<=(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
friend bool operator<(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
ExecutorAddr & operator+=(const ExecutorAddrDiff &Delta)
friend bool operator!=(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
std::enable_if_t< std::is_pointer< T >::value, T > toPtr(WrapFn &&Wrap=WrapFn()) const
Cast this ExecutorAddr to a pointer of the given type.
A utility class for serializing to a blob from a variadic list.
Input char buffer with underflow check.
Output char buffer with overflow check.
static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddrRange &Value)
static bool deserialize(SPSInputBuffer &BIB, ExecutorAddrRange &Value)
static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddr &EA)
static bool deserialize(SPSInputBuffer &BIB, ExecutorAddr &EA)
Specialize to describe how to serialize/deserialize to/from the given concrete type.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
ExecutorAddrDiff operator%(const ExecutorAddr &LHS, const ExecutorAddrDiff &RHS)
Taking the modulus of an address and a diff yields a diff.
ExecutorAddr operator+(const ExecutorAddr &LHS, const ExecutorAddrDiff &RHS)
Adding an offset and an address yields an address.
uint64_t ExecutorAddrDiff
ExecutorAddrDiff operator-(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
Subtracting two addresses yields an offset.
raw_ostream & operator<<(raw_ostream &OS, const SymbolStringPtr &Sym)
Render a SymbolStringPtr.
Definition: DebugUtils.cpp:141
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
static unsigned getHashValue(const orc::ExecutorAddr &Addr)
static bool isEqual(const orc::ExecutorAddr &LHS, const orc::ExecutorAddr &RHS)
static orc::ExecutorAddr getTombstoneKey()
static orc::ExecutorAddr getEmptyKey()
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:51
Represents an address range in the exceutor process.
friend bool operator==(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)
bool overlaps(const ExecutorAddrRange &Other)
friend bool operator>=(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)
ExecutorAddrRange(ExecutorAddr Start, ExecutorAddr End)
friend bool operator!=(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)
friend bool operator<(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)
ExecutorAddrRange(ExecutorAddr Start, ExecutorAddrDiff Size)
ExecutorAddrDiff size() const
friend bool operator<=(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)
bool contains(ExecutorAddr Addr) const
friend bool operator>(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)