Skip to content

Commit 86cca00

Browse files
authored
[llvm-c] Add LLVMConstDataArray and LLVMGetRawDataValues (#129440)
Resolves #129439. The addition to `echo.ll` is for testing `ConstantArray`, because every other array in that file is in fact a `ConstantDataArray` and now takes the new code path in `echo.cpp`.
1 parent a9788e3 commit 86cca00

File tree

5 files changed

+52
-5
lines changed

5 files changed

+52
-5
lines changed

llvm/docs/ReleaseNotes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ Changes to the C API
203203
* `LLVMConstNUWMul`
204204
* `LLVMConstNSWMul`
205205

206+
* Added `LLVMConstDataArray` and `LLVMGetRawDataValues` to allow creating and
207+
reading `ConstantDataArray` values without needing extra `LLVMValueRef`s for
208+
individual elements.
209+
206210
Changes to the CodeGen infrastructure
207211
-------------------------------------
208212

llvm/include/llvm-c/Core.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,6 +2350,16 @@ LLVMBool LLVMIsConstantString(LLVMValueRef c);
23502350
*/
23512351
const char *LLVMGetAsString(LLVMValueRef c, size_t *Length);
23522352

2353+
/**
2354+
* Get the raw, underlying bytes of the given constant data sequential.
2355+
*
2356+
* This is the same as LLVMGetAsString except it works for all constant data
2357+
* sequentials, not just i8 arrays.
2358+
*
2359+
* @see ConstantDataSequential::getRawDataValues()
2360+
*/
2361+
const char *LLVMGetRawDataValues(LLVMValueRef c, size_t *SizeInBytes);
2362+
23532363
/**
23542364
* Create an anonymous ConstantStruct with the specified values.
23552365
*
@@ -2388,6 +2398,18 @@ LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
23882398
LLVMValueRef LLVMConstArray2(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals,
23892399
uint64_t Length);
23902400

2401+
/**
2402+
* Create a ConstantDataArray from raw values.
2403+
*
2404+
* ElementTy must be one of i8, i16, i32, i64, half, bfloat, float, or double.
2405+
* Data points to a contiguous buffer of raw values in the host endianness. The
2406+
* element count is inferred from the element type and the data size in bytes.
2407+
*
2408+
* @see llvm::ConstantDataArray::getRaw()
2409+
*/
2410+
LLVMValueRef LLVMConstDataArray(LLVMTypeRef ElementTy, const char *Data,
2411+
size_t SizeInBytes);
2412+
23912413
/**
23922414
* Create a non-anonymous ConstantStruct from values.
23932415
*

llvm/lib/IR/Core.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,6 +1643,12 @@ const char *LLVMGetAsString(LLVMValueRef C, size_t *Length) {
16431643
return Str.data();
16441644
}
16451645

1646+
const char *LLVMGetRawDataValues(LLVMValueRef C, size_t *SizeInBytes) {
1647+
StringRef Str = unwrap<ConstantDataSequential>(C)->getRawDataValues();
1648+
*SizeInBytes = Str.size();
1649+
return Str.data();
1650+
}
1651+
16461652
LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
16471653
LLVMValueRef *ConstantVals, unsigned Length) {
16481654
ArrayRef<Constant*> V(unwrap<Constant>(ConstantVals, Length), Length);
@@ -1655,6 +1661,13 @@ LLVMValueRef LLVMConstArray2(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals,
16551661
return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), V));
16561662
}
16571663

1664+
LLVMValueRef LLVMConstDataArray(LLVMTypeRef ElementTy, const char *Data,
1665+
size_t SizeInBytes) {
1666+
Type *Ty = unwrap(ElementTy);
1667+
size_t Len = SizeInBytes / (Ty->getPrimitiveSizeInBits() / 8);
1668+
return wrap(ConstantDataArray::getRaw(StringRef(Data, SizeInBytes), Len, Ty));
1669+
}
1670+
16581671
LLVMValueRef LLVMConstStructInContext(LLVMContextRef C,
16591672
LLVMValueRef *ConstantVals,
16601673
unsigned Count, LLVMBool Packed) {

llvm/test/Bindings/llvm-c/echo.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module asm "classical GAS"
1717
@arr = linkonce_odr global [5 x i8] [ i8 2, i8 3, i8 5, i8 7, i8 11 ]
1818
@str = private unnamed_addr constant [13 x i8] c"hello world\0A\00"
1919
@locStr = private local_unnamed_addr constant [13 x i8] c"hello world\0A\00"
20+
@caLarge = private constant [2 x i128] [ i128 12345, i128 67890 ]
2021
@hidden = hidden global i32 7
2122
@protected = protected global i32 23
2223
@section = global i32 27, section ".custom"

llvm/tools/llvm-c-test/echo.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -317,11 +317,18 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) {
317317
return LLVMConstNull(TypeCloner(M).Clone(Cst));
318318
}
319319

320-
// Try constant array or constant data array
321-
if (LLVMIsAConstantArray(Cst) || LLVMIsAConstantDataArray(Cst)) {
322-
check_value_kind(Cst, LLVMIsAConstantArray(Cst)
323-
? LLVMConstantArrayValueKind
324-
: LLVMConstantDataArrayValueKind);
320+
// Try constant data array
321+
if (LLVMIsAConstantDataArray(Cst)) {
322+
check_value_kind(Cst, LLVMConstantDataArrayValueKind);
323+
LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
324+
size_t SizeInBytes;
325+
const char *Data = LLVMGetRawDataValues(Cst, &SizeInBytes);
326+
return LLVMConstDataArray(LLVMGetElementType(Ty), Data, SizeInBytes);
327+
}
328+
329+
// Try constant array
330+
if (LLVMIsAConstantArray(Cst)) {
331+
check_value_kind(Cst, LLVMConstantArrayValueKind);
325332
LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
326333
uint64_t EltCount = LLVMGetArrayLength2(Ty);
327334
SmallVector<LLVMValueRef, 8> Elts;

0 commit comments

Comments
 (0)