1//===-- InstrumentorVariables.inc.in - instrumentor variables -*- 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// This file is configured by the build system to define a variable containing
10// instrumentor runtime library source code for use by the instrumentor pass.
11//
12// The variant of this file not ending with .in has been autogenerated by the
13// LLVM build. Do not edit!
14//
15//===----------------------------------------------------------------------===//
16
17constexpr char InstrumentorRuntimeHelper[] =
18 R"(//===-- Instrumentor Runtime Helper Header -------------------------------===//
19//
20// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
21// See https://llvm.org/LICENSE.txt for license information.
22// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
23//
24//===----------------------------------------------------------------------===//
25//
26// This header provides helper structures and functions for reading data
27// generated by the LLVM Instrumentor pass and passed to runtime functions.
28//
29//===----------------------------------------------------------------------===//
30
31#ifndef INSTRUMENTOR_RUNTIME_H
32#define INSTRUMENTOR_RUNTIME_H
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38#include <stdint.h>
39#include <string.h>
40
41#ifdef __cplusplus
42}
43#endif
44
45/// Header for each value in a value pack. Value packs are used to pass function
46/// arguments and other variable-length data to the runtime. The format is:
47/// [ValueHeader][Padding][Value Data]
48/// where padding aligns the value data to 8-byte boundaries.
49typedef struct {
50 uint32_t size; // Size of the value in bytes
51 uint32_t type_id; // LLVM Type::TypeID of the value
52} ValuePackHeader;
53
54/// Iterator for reading values from a value pack.
55typedef struct {
56 const char *current; // Current position in the pack
57 uint64_t offset; // Byte offset from the start
58 uint32_t count; // Number of elements in the pack
59 uint32_t index; // Current element index
60} ValuePackIterator;
61
62/// Initialize a value pack iterator.
63/// \param iter The iterator to initialize
64/// \param pack_ptr Pointer to the start of the value pack
65/// \param num_elements Number of elements in the pack
66static inline void initValuePackIterator(ValuePackIterator *iter,
67 const void *pack_ptr,
68 uint32_t num_elements) {
69 iter->current = (const char *)pack_ptr;
70 iter->offset = 0;
71 iter->count = num_elements;
72 iter->index = 0;
73}
74
75/// Get the header for the current value.
76static inline ValuePackHeader
77getValuePackHeader(const ValuePackIterator *iter) {
78 const ValuePackHeader *header = (const ValuePackHeader *)iter->current;
79 return *header;
80}
81
82/// Get a pointer to the current value data.
83static inline const void *getValuePackData(const ValuePackIterator *iter) {
84 // Skip header (8 bytes: size + type_id)
85 const char *data_start = iter->current + sizeof(ValuePackHeader);
86 // Calculate padding for 8-byte alignment
87 ValuePackHeader header = getValuePackHeader(iter);
88 uint32_t padding = (8 - (header.size % 8)) % 8;
89 // Skip padding
90 return data_start + padding;
91}
92
93/// Move to the next value in the pack.
94static inline void nextValuePack(ValuePackIterator *iter) {
95 if (iter->index >= iter->count) {
96 iter->current = NULL;
97 return;
98 }
99 ValuePackHeader header = getValuePackHeader(iter);
100 uint32_t padding = (8 - (header.size % 8)) % 8;
101 uint64_t advance = sizeof(ValuePackHeader) + padding + header.size;
102 iter->current += advance;
103 iter->offset += advance;
104 iter->index++;
105}
106
107/// Get the current offset in bytes from the start of the pack.
108static inline uint64_t getValuePackOffset(const ValuePackIterator *iter) {
109 return iter->offset;
110}
111
112/// Extract a specific value from a value pack by index.
113///
114/// \param pack_ptr Pointer to the start of the value pack
115/// \param num_elements Number of elements in the pack
116/// \param index Zero-based index of the value to extract
117/// \param header Output parameter for the value header (can be NULL)
118/// \return Pointer to the value data, or NULL if index is out of bounds
119static inline const void *getValuePackEntry(const void *pack_ptr,
120 uint32_t num_elements,
121 uint32_t index,
122 ValuePackHeader *header) {
123 if (!pack_ptr || index >= num_elements)
124 return NULL;
125
126 ValuePackIterator iter;
127 initValuePackIterator(&iter, pack_ptr, num_elements);
128
129 while (iter.current != NULL && iter.index < iter.count) {
130 ValuePackHeader h = getValuePackHeader(&iter);
131 if (iter.index == index) {
132 if (header)
133 *header = h;
134 return getValuePackData(&iter);
135 }
136 nextValuePack(&iter);
137 }
138
139 return NULL; // Index out of bounds
140}
141
142/// LLVM Type IDs for interpreting value pack data.
143/// These correspond to llvm::Type::TypeID enum values.
144enum LLVMTypeID {
145 HalfTyID = 0, ///< 16-bit floating point type
146 BFloatTyID, ///< 16-bit floating point type (7-bit significand)
147 FloatTyID, ///< 32-bit floating point type
148 DoubleTyID, ///< 64-bit floating point type
149 X86_FP80TyID, ///< 80-bit floating point type (X87)
150 FP128TyID, ///< 128-bit floating point type (112-bit significand)
151 PPC_FP128TyID, ///< 128-bit floating point type (two 64-bits, PowerPC)
152 VoidTyID, ///< type with no size
153 LabelTyID, ///< Labels
154 MetadataTyID, ///< Metadata
155 X86_AMXTyID, ///< AMX vectors (8192 bits, X86 specific)
156 TokenTyID, ///< Tokens
157 // Derived types... see DerivedTypes.h file.
158 IntegerTyID, ///< Arbitrary bit width integers
159 ByteTyID, ///< Arbitrary bit width bytes
160 FunctionTyID, ///< Functions
161 PointerTyID, ///< Pointers
162 StructTyID, ///< Structures
163 ArrayTyID, ///< Arrays
164 FixedVectorTyID, ///< Fixed width SIMD vector type
165 ScalableVectorTyID, ///< Scalable SIMD vector type
166 TypedPointerTyID, ///< Typed pointer used by some GPU targets
167 TargetExtTyID, ///< Target extension type
168};
169
170/// Get the string name of an LLVM Type ID.
171static inline const char *getLLVMTypeIDName(int32_t type_id) {
172 switch (type_id) {
173 case -1:
174 return "none";
175 case HalfTyID:
176 return "half";
177 case BFloatTyID:
178 return "bfloat";
179 case FloatTyID:
180 return "float";
181 case DoubleTyID:
182 return "double";
183 case X86_FP80TyID:
184 return "x86_fp80";
185 case FP128TyID:
186 return "fp128";
187 case PPC_FP128TyID:
188 return "ppc_fp128";
189 case VoidTyID:
190 return "void";
191 case LabelTyID:
192 return "label";
193 case MetadataTyID:
194 return "metadata";
195 case X86_AMXTyID:
196 return "x86_amx";
197 case TokenTyID:
198 return "token";
199 case IntegerTyID:
200 return "integer";
201 case ByteTyID:
202 return "integer";
203 case FunctionTyID:
204 return "function";
205 case PointerTyID:
206 return "pointer";
207 case StructTyID:
208 return "struct";
209 case ArrayTyID:
210 return "array";
211 case FixedVectorTyID:
212 return "fixed_vector";
213 case ScalableVectorTyID:
214 return "scalable_vector";
215 case TypedPointerTyID:
216 return "typed_pointer";
217 case TargetExtTyID:
218 return "target_ext";
219 default:
220 return "unknown";
221 }
222}
223
224#ifdef __cplusplus
225
226// C++ overlays for range-based iteration and quality of life improvements
227
228/// Range wrapper for value packs enabling range-based for loops.
229/// Example:
230/// for (auto val : ValuePackRange(pack_ptr, num_elements)) {
231/// // val provides access to header and data
232/// }
233class ValuePackRange {
234public:
235 struct ValueRef {
236 ValuePackHeader header;
237 const void *data;
238
239 uint32_t type_id() const { return header.type_id; }
240 uint32_t size() const { return header.size; }
241 const char *type_name() const { return getLLVMTypeIDName(header.type_id); }
242
243 template <typename T> const T &as() const {
244 return *static_cast<const T *>(data);
245 }
246 template <typename T> const T *ptr() const {
247 return static_cast<const T *>(data);
248 }
249 };
250
251 class iterator {
252 public:
253 iterator(const void *ptr, uint32_t num_elements, uint64_t max_offset)
254 : max_offset_(max_offset) {
255 initValuePackIterator(&iter_, ptr, num_elements);
256 if (ptr && !is_valid_position())
257 iter_.current = nullptr;
258 }
259
260 ValueRef operator*() const {
261 return ValueRef{getValuePackHeader(&iter_), getValuePackData(&iter_)};
262 }
263
264 iterator &operator++() {
265 nextValuePack(&iter_);
266 if (!is_valid_position())
267 iter_.current = nullptr;
268 return *this;
269 }
270
271 bool operator!=(const iterator &other) const {
272 return iter_.current != other.iter_.current;
273 }
274
275 private:
276 bool is_valid_position() const {
277 if (!iter_.current)
278 return false;
279 if (iter_.index >= iter_.count)
280 return false;
281 if (max_offset_ > 0 && iter_.offset >= max_offset_)
282 return false;
283 return true;
284 }
285
286 ValuePackIterator iter_;
287 uint64_t max_offset_;
288 };
289
290 ValuePackRange(const void *ptr, uint32_t num_elements, uint64_t max_size = 0)
291 : ptr_(ptr), num_elements_(num_elements), max_size_(max_size) {}
292
293 iterator begin() const { return iterator(ptr_, num_elements_, max_size_); }
294 iterator end() const { return iterator(nullptr, 0, 0); }
295
296private:
297 const void *ptr_;
298 uint32_t num_elements_;
299 uint64_t max_size_;
300};
301
302/// Template helper to extract a typed value from a value pack by index.
303template <typename T>
304inline const T *getValueAs(const void *pack_ptr, uint32_t num_elements,
305 uint32_t index) {
306 return static_cast<const T *>(
307 getValuePackEntry(pack_ptr, num_elements, index, nullptr));
308}
309
310#endif // __cplusplus
311
312/// Bitmask flags for different instrumentation opportunities.
313
314/// NumericIO flag bitmask values.
315typedef enum NumericFlags {
316 NUMERIC_FLAG_NONE = 0,
317 NUMERIC_FLAG_NO_SIGNED_WRAP = 1 << 0,
318 NUMERIC_FLAG_NO_UNSIGNED_WRAP = 1 << 1,
319 NUMERIC_FLAG_HAS_NO_NANS = 1 << 2,
320 NUMERIC_FLAG_HAS_NO_INFS = 1 << 3,
321 NUMERIC_FLAG_HAS_NO_SIGNED_ZEROS = 1 << 4,
322 NUMERIC_FLAG_IS_DISJOINT = 1 << 5,
323 NUMERIC_FLAG_IS_EXACT = 1 << 6,
324} NumericFlags;
325
326/// CompareIO flag bitmask values.
327typedef enum CompareFlags {
328 COMPARE_FLAG_NONE = 0,
329 COMPARE_FLAG_SAMESIGN = 1 << 0,
330 COMPARE_FLAG_HAS_NO_NANS = 1 << 1,
331 COMPARE_FLAG_HAS_NO_INFS = 1 << 2,
332 COMPARE_FLAG_HAS_NO_SIGNED_ZEROS = 1 << 3,
333} CompareFlags;
334
335#endif // INSTRUMENTOR_RUNTIME_H
336)";
337