From 15a845eced902d40438054f036c47cc9c202f241 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Sun, 2 Mar 2025 23:21:17 +0800 Subject: [PATCH 1/2] [llvm-c] Add `LLVMConstDataArray` and `LLVMGetRawDataValues` --- llvm/docs/ReleaseNotes.md | 4 ++++ llvm/include/llvm-c/Core.h | 23 +++++++++++++++++++++++ llvm/lib/IR/Core.cpp | 13 +++++++++++++ llvm/test/Bindings/llvm-c/echo.ll | 1 + llvm/tools/llvm-c-test/echo.cpp | 17 ++++++++++++----- 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index f1f64f77ee71a..9a7aae7aa2f15 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -139,6 +139,10 @@ Changes to the C API * `LLVMConstNUWMul` * `LLVMConstNSWMul` +* Added `LLVMConstDataArray` and `LLVMGetRawDataValues` to allow creating and + reading `ConstantDataArray` values without needing extra `LLVMValueRef`s for + individual elements. + Changes to the CodeGen infrastructure ------------------------------------- diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index a414e2061a595..2d6158229b9c3 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -2350,6 +2350,16 @@ LLVMBool LLVMIsConstantString(LLVMValueRef c); */ const char *LLVMGetAsString(LLVMValueRef c, size_t *Length); +/** + * Get the raw, underlying bytes of the given constant data sequential. + * + * This is the same as LLVMGetAsString except it works for all constant data + * sequentials, not just i8 arrays. + * + * @see ConstantDataSequential::getRawDataValues() + */ +const char *LLVMGetRawDataValues(LLVMValueRef c, size_t *SizeInBytes); + /** * Create an anonymous ConstantStruct with the specified values. * @@ -2388,6 +2398,19 @@ LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, LLVMValueRef LLVMConstArray2(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals, uint64_t Length); +/** + * Create a ConstantDataArray from raw values. + * + * ElementTy must be one of i8, i16, i32, i64, half, bfloat, float, or double. + * Data points to a contiguous buffer of raw values with the appropriate + * endianness. The element count is inferred from the element type and the data + * size in bytes. + * + * @see llvm::ConstantDataArray::getRaw() + */ +LLVMValueRef LLVMConstDataArray(LLVMTypeRef ElementTy, const char *Data, + size_t SizeInBytes); + /** * Create a non-anonymous ConstantStruct from values. * diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 88b89c52c19a2..2941b4ea2ca2e 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -1643,6 +1643,12 @@ const char *LLVMGetAsString(LLVMValueRef C, size_t *Length) { return Str.data(); } +const char *LLVMGetRawDataValues(LLVMValueRef C, size_t *SizeInBytes) { + StringRef Str = unwrap(C)->getRawDataValues(); + *SizeInBytes = Str.size(); + return Str.data(); +} + LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals, unsigned Length) { ArrayRef V(unwrap(ConstantVals, Length), Length); @@ -1655,6 +1661,13 @@ LLVMValueRef LLVMConstArray2(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals, return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), V)); } +LLVMValueRef LLVMConstDataArray(LLVMTypeRef ElementTy, const char *Data, + size_t SizeInBytes) { + Type *Ty = unwrap(ElementTy); + size_t Len = SizeInBytes / (Ty->getPrimitiveSizeInBits() / 8); + return wrap(ConstantDataArray::getRaw(StringRef(Data, SizeInBytes), Len, Ty)); +} + LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed) { diff --git a/llvm/test/Bindings/llvm-c/echo.ll b/llvm/test/Bindings/llvm-c/echo.ll index c4b932034b501..0a688afab6125 100644 --- a/llvm/test/Bindings/llvm-c/echo.ll +++ b/llvm/test/Bindings/llvm-c/echo.ll @@ -17,6 +17,7 @@ module asm "classical GAS" @arr = linkonce_odr global [5 x i8] [ i8 2, i8 3, i8 5, i8 7, i8 11 ] @str = private unnamed_addr constant [13 x i8] c"hello world\0A\00" @locStr = private local_unnamed_addr constant [13 x i8] c"hello world\0A\00" +@caLarge = private constant [2 x i128] [ i128 12345, i128 67890 ] @hidden = hidden global i32 7 @protected = protected global i32 23 @section = global i32 27, section ".custom" diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp index 4173e49e60a04..3ec40fdba0bad 100644 --- a/llvm/tools/llvm-c-test/echo.cpp +++ b/llvm/tools/llvm-c-test/echo.cpp @@ -317,11 +317,18 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) { return LLVMConstNull(TypeCloner(M).Clone(Cst)); } - // Try constant array or constant data array - if (LLVMIsAConstantArray(Cst) || LLVMIsAConstantDataArray(Cst)) { - check_value_kind(Cst, LLVMIsAConstantArray(Cst) - ? LLVMConstantArrayValueKind - : LLVMConstantDataArrayValueKind); + // Try constant data array + if (LLVMIsAConstantDataArray(Cst)) { + check_value_kind(Cst, LLVMConstantDataArrayValueKind); + LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); + size_t SizeInBytes; + const char *Data = LLVMGetRawDataValues(Cst, &SizeInBytes); + return LLVMConstDataArray(LLVMGetElementType(Ty), Data, SizeInBytes); + } + + // Try constant array + if (LLVMIsAConstantArray(Cst)) { + check_value_kind(Cst, LLVMConstantArrayValueKind); LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); uint64_t EltCount = LLVMGetArrayLength2(Ty); SmallVector Elts; From a2a14b23b01e6f18bd1629322b3bdc1fb4542407 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Fri, 25 Apr 2025 15:49:38 +0800 Subject: [PATCH 2/2] host endianness --- llvm/include/llvm-c/Core.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index faff148615d86..596531c93a949 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -2402,9 +2402,8 @@ LLVMValueRef LLVMConstArray2(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals, * Create a ConstantDataArray from raw values. * * ElementTy must be one of i8, i16, i32, i64, half, bfloat, float, or double. - * Data points to a contiguous buffer of raw values with the appropriate - * endianness. The element count is inferred from the element type and the data - * size in bytes. + * Data points to a contiguous buffer of raw values in the host endianness. The + * element count is inferred from the element type and the data size in bytes. * * @see llvm::ConstantDataArray::getRaw() */