[llvm-c] Add functions for enabling and creating opaque pointers

This is based on https://reviews.llvm.org/D125168 which adds a
wrapper to allow use of opaque pointers from the C API.

I added an opaque pointer mode test to echo.ll, and to fix assertions
that forbid the use of mixed typed and opaque pointers that were
triggering in it I had to also add wrappers for setOpaquePointers()
and isOpaquePointer().

I also changed echo.ll to remove a bitcast i32* %x to i8*, because
passing it through llvm-as and llvm-dis was generating a
%0 = bitcast ptr %x to ptr, but when building that same bitcast in
echo.cpp it was getting elided by IRBuilderBase::CreateCast
(08ac661248/llvm/include/llvm/IR/IRBuilder.h (L1998-L1999)).

Differential Revision: https://reviews.llvm.org/D125183
This commit is contained in:
Nicolas Abram Lujan 2022-05-16 10:51:51 +02:00 committed by Nikita Popov
parent c1af2d329f
commit 436bbce765
6 changed files with 59 additions and 14 deletions

View File

@ -548,6 +548,13 @@ LLVMBool LLVMContextShouldDiscardValueNames(LLVMContextRef C);
*/
void LLVMContextSetDiscardValueNames(LLVMContextRef C, LLVMBool Discard);
/**
* Set whether the given context is in opaque pointer mode.
*
* @see LLVMContext::setOpaquePointers()
*/
void LLVMContextSetOpaquePointers(LLVMContextRef C, LLVMBool OpaquePointers);
/**
* Destroy a context instance.
*
@ -1442,6 +1449,22 @@ unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy);
*/
LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace);
/**
* Determine whether a pointer is opaque.
*
* True if this is an instance of an opaque PointerType.
*
* @see llvm::Type::isOpaquePointerTy()
*/
LLVMBool LLVMPointerTypeIsOpaque(LLVMTypeRef Ty);
/**
* Create an opaque pointer type in a context.
*
* @see llvm::PointerType::get()
*/
LLVMTypeRef LLVMPointerTypeInContext(LLVMContextRef C, unsigned AddressSpace);
/**
* Obtain the address space of a pointer type.
*

View File

@ -115,6 +115,10 @@ void LLVMContextSetDiscardValueNames(LLVMContextRef C, LLVMBool Discard) {
unwrap(C)->setDiscardValueNames(Discard);
}
void LLVMContextSetOpaquePointers(LLVMContextRef C, LLVMBool OpaquePointers) {
unwrap(C)->setOpaquePointers(OpaquePointers);
}
void LLVMContextDispose(LLVMContextRef C) {
delete unwrap(C);
}
@ -788,6 +792,10 @@ LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace) {
return wrap(PointerType::get(unwrap(ElementType), AddressSpace));
}
LLVMBool LLVMPointerTypeIsOpaque(LLVMTypeRef Ty) {
return unwrap(Ty)->isOpaquePointerTy();
}
LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount) {
return wrap(FixedVectorType::get(unwrap(ElementType), ElementCount));
}
@ -824,6 +832,10 @@ unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy) {
/*--.. Operations on other types ...........................................--*/
LLVMTypeRef LLVMPointerTypeInContext(LLVMContextRef C, unsigned AddressSpace) {
return wrap(PointerType::get(*unwrap(C), AddressSpace));
}
LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C) {
return wrap(Type::getVoidTy(*unwrap(C)));
}

View File

@ -1,6 +1,10 @@
; RUN: llvm-as < %s | llvm-dis > %t.orig
; RUN: llvm-as < %s | llvm-c-test --echo > %t.echo
; RUN: diff -w %t.orig %t.echo
;
; RUN: llvm-as -opaque-pointers < %s | llvm-dis -opaque-pointers > %t.orig_opaque
; RUN: llvm-as -opaque-pointers < %s | llvm-c-test --echo --opaque-pointers > %t.echo_opaque
; RUN: diff -w %t.orig_opaque %t.echo_opaque
source_filename = "/test/Bindings/echo.ll"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
@ -237,10 +241,9 @@ declare void @llvm.lifetime.end.p0i8(i64, i8*)
define void @test_intrinsics() {
entry:
%sp = call i8* @llvm.stacksave()
%x = alloca i32, align 4
%0 = bitcast i32* %x to i8*
call void @llvm.lifetime.start.p0i8(i64 4, i8* %0)
call void @llvm.lifetime.end.p0i8(i64 4, i8* %0)
%0 = alloca i8, align 1
call void @llvm.lifetime.start.p0i8(i64 1, i8* %0)
call void @llvm.lifetime.end.p0i8(i64 1, i8* %0)
call void @llvm.stackrestore(i8* %sp)
ret void
}

