CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
296 lines
9.0 KiB
C++
296 lines
9.0 KiB
C++
//===-- 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
|
|
|
|
// Generated with runtime prefix: __instrumentor_
|