Skip to content

Commit 15a845e

Browse files
committed
[llvm-c] Add LLVMConstDataArray and LLVMGetRawDataValues
1 parent d403f33 commit 15a845e

File tree

5 files changed

+53
-5
lines changed

5 files changed

+53
-5
lines changed

llvm/docs/ReleaseNotes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ Changes to the C API
139139
* `LLVMConstNUWMul`
140140
* `LLVMConstNSWMul`
141141

142+
* Added `LLVMConstDataArray` and `LLVMGetRawDataValues` to allow creating and
143+
reading `ConstantDataArray` values without needing extra `LLVMValueRef`s for
144+
individual elements.
145+
142146
Changes to the CodeGen infrastructure
143147
-------------------------------------
144148

llvm/include/llvm-c/Core.h

Lines changed: 23 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,19 @@ 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 with the appropriate
2406+
* endianness. The element count is inferred from the element type and the data
2407+
* size in bytes.
2408+
*
2409+
* @see llvm::ConstantDataArray::getRaw()
2410+
*/
2411+
LLVMValueRef LLVMConstDataArray(LLVMTypeRef ElementTy, const char *Data,
2412+
size_t SizeInBytes);
2413+
23912414
/**
23922415
* Create a non-anonymous ConstantStruct from values.
23932416
*

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)