View File

@ -138,10 +138,11 @@ struct TypeCloner {
LLVMGetArrayLength(Src)
);
case LLVMPointerTypeKind:
return LLVMPointerType(
Clone(LLVMGetElementType(Src)),
LLVMGetPointerAddressSpace(Src)
);
if (LLVMPointerTypeIsOpaque(Src))
return LLVMPointerTypeInContext(Ctx, LLVMGetPointerAddressSpace(Src));
else
return LLVMPointerType(Clone(LLVMGetElementType(Src)),
LLVMGetPointerAddressSpace(Src));
case LLVMVectorTypeKind:
return LLVMVectorType(
Clone(LLVMGetElementType(Src)),
@ -997,7 +998,7 @@ static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
const char *Name = LLVMGetValueName2(Cur, &NameLen);
if (LLVMGetNamedGlobal(M, Name))
report_fatal_error("GlobalVariable already cloned");
LLVMAddGlobal(M, LLVMGetElementType(TypeCloner(M).Clone(Cur)), Name);
LLVMAddGlobal(M, TypeCloner(M).Clone(LLVMGlobalGetValueType(Cur)), Name);
Next = LLVMGetNextGlobal(Cur);
if (Next == nullptr) {
@ -1029,7 +1030,8 @@ FunDecl:
const char *Name = LLVMGetValueName2(Cur, &NameLen);
if (LLVMGetNamedFunction(M, Name))
report_fatal_error("Function already cloned");
auto Ty = LLVMGetElementType(TypeCloner(M).Clone(Cur));
LLVMTypeRef Ty = TypeCloner(M).Clone(LLVMGlobalGetValueType(Cur));
auto F = LLVMAddFunction(M, Name, Ty);
// Copy attributes
@ -1390,7 +1392,7 @@ NamedMDClone:
}
}
int llvm_echo(void) {
int llvm_echo(bool OpaquePointers) {
LLVMEnablePrettyStackTrace();
LLVMModuleRef Src = llvm_load_module(false, true);
@ -1399,6 +1401,8 @@ int llvm_echo(void) {
size_t ModuleIdentLen;
const char *ModuleName = LLVMGetModuleIdentifier(Src, &ModuleIdentLen);
LLVMContextRef Ctx = LLVMContextCreate();
if (OpaquePointers)
LLVMContextSetOpaquePointers(Ctx, true);
LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleName, Ctx);
LLVMSetSourceFileName(M, SourceFileName, SourceFileLen);

View File

@ -50,7 +50,7 @@ int llvm_object_list_symbols(void);
int llvm_targets_list(void);
// echo.c
int llvm_echo(void);
int llvm_echo(bool OpaquePointers);
// diagnostic.c
int llvm_test_diagnostic_handler(void);

View File

@ -49,6 +49,9 @@ static void print_usage(void) {
" Read lines of name, rpn from stdin - print generated module\n\n");
fprintf(stderr, " * --echo\n");
fprintf(stderr, " Read bitcode file from stdin - print it back out\n\n");
fprintf(stderr, " * --echo --opaque-pointers\n");
fprintf(stderr, " Read bitcode file from stdin - print it back out in "
"opaque pointer mode\n\n");
fprintf(stderr, " * --test-diagnostic-handler\n");
fprintf(stderr,
" Read bitcode file from stdin with a diagnostic handler set\n\n");
@ -92,8 +95,8 @@ int main(int argc, char **argv) {
return llvm_test_function_attributes();
} else if (argc == 2 && !strcmp(argv[1], "--test-callsite-attributes")) {
return llvm_test_callsite_attributes();
} else if (argc == 2 && !strcmp(argv[1], "--echo")) {
return llvm_echo();
} else if ((argc == 2 || argc == 3) && !strcmp(argv[1], "--echo")) {
return llvm_echo(argc == 3 ? !strcmp(argv[2], "--opaque-pointers") : 0);
} else if (argc == 2 && !strcmp(argv[1], "--test-diagnostic-handler")) {
return llvm_test_diagnostic_handler();
} else if (argc == 2 && !strcmp(argv[1], "--test-dibuilder")) {