[llvm] [llvm-c] Add `LLVMConstDataArray` and `LLVMGetRawDataValues` (PR #129440)

Quinton Miller via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 25 00:49:52 PDT 2025


https://github.com/HertzDevil updated https://github.com/llvm/llvm-project/pull/129440

>From 15a845eced902d40438054f036c47cc9c202f241 Mon Sep 17 00:00:00 2001
From: Quinton Miller <nicetas.c at gmail.com>
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<ConstantDataSequential>(C)->getRawDataValues();
+  *SizeInBytes = Str.size();
+  return Str.data();
+}
+
 LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
                             LLVMValueRef *ConstantVals, unsigned Length) {
   ArrayRef<Constant*> V(unwrap<Constant>(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"
+ at 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<LLVMValueRef, 8> Elts;

>From a2a14b23b01e6f18bd1629322b3bdc1fb4542407 Mon Sep 17 00:00:00 2001
From: Quinton Miller <nicetas.c at gmail.com>
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()
  */



More information about the llvm-commits mailing list