[Instrumentor] Move instrumentor stub library into its own header file (#199329)

This patch depends on #198366. It moves the instrumentor runtime helper
header into its own file and makes it accessible as a string value to
the instrumentor pass.
This commit is contained in:
Ethan Luis McDonough authored and GitHub committed 2026-05-28 21:00:26 -05:00
1 parent 4910eda2a0
commit 7964b66bf5
5 files changed
+403 -341

No files matched your search

+9
View File
@@ -2,6 +2,15 @@
# LLVM_HEADERS_TABLEGEN points to `llvm-min-tblgen`
set(LLVM_TABLEGEN_PROJECT LLVM_HEADERS)
# Read instrumentor runtime helper header to a string for use in
# instrumentor pass
file(READ
${CMAKE_CURRENT_SOURCE_DIR}/Transforms/IPO/InstrumentorRuntimeHelper.h
LLVM_INSTRUMENTOR_RUNTIME_HELPER)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/Transforms/IPO/InstrumentorVariables.inc.in
${CMAKE_CURRENT_BINARY_DIR}/Transforms/IPO/InstrumentorVariables.inc @ONLY)
add_subdirectory(Analysis)
add_subdirectory(CodeGen)
add_subdirectory(IR)
@@ -0,0 +1,293 @@
//===-- Instrumentor Runtime Helper Header -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This header provides helper structures and functions for reading data
// generated by the LLVM Instrumentor pass and passed to runtime functions.
//
//===----------------------------------------------------------------------===//
#ifndef INSTRUMENTOR_RUNTIME_H
#define INSTRUMENTOR_RUNTIME_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
}
#endif
/// Header for each value in a value pack. Value packs are used to pass function
/// arguments and other variable-length data to the runtime. The format is:
/// [ValueHeader][Padding][Value Data]
/// where padding aligns the value data to 8-byte boundaries.
typedef struct {
uint32_t size; // Size of the value in bytes
uint32_t type_id; // LLVM Type::TypeID of the value
} ValuePackHeader;
/// Iterator for reading values from a value pack.
typedef struct {
const char *current; // Current position in the pack
uint64_t offset; // Byte offset from the start
uint32_t count; // Number of elements in the pack
uint32_t index; // Current element index
} ValuePackIterator;
/// Initialize a value pack iterator.
/// \param iter The iterator to initialize
/// \param pack_ptr Pointer to the start of the value pack
/// \param num_elements Number of elements in the pack
static inline void initValuePackIterator(ValuePackIterator *iter,
const void *pack_ptr,
uint32_t num_elements) {
iter->current = (const char *)pack_ptr;
iter->offset = 0;
iter->count = num_elements;
iter->index = 0;
}
/// Get the header for the current value.
static inline ValuePackHeader
getValuePackHeader(const ValuePackIterator *iter) {
const ValuePackHeader *header = (const ValuePackHeader *)iter->current;
return *header;
}
/// Get a pointer to the current value data.
static inline const void *getValuePackData(const ValuePackIterator *iter) {
// Skip header (8 bytes: size + type_id)
const char *data_start = iter->current + sizeof(ValuePackHeader);
// Calculate padding for 8-byte alignment
ValuePackHeader header = getValuePackHeader(iter);
uint32_t padding = (8 - (header.size % 8)) % 8;
// Skip padding
return data_start + padding;
}
/// Move to the next value in the pack.
static inline void nextValuePack(ValuePackIterator *iter) {
if (iter->index >= iter->count) {
iter->current = NULL;
return;
}
ValuePackHeader header = getValuePackHeader(iter);
uint32_t padding = (8 - (header.size % 8)) % 8;
uint64_t advance = sizeof(ValuePackHeader) + padding + header.size;
iter->current += advance;
iter->offset += advance;
iter->index++;
}
/// Get the current offset in bytes from the start of the pack.
static inline uint64_t getValuePackOffset(const ValuePackIterator *iter) {
return iter->offset;
}
/// Extract a specific value from a value pack by index.
///
/// \param pack_ptr Pointer to the start of the value pack
/// \param num_elements Number of elements in the pack
/// \param index Zero-based index of the value to extract
/// \param header Output parameter for the value header (can be NULL)
/// \return Pointer to the value data, or NULL if index is out of bounds
static inline const void *getValuePackEntry(const void *pack_ptr,
uint32_t num_elements,
uint32_t index,
ValuePackHeader *header) {
if (!pack_ptr || index >= num_elements)
return NULL;
ValuePackIterator iter;
initValuePackIterator(&iter, pack_ptr, num_elements);
while (iter.current != NULL && iter.index < iter.count) {
ValuePackHeader h = getValuePackHeader(&iter);
if (iter.index == index) {
if (header)
*header = h;
return getValuePackData(&iter);
}
nextValuePack(&iter);
}
return NULL; // Index out of bounds
}
/// LLVM Type IDs for interpreting value pack data.
/// These correspond to llvm::Type::TypeID enum values.
enum LLVMTypeID {
HalfTyID = 0, ///< 16-bit floating point type
BFloatTyID, ///< 16-bit floating point type (7-bit significand)
FloatTyID, ///< 32-bit floating point type
DoubleTyID, ///< 64-bit floating point type
X86_FP80TyID, ///< 80-bit floating point type (X87)
FP128TyID, ///< 128-bit floating point type (112-bit significand)
PPC_FP128TyID, ///< 128-bit floating point type (two 64-bits, PowerPC)
VoidTyID, ///< type with no size
LabelTyID, ///< Labels
MetadataTyID, ///< Metadata
X86_AMXTyID, ///< AMX vectors (8192 bits, X86 specific)
TokenTyID, ///< Tokens
// Derived types... see DerivedTypes.h file.
IntegerTyID, ///< Arbitrary bit width integers
ByteTyID, ///< Arbitrary bit width bytes
FunctionTyID, ///< Functions
PointerTyID, ///< Pointers
StructTyID, ///< Structures
ArrayTyID, ///< Arrays
FixedVectorTyID, ///< Fixed width SIMD vector type
ScalableVectorTyID, ///< Scalable SIMD vector type
TypedPointerTyID, ///< Typed pointer used by some GPU targets
TargetExtTyID, ///< Target extension type
};
/// Get the string name of an LLVM Type ID.
static inline const char *getLLVMTypeIDName(uint32_t type_id) {
switch (type_id) {
case HalfTyID:
return "half";
case BFloatTyID:
return "bfloat";
case FloatTyID:
return "float";
case DoubleTyID:
return "double";
case X86_FP80TyID:
return "x86_fp80";
case FP128TyID:
return "fp128";
case PPC_FP128TyID:
return "ppc_fp128";
case VoidTyID:
return "void";
case LabelTyID:
return "label";
case MetadataTyID:
return "metadata";
case X86_AMXTyID:
return "x86_amx";
case TokenTyID:
return "token";
case IntegerTyID:
return "integer";
case ByteTyID:
return "integer";
case FunctionTyID:
return "function";
case PointerTyID:
return "pointer";
case StructTyID:
return "struct";
case ArrayTyID:
return "array";
case FixedVectorTyID:
return "fixed_vector";
case ScalableVectorTyID:
return "scalable_vector";
case TypedPointerTyID:
return "typed_pointer";
case TargetExtTyID:
return "target_ext";
default:
return "unknown";
}
}
#ifdef __cplusplus
// C++ overlays for range-based iteration and quality of life improvements
/// Range wrapper for value packs enabling range-based for loops.
/// Example:
/// for (auto val : ValuePackRange(pack_ptr, num_elements)) {
/// // val provides access to header and data
/// }
class ValuePackRange {
public:
struct ValueRef {
ValuePackHeader header;
const void *data;
uint32_t type_id() const { return header.type_id; }
uint32_t size() const { return header.size; }
const char *type_name() const { return getLLVMTypeIDName(header.type_id); }
template <typename T> const T &as() const {
return *static_cast<const T *>(data);
}
template <typename T> const T *ptr() const {
return static_cast<const T *>(data);
}
};
class iterator {
public:
iterator(const void *ptr, uint32_t num_elements, uint64_t max_offset)
: max_offset_(max_offset) {
initValuePackIterator(&iter_, ptr, num_elements);
if (ptr && !is_valid_position())
iter_.current = nullptr;
}
ValueRef operator*() const {
return ValueRef{getValuePackHeader(&iter_), getValuePackData(&iter_)};
}
iterator &operator++() {
nextValuePack(&iter_);
if (!is_valid_position())
iter_.current = nullptr;
return *this;
}
bool operator!=(const iterator &other) const {
return iter_.current != other.iter_.current;
}
private:
bool is_valid_position() const {
if (!iter_.current)
return false;
if (iter_.index >= iter_.count)
return false;
if (max_offset_ > 0 && iter_.offset >= max_offset_)
return false;
return true;
}
ValuePackIterator iter_;
uint64_t max_offset_;
};
ValuePackRange(const void *ptr, uint32_t num_elements, uint64_t max_size = 0)
: ptr_(ptr), num_elements_(num_elements), max_size_(max_size) {}
iterator begin() const { return iterator(ptr_, num_elements_, max_size_); }
iterator end() const { return iterator(nullptr, 0, 0); }
private:
const void *ptr_;
uint32_t num_elements_;
uint64_t max_size_;
};
/// Template helper to extract a typed value from a value pack by index.
template <typename T>
inline const T *getValueAs(const void *pack_ptr, uint32_t num_elements,
uint32_t index) {
return static_cast<const T *>(
getValuePackEntry(pack_ptr, num_elements, index, nullptr));
}
#endif // __cplusplus
#endif // INSTRUMENTOR_RUNTIME_H
@@ -0,0 +1,18 @@
//===-- InstrumentorVariables.inc.in - instrumentor variables -*- C++ -*---===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is configured by the build system to define a variable containing
// instrumentor runtime library source code for use by the instrumentor pass.
//
// The variant of this file not ending with .in has been autogenerated by the
// LLVM build. Do not edit!
//
//===----------------------------------------------------------------------===//
constexpr char InstrumentorRuntimeHelper[] =
R"(@LLVM_INSTRUMENTOR_RUNTIME_HELPER@)";
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/IPO/Instrumentor.h"
#include "llvm/Transforms/IPO/InstrumentorVariables.inc"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -242,298 +243,8 @@ void printRuntimeHeader(const InstrumentationConfig &IConf,
StringRef Prefix = IConf.getRTName();
OS << "//===-- Instrumentor Runtime Helper Header "
"-------------------------------===//\n";
OS << "//\n";
OS << "// Part of the LLVM Project, under the Apache License v2.0 with LLVM "
"Exceptions.\n";
OS << "// See https://llvm.org/LICENSE.txt for license information.\n";
OS << "// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n";
OS << "//\n";
OS << "//"
"===-------------------------------------------------------------------"
"---===//\n";
OS << "//\n";
OS << "// This header provides helper structures and functions for reading "
"data\n";
OS << "// generated by the LLVM Instrumentor pass and passed to runtime "
"functions.\n";
OS << "//\n";
OS << "// Generated with runtime prefix: " << Prefix << "\n";
OS << "//\n";
OS << "//"
"===-------------------------------------------------------------------"
"---===//\n\n";
OS << "#ifndef INSTRUMENTOR_RUNTIME_H\n";
OS << "#define INSTRUMENTOR_RUNTIME_H\n\n";
OS << "#ifdef __cplusplus\n";
OS << "extern \"C\" {\n";
OS << "#endif\n\n";
OS << "#include <stdint.h>\n";
OS << "#include <string.h>\n\n";
OS << "#ifdef __cplusplus\n";
OS << "}\n";
OS << "#endif\n\n";
// Value pack structures
OS << "/// Header for each value in a value pack.\n";
OS << "/// Value packs are used to pass function arguments and other "
"variable-length\n";
OS << "/// data to the runtime. The format is:\n";
OS << "/// [ValueHeader][Padding][Value Data]\n";
OS << "/// where padding aligns the value data to 8-byte boundaries.\n";
OS << "typedef struct {\n";
OS << " uint32_t size; // Size of the value in bytes\n";
OS << " uint32_t type_id; // LLVM Type::TypeID of the value\n";
OS << "} ValuePackHeader;\n\n";
// Value pack iterator
OS << "/// Iterator for reading values from a value pack.\n";
OS << "typedef struct {\n";
OS << " const char *current; // Current position in the pack\n";
OS << " uint64_t offset; // Byte offset from the start\n";
OS << " uint32_t count; // Number of elements in the pack\n";
OS << " uint32_t index; // Current element index\n";
OS << "} ValuePackIterator;\n\n";
OS << "/// Initialize a value pack iterator.\n";
OS << "/// \\param iter The iterator to initialize\n";
OS << "/// \\param pack_ptr Pointer to the start of the value pack\n";
OS << "/// \\param num_elements Number of elements in the pack\n";
OS << "static inline void initValuePackIterator(ValuePackIterator *iter, "
"const void *pack_ptr, uint32_t num_elements) {\n";
OS << " iter->current = (const char *)pack_ptr;\n";
OS << " iter->offset = 0;\n";
OS << " iter->count = num_elements;\n";
OS << " iter->index = 0;\n";
OS << "}\n\n";
OS << "/// Get the header for the current value.\n";
OS << "static inline ValuePackHeader getValuePackHeader(const "
"ValuePackIterator *iter) {\n";
OS << " const ValuePackHeader *header = (const ValuePackHeader "
"*)iter->current;\n";
OS << " return *header;\n";
OS << "}\n\n";
OS << "/// Get a pointer to the current value data.\n";
OS << "static inline const void *getValuePackData(const ValuePackIterator "
"*iter) {\n";
OS << " // Skip header (8 bytes: size + type_id)\n";
OS << " const char *data_start = iter->current + sizeof(ValuePackHeader);\n";
OS << " // Calculate padding for 8-byte alignment\n";
OS << " ValuePackHeader header = getValuePackHeader(iter);\n";
OS << " uint32_t padding = (8 - (header.size % 8)) % 8;\n";
OS << " // Skip padding\n";
OS << " return data_start + padding;\n";
OS << "}\n\n";
OS << "/// Move to the next value in the pack.\n";
OS << "static inline void nextValuePack(ValuePackIterator *iter) {\n";
OS << " if (iter->index >= iter->count) {\n";
OS << " iter->current = NULL;\n";
OS << " return;\n";
OS << " }\n";
OS << " ValuePackHeader header = getValuePackHeader(iter);\n";
OS << " uint32_t padding = (8 - (header.size % 8)) % 8;\n";
OS << " uint64_t advance = sizeof(ValuePackHeader) + padding + "
"header.size;\n";
OS << " iter->current += advance;\n";
OS << " iter->offset += advance;\n";
OS << " iter->index++;\n";
OS << "}\n\n";
OS << "/// Get the current offset in bytes from the start of the pack.\n";
OS << "static inline uint64_t getValuePackOffset(const ValuePackIterator "
"*iter) {\n";
OS << " return iter->offset;\n";
OS << "}\n\n";
OS << "/// Extract a specific value from a value pack by index.\n";
OS << "///\n";
OS << "/// \\param pack_ptr Pointer to the start of the value pack\n";
OS << "/// \\param num_elements Number of elements in the pack\n";
OS << "/// \\param index Zero-based index of the value to extract\n";
OS << "/// \\param header Output parameter for the value header (can be "
"NULL)\n";
OS << "/// \\return Pointer to the value data, or NULL if index is out of "
"bounds\n";
OS << "static inline const void *getValuePackEntry(const void *pack_ptr, "
"uint32_t num_elements,\n";
OS << " uint32_t index, "
"ValuePackHeader *header) {\n";
OS << " if (!pack_ptr || index >= num_elements)\n";
OS << " return NULL;\n\n";
OS << " ValuePackIterator iter;\n";
OS << " initValuePackIterator(&iter, pack_ptr, num_elements);\n\n";
OS << " while (iter.current != NULL && iter.index < iter.count) {\n";
OS << " ValuePackHeader h = getValuePackHeader(&iter);\n";
OS << " if (iter.index == index) {\n";
OS << " if (header)\n";
OS << " *header = h;\n";
OS << " return getValuePackData(&iter);\n";
OS << " }\n";
OS << " nextValuePack(&iter);\n";
OS << " }\n\n";
OS << " return NULL; // Index out of bounds\n";
OS << "}\n\n";
// LLVM Type IDs enum
OS << "/// LLVM Type IDs for interpreting value pack data.\n";
OS << "/// These correspond to llvm::Type::TypeID enum values.\n";
OS << "enum LLVMTypeID {\n";
OS << " HalfTyID = 0, ///< 16-bit floating point type\n";
OS << " BFloatTyID, ///< 16-bit floating point type (7-bit "
"significand)\n";
OS << " FloatTyID, ///< 32-bit floating point type\n";
OS << " DoubleTyID, ///< 64-bit floating point type\n";
OS << " X86_FP80TyID, ///< 80-bit floating point type (X87)\n";
OS << " FP128TyID, ///< 128-bit floating point type (112-bit "
"significand)\n";
OS << " PPC_FP128TyID, ///< 128-bit floating point type (two 64-bits, "
"PowerPC)\n";
OS << " VoidTyID, ///< type with no size\n";
OS << " LabelTyID, ///< Labels\n";
OS << " MetadataTyID, ///< Metadata\n";
OS << " X86_AMXTyID, ///< AMX vectors (8192 bits, X86 specific)\n";
OS << " TokenTyID, ///< Tokens\n";
OS << " // Derived types... see DerivedTypes.h file.\n";
OS << " IntegerTyID, ///< Arbitrary bit width integers\n";
OS << " ByteTyID, ///< Arbitrary bit width bytes\n";
OS << " FunctionTyID, ///< Functions\n";
OS << " PointerTyID, ///< Pointers\n";
OS << " StructTyID, ///< Structures\n";
OS << " ArrayTyID, ///< Arrays\n";
OS << " FixedVectorTyID, ///< Fixed width SIMD vector type\n";
OS << " ScalableVectorTyID, ///< Scalable SIMD vector type\n";
OS << " TypedPointerTyID, ///< Typed pointer used by some GPU targets\n";
OS << " TargetExtTyID, ///< Target extension type\n";
OS << "};\n\n";
// Type ID printer function
OS << "/// Get the string name of an LLVM Type ID.\n";
OS << "static inline const char *getLLVMTypeIDName(uint32_t type_id) {\n";
OS << " switch (type_id) {\n";
OS << " case HalfTyID: return \"half\";\n";
OS << " case BFloatTyID: return \"bfloat\";\n";
OS << " case FloatTyID: return \"float\";\n";
OS << " case DoubleTyID: return \"double\";\n";
OS << " case X86_FP80TyID: return \"x86_fp80\";\n";
OS << " case FP128TyID: return \"fp128\";\n";
OS << " case PPC_FP128TyID: return \"ppc_fp128\";\n";
OS << " case VoidTyID: return \"void\";\n";
OS << " case LabelTyID: return \"label\";\n";
OS << " case MetadataTyID: return \"metadata\";\n";
OS << " case X86_AMXTyID: return \"x86_amx\";\n";
OS << " case TokenTyID: return \"token\";\n";
OS << " case IntegerTyID: return \"integer\";\n";
OS << " case ByteTyID: return \"integer\";\n";
OS << " case FunctionTyID: return \"function\";\n";
OS << " case PointerTyID: return \"pointer\";\n";
OS << " case StructTyID: return \"struct\";\n";
OS << " case ArrayTyID: return \"array\";\n";
OS << " case FixedVectorTyID: return \"fixed_vector\";\n";
OS << " case ScalableVectorTyID: return \"scalable_vector\";\n";
OS << " case TypedPointerTyID: return \"typed_pointer\";\n";
OS << " case TargetExtTyID: return \"target_ext\";\n";
OS << " default: return \"unknown\";\n";
OS << " }\n";
OS << "}\n\n";
// C++ overlays section
OS << "#ifdef __cplusplus\n\n";
OS << "// C++ overlays for range-based iteration and quality of life "
"improvements\n\n";
// ValuePackRange class
OS << "/// Range wrapper for value packs enabling range-based for loops.\n";
OS << "/// Example:\n";
OS << "/// for (auto val : ValuePackRange(pack_ptr, num_elements)) {\n";
OS << "/// // val provides access to header and data\n";
OS << "/// }\n";
OS << "class ValuePackRange {\n";
OS << "public:\n";
OS << " struct ValueRef {\n";
OS << " ValuePackHeader header;\n";
OS << " const void *data;\n\n";
OS << " uint32_t type_id() const { return header.type_id; }\n";
OS << " uint32_t size() const { return header.size; }\n";
OS << " const char *type_name() const { return "
"getLLVMTypeIDName(header.type_id); }\n\n";
OS << " template <typename T> const T &as() const {\n";
OS << " return *static_cast<const T*>(data);\n";
OS << " }\n";
OS << " template <typename T> const T *ptr() const {\n";
OS << " return static_cast<const T*>(data);\n";
OS << " }\n";
OS << " };\n\n";
OS << " class iterator {\n";
OS << " public:\n";
OS << " iterator(const void *ptr, uint32_t num_elements, uint64_t "
"max_offset)\n";
OS << " : max_offset_(max_offset) {\n";
OS << " initValuePackIterator(&iter_, ptr, num_elements);\n";
OS << " if (ptr && !is_valid_position()) iter_.current = nullptr;\n";
OS << " }\n\n";
OS << " ValueRef operator*() const {\n";
OS << " return ValueRef{\n";
OS << " getValuePackHeader(&iter_),\n";
OS << " getValuePackData(&iter_)\n";
OS << " };\n";
OS << " }\n\n";
OS << " iterator &operator++() {\n";
OS << " nextValuePack(&iter_);\n";
OS << " if (!is_valid_position()) iter_.current = nullptr;\n";
OS << " return *this;\n";
OS << " }\n\n";
OS << " bool operator!=(const iterator &other) const {\n";
OS << " return iter_.current != other.iter_.current;\n";
OS << " }\n\n";
OS << " private:\n";
OS << " bool is_valid_position() const {\n";
OS << " if (!iter_.current) return false;\n";
OS << " if (iter_.index >= iter_.count) return false;\n";
OS << " if (max_offset_ > 0 && iter_.offset >= max_offset_) return "
"false;\n";
OS << " return true;\n";
OS << " }\n\n";
OS << " ValuePackIterator iter_;\n";
OS << " uint64_t max_offset_;\n";
OS << " };\n\n";
OS << " ValuePackRange(const void *ptr, uint32_t num_elements, uint64_t "
"max_size = 0)\n";
OS << " : ptr_(ptr), num_elements_(num_elements), max_size_(max_size) "
"{}\n\n";
OS << " iterator begin() const { return iterator(ptr_, num_elements_, "
"max_size_); }\n";
OS << " iterator end() const { return iterator(nullptr, 0, 0); }\n\n";
OS << "private:\n";
OS << " const void *ptr_;\n";
OS << " uint32_t num_elements_;\n";
OS << " uint64_t max_size_;\n";
OS << "};\n\n";
// Helper template functions
OS << "/// Template helper to extract a typed value from a value pack by "
"index.\n";
OS << "template <typename T>\n";
OS << "inline const T *getValueAs(const void *pack_ptr, uint32_t "
"num_elements, uint32_t index) {\n";
OS << " return static_cast<const T*>(getValuePackEntry(pack_ptr, "
"num_elements, index, nullptr));\n";
OS << "}\n\n";
OS << "#endif // __cplusplus\n\n";
OS << "#endif // INSTRUMENTOR_RUNTIME_H\n";
OS << InstrumentorRuntimeHelper;
OS << "\n// Generated with runtime prefix: " << Prefix << "\n";
}
void printRuntimeStub(const InstrumentationConfig &IConf,
@@ -9,8 +9,6 @@
// This header provides helper structures and functions for reading data
// generated by the LLVM Instrumentor pass and passed to runtime functions.
//
// Generated with runtime prefix: __instrumentor_
//
//===----------------------------------------------------------------------===//
#ifndef INSTRUMENTOR_RUNTIME_H
@@ -27,9 +25,8 @@ extern "C" {
}
#endif
/// Header for each value in a value pack.
/// Value packs are used to pass function arguments and other variable-length
/// data to the runtime. The format is:
/// Header for each value in a value pack. Value packs are used to pass function
/// arguments and other variable-length data to the runtime. The format is:
/// [ValueHeader][Padding][Value Data]
/// where padding aligns the value data to 8-byte boundaries.
typedef struct {
@@ -39,17 +36,19 @@ typedef struct {
/// Iterator for reading values from a value pack.
typedef struct {
const char *current; // Current position in the pack
uint64_t offset; // Byte offset from the start
uint32_t count; // Number of elements in the pack
uint32_t index; // Current element index
const char *current; // Current position in the pack
uint64_t offset; // Byte offset from the start
uint32_t count; // Number of elements in the pack
uint32_t index; // Current element index
} ValuePackIterator;
/// Initialize a value pack iterator.
/// \param iter The iterator to initialize
/// \param pack_ptr Pointer to the start of the value pack
/// \param num_elements Number of elements in the pack
static inline void initValuePackIterator(ValuePackIterator *iter, const void *pack_ptr, uint32_t num_elements) {
static inline void initValuePackIterator(ValuePackIterator *iter,
const void *pack_ptr,
uint32_t num_elements) {
iter->current = (const char *)pack_ptr;
iter->offset = 0;
iter->count = num_elements;
@@ -57,7 +56,8 @@ static inline void initValuePackIterator(ValuePackIterator *iter, const void *pa
}
/// Get the header for the current value.
static inline ValuePackHeader getValuePackHeader(const ValuePackIterator *iter) {
static inline ValuePackHeader
getValuePackHeader(const ValuePackIterator *iter) {
const ValuePackHeader *header = (const ValuePackHeader *)iter->current;
return *header;
}
@@ -99,8 +99,10 @@ static inline uint64_t getValuePackOffset(const ValuePackIterator *iter) {
/// \param index Zero-based index of the value to extract
/// \param header Output parameter for the value header (can be NULL)
/// \return Pointer to the value data, or NULL if index is out of bounds
static inline const void *getValuePackEntry(const void *pack_ptr, uint32_t num_elements,
uint32_t index, ValuePackHeader *header) {
static inline const void *getValuePackEntry(const void *pack_ptr,
uint32_t num_elements,
uint32_t index,
ValuePackHeader *header) {
if (!pack_ptr || index >= num_elements)
return NULL;
@@ -151,29 +153,52 @@ enum LLVMTypeID {
/// Get the string name of an LLVM Type ID.
static inline const char *getLLVMTypeIDName(uint32_t type_id) {
switch (type_id) {
case HalfTyID: return "half";
case BFloatTyID: return "bfloat";
case FloatTyID: return "float";
case DoubleTyID: return "double";
case X86_FP80TyID: return "x86_fp80";
case FP128TyID: return "fp128";
case PPC_FP128TyID: return "ppc_fp128";
case VoidTyID: return "void";
case LabelTyID: return "label";
case MetadataTyID: return "metadata";
case X86_AMXTyID: return "x86_amx";
case TokenTyID: return "token";
case IntegerTyID: return "integer";
case ByteTyID: return "integer";
case FunctionTyID: return "function";
case PointerTyID: return "pointer";
case StructTyID: return "struct";
case ArrayTyID: return "array";
case FixedVectorTyID: return "fixed_vector";
case ScalableVectorTyID: return "scalable_vector";
case TypedPointerTyID: return "typed_pointer";
case TargetExtTyID: return "target_ext";
default: return "unknown";
case HalfTyID:
return "half";
case BFloatTyID:
return "bfloat";
case FloatTyID:
return "float";
case DoubleTyID:
return "double";
case X86_FP80TyID:
return "x86_fp80";
case FP128TyID:
return "fp128";
case PPC_FP128TyID:
return "ppc_fp128";
case VoidTyID:
return "void";
case LabelTyID:
return "label";
case MetadataTyID:
return "metadata";
case X86_AMXTyID:
return "x86_amx";
case TokenTyID:
return "token";
case IntegerTyID:
return "integer";
case ByteTyID:
return "integer";
case FunctionTyID:
return "function";
case PointerTyID:
return "pointer";
case StructTyID:
return "struct";
case ArrayTyID:
return "array";
case FixedVectorTyID:
return "fixed_vector";
case ScalableVectorTyID:
return "scalable_vector";
case TypedPointerTyID:
return "typed_pointer";
case TargetExtTyID:
return "target_ext";
default:
return "unknown";
}
}
@@ -197,10 +222,10 @@ public:
const char *type_name() const { return getLLVMTypeIDName(header.type_id); }
template <typename T> const T &as() const {
return *static_cast<const T*>(data);
return *static_cast<const T *>(data);
}
template <typename T> const T *ptr() const {
return static_cast<const T*>(data);
return static_cast<const T *>(data);
}
};
@@ -209,19 +234,18 @@ public:
iterator(const void *ptr, uint32_t num_elements, uint64_t max_offset)
: max_offset_(max_offset) {
initValuePackIterator(&iter_, ptr, num_elements);
if (ptr && !is_valid_position()) iter_.current = nullptr;
if (ptr && !is_valid_position())
iter_.current = nullptr;
}
ValueRef operator*() const {
return ValueRef{
getValuePackHeader(&iter_),
getValuePackData(&iter_)
};
return ValueRef{getValuePackHeader(&iter_), getValuePackData(&iter_)};
}
iterator &operator++() {
nextValuePack(&iter_);
if (!is_valid_position()) iter_.current = nullptr;
if (!is_valid_position())
iter_.current = nullptr;
return *this;
}
@@ -231,9 +255,12 @@ public:
private:
bool is_valid_position() const {
if (!iter_.current) return false;
if (iter_.index >= iter_.count) return false;
if (max_offset_ > 0 && iter_.offset >= max_offset_) return false;
if (!iter_.current)
return false;
if (iter_.index >= iter_.count)
return false;
if (max_offset_ > 0 && iter_.offset >= max_offset_)
return false;
return true;
}
@@ -255,10 +282,14 @@ private:
/// Template helper to extract a typed value from a value pack by index.
template <typename T>
inline const T *getValueAs(const void *pack_ptr, uint32_t num_elements, uint32_t index) {
return static_cast<const T*>(getValuePackEntry(pack_ptr, num_elements, index, nullptr));
inline const T *getValueAs(const void *pack_ptr, uint32_t num_elements,
uint32_t index) {
return static_cast<const T *>(
getValuePackEntry(pack_ptr, num_elements, index, nullptr));
}
#endif // __cplusplus
#endif // INSTRUMENTOR_RUNTIME_H
// Generated with runtime prefix: __instrumentor_