LLVM 23.0.0git
InstrumentorRuntimeHelper.h
Go to the documentation of this file.
1//===-- Instrumentor Runtime Helper Header -------------------------------===//
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// This header provides helper structures and functions for reading data
10// generated by the LLVM Instrumentor pass and passed to runtime functions.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef INSTRUMENTOR_RUNTIME_H
15#define INSTRUMENTOR_RUNTIME_H
16
17#ifdef __cplusplus
18extern "C" {
19#endif
20
21#include <stdint.h>
22#include <string.h>
23
24#ifdef __cplusplus
25}
26#endif
27
28/// Header for each value in a value pack. Value packs are used to pass function
29/// arguments and other variable-length data to the runtime. The format is:
30/// [ValueHeader][Padding][Value Data]
31/// where padding aligns the value data to 8-byte boundaries.
32typedef struct {
33 uint32_t size; // Size of the value in bytes
34 uint32_t type_id; // LLVM Type::TypeID of the value
36
37/// Iterator for reading values from a value pack.
38typedef struct {
39 const char *current; // Current position in the pack
40 uint64_t offset; // Byte offset from the start
41 uint32_t count; // Number of elements in the pack
42 uint32_t index; // Current element index
44
45/// Initialize a value pack iterator.
46/// \param iter The iterator to initialize
47/// \param pack_ptr Pointer to the start of the value pack
48/// \param num_elements Number of elements in the pack
50 const void *pack_ptr,
51 uint32_t num_elements) {
52 iter->current = (const char *)pack_ptr;
53 iter->offset = 0;
54 iter->count = num_elements;
55 iter->index = 0;
56}
57
58/// Get the header for the current value.
59static inline ValuePackHeader
61 const ValuePackHeader *header = (const ValuePackHeader *)iter->current;
62 return *header;
63}
64
65/// Get a pointer to the current value data.
66static inline const void *getValuePackData(const ValuePackIterator *iter) {
67 // Skip header (8 bytes: size + type_id)
68 const char *data_start = iter->current + sizeof(ValuePackHeader);
69 // Calculate padding for 8-byte alignment
71 uint32_t padding = (8 - (header.size % 8)) % 8;
72 // Skip padding
73 return data_start + padding;
74}
75
76/// Move to the next value in the pack.
77static inline void nextValuePack(ValuePackIterator *iter) {
78 if (iter->index >= iter->count) {
79 iter->current = NULL;
80 return;
81 }
83 uint32_t padding = (8 - (header.size % 8)) % 8;
84 uint64_t advance = sizeof(ValuePackHeader) + padding + header.size;
85 iter->current += advance;
86 iter->offset += advance;
87 iter->index++;
88}
89
90/// Get the current offset in bytes from the start of the pack.
91static inline uint64_t getValuePackOffset(const ValuePackIterator *iter) {
92 return iter->offset;
93}
94
95/// Extract a specific value from a value pack by index.
96///
97/// \param pack_ptr Pointer to the start of the value pack
98/// \param num_elements Number of elements in the pack
99/// \param index Zero-based index of the value to extract
100/// \param header Output parameter for the value header (can be NULL)
101/// \return Pointer to the value data, or NULL if index is out of bounds
102static inline const void *getValuePackEntry(const void *pack_ptr,
103 uint32_t num_elements,
104 uint32_t index,
105 ValuePackHeader *header) {
106 if (!pack_ptr || index >= num_elements)
107 return NULL;
108
110 initValuePackIterator(&iter, pack_ptr, num_elements);
111
112 while (iter.current != NULL && iter.index < iter.count) {
114 if (iter.index == index) {
115 if (header)
116 *header = h;
117 return getValuePackData(&iter);
118 }
119 nextValuePack(&iter);
120 }
121
122 return NULL; // Index out of bounds
123}
124
125/// LLVM Type IDs for interpreting value pack data.
126/// These correspond to llvm::Type::TypeID enum values.
128 HalfTyID = 0, ///< 16-bit floating point type
129 BFloatTyID, ///< 16-bit floating point type (7-bit significand)
130 FloatTyID, ///< 32-bit floating point type
131 DoubleTyID, ///< 64-bit floating point type
132 X86_FP80TyID, ///< 80-bit floating point type (X87)
133 FP128TyID, ///< 128-bit floating point type (112-bit significand)
134 PPC_FP128TyID, ///< 128-bit floating point type (two 64-bits, PowerPC)
135 VoidTyID, ///< type with no size
136 LabelTyID, ///< Labels
137 MetadataTyID, ///< Metadata
138 X86_AMXTyID, ///< AMX vectors (8192 bits, X86 specific)
139 TokenTyID, ///< Tokens
140 // Derived types... see DerivedTypes.h file.
141 IntegerTyID, ///< Arbitrary bit width integers
142 ByteTyID, ///< Arbitrary bit width bytes
143 FunctionTyID, ///< Functions
144 PointerTyID, ///< Pointers
145 StructTyID, ///< Structures
146 ArrayTyID, ///< Arrays
147 FixedVectorTyID, ///< Fixed width SIMD vector type
148 ScalableVectorTyID, ///< Scalable SIMD vector type
149 TypedPointerTyID, ///< Typed pointer used by some GPU targets
150 TargetExtTyID, ///< Target extension type
151};
152
153/// Get the string name of an LLVM Type ID.
154static inline const char *getLLVMTypeIDName(uint32_t type_id) {
155 switch (type_id) {
156 case HalfTyID:
157 return "half";
158 case BFloatTyID:
159 return "bfloat";
160 case FloatTyID:
161 return "float";
162 case DoubleTyID:
163 return "double";
164 case X86_FP80TyID:
165 return "x86_fp80";
166 case FP128TyID:
167 return "fp128";
168 case PPC_FP128TyID:
169 return "ppc_fp128";
170 case VoidTyID:
171 return "void";
172 case LabelTyID:
173 return "label";
174 case MetadataTyID:
175 return "metadata";
176 case X86_AMXTyID:
177 return "x86_amx";
178 case TokenTyID:
179 return "token";
180 case IntegerTyID:
181 return "integer";
182 case ByteTyID:
183 return "integer";
184 case FunctionTyID:
185 return "function";
186 case PointerTyID:
187 return "pointer";
188 case StructTyID:
189 return "struct";
190 case ArrayTyID:
191 return "array";
192 case FixedVectorTyID:
193 return "fixed_vector";
195 return "scalable_vector";
196 case TypedPointerTyID:
197 return "typed_pointer";
198 case TargetExtTyID:
199 return "target_ext";
200 default:
201 return "unknown";
202 }
203}
204
205#ifdef __cplusplus
206
207// C++ overlays for range-based iteration and quality of life improvements
208
209/// Range wrapper for value packs enabling range-based for loops.
210/// Example:
211/// for (auto val : ValuePackRange(pack_ptr, num_elements)) {
212/// // val provides access to header and data
213/// }
214class ValuePackRange {
215public:
216 struct ValueRef {
217 ValuePackHeader header;
218 const void *data;
219
220 uint32_t type_id() const { return header.type_id; }
221 uint32_t size() const { return header.size; }
222 const char *type_name() const { return getLLVMTypeIDName(header.type_id); }
223
224 template <typename T> const T &as() const {
225 return *static_cast<const T *>(data);
226 }
227 template <typename T> const T *ptr() const {
228 return static_cast<const T *>(data);
229 }
230 };
231
232 class iterator {
233 public:
234 iterator(const void *ptr, uint32_t num_elements, uint64_t max_offset)
235 : max_offset_(max_offset) {
236 initValuePackIterator(&iter_, ptr, num_elements);
237 if (ptr && !is_valid_position())
238 iter_.current = nullptr;
239 }
240
241 ValueRef operator*() const {
242 return ValueRef{getValuePackHeader(&iter_), getValuePackData(&iter_)};
243 }
244
245 iterator &operator++() {
246 nextValuePack(&iter_);
247 if (!is_valid_position())
248 iter_.current = nullptr;
249 return *this;
250 }
251
252 bool operator!=(const iterator &other) const {
253 return iter_.current != other.iter_.current;
254 }
255
256 private:
257 bool is_valid_position() const {
258 if (!iter_.current)
259 return false;
260 if (iter_.index >= iter_.count)
261 return false;
262 if (max_offset_ > 0 && iter_.offset >= max_offset_)
263 return false;
264 return true;
265 }
266
267 ValuePackIterator iter_;
268 uint64_t max_offset_;
269 };
270
271 ValuePackRange(const void *ptr, uint32_t num_elements, uint64_t max_size = 0)
272 : ptr_(ptr), num_elements_(num_elements), max_size_(max_size) {}
273
274 iterator begin() const { return iterator(ptr_, num_elements_, max_size_); }
275 iterator end() const { return iterator(nullptr, 0, 0); }
276
277private:
278 const void *ptr_;
279 uint32_t num_elements_;
280 uint64_t max_size_;
281};
282
283/// Template helper to extract a typed value from a value pack by index.
284template <typename T>
285inline const T *getValueAs(const void *pack_ptr, uint32_t num_elements,
286 uint32_t index) {
287 return static_cast<const T *>(
288 getValuePackEntry(pack_ptr, num_elements, index, nullptr));
289}
290
291#endif // __cplusplus
292
293#endif // INSTRUMENTOR_RUNTIME_H
static void nextValuePack(ValuePackIterator *iter)
Move to the next value in the pack.
static const char * getLLVMTypeIDName(uint32_t type_id)
Get the string name of an LLVM Type ID.
LLVMTypeID
LLVM Type IDs for interpreting value pack data.
@ StructTyID
Structures.
@ X86_FP80TyID
80-bit floating point type (X87)
@ FunctionTyID
Functions.
@ ArrayTyID
Arrays.
@ ScalableVectorTyID
Scalable SIMD vector type.
@ IntegerTyID
Arbitrary bit width integers.
@ X86_AMXTyID
AMX vectors (8192 bits, X86 specific)
@ FP128TyID
128-bit floating point type (112-bit significand)
@ TypedPointerTyID
Typed pointer used by some GPU targets.
@ LabelTyID
Labels.
@ ByteTyID
Arbitrary bit width bytes.
@ PointerTyID
Pointers.
@ TokenTyID
Tokens.
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
@ DoubleTyID
64-bit floating point type
@ FixedVectorTyID
Fixed width SIMD vector type.
@ HalfTyID
16-bit floating point type
@ BFloatTyID
16-bit floating point type (7-bit significand)
@ FloatTyID
32-bit floating point type
@ VoidTyID
type with no size
@ TargetExtTyID
Target extension type.
@ MetadataTyID
Metadata.
static uint64_t getValuePackOffset(const ValuePackIterator *iter)
Get the current offset in bytes from the start of the pack.
static const void * getValuePackData(const ValuePackIterator *iter)
Get a pointer to the current value data.
static ValuePackHeader getValuePackHeader(const ValuePackIterator *iter)
Get the header for the current value.
static void initValuePackIterator(ValuePackIterator *iter, const void *pack_ptr, uint32_t num_elements)
Initialize a value pack iterator.
static const void * getValuePackEntry(const void *pack_ptr, uint32_t num_elements, uint32_t index, ValuePackHeader *header)
Extract a specific value from a value pack by index.
#define T
static Split data
iterator end() const
Definition BasicBlock.h:89
BBIterator iterator
Definition BasicBlock.h:87
LLVM_ABI iterator begin() const
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1668
APInt operator*(APInt a, uint64_t RHS)
Definition APInt.h:2264
bool operator!=(uint64_t V1, const APInt &V2)
Definition APInt.h:2142
Header for each value in a value pack.
Iterator for reading values from a value pack.