[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`.
This commit is contained in:
@@ -203,6 +203,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
|
||||
-------------------------------------
|
||||
|
||||
|
||||
@@ -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,18 @@ 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 in the host 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.
|
||||
*
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user