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

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon May 16 01:53:55 PDT 2022


Author: Nicolas Abram Lujan
Date: 2022-05-16T10:53:46+02:00
New Revision: 436bbce7657df830dcebd16b2ad675be56f58681

URL: https://github.com/llvm/llvm-project/commit/436bbce7657df830dcebd16b2ad675be56f58681
DIFF: https://github.com/llvm/llvm-project/commit/436bbce7657df830dcebd16b2ad675be56f58681.diff

LOG: [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
(https://github.com/llvm/llvm-project/blob/08ac66124874d70dab63c731da0244f9e29ef168/llvm/include/llvm/IR/IRBuilder.h#L1998-L1999).

Differential Revision: https://reviews.llvm.org/D125183

Added: 
    

Modified: 
    llvm/include/llvm-c/Core.h
    llvm/lib/IR/Core.cpp
    llvm/test/Bindings/llvm-c/echo.ll
    llvm/tools/llvm-c-test/echo.cpp
    llvm/tools/llvm-c-test/llvm-c-test.h
    llvm/tools/llvm-c-test/main.c

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 9bc0a4905ac18..eb2d14ba5ea5f 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -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.
  *

diff  --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index daeaf0c521f93..4a71187933d8f 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -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)));
 }

diff  --git a/llvm/test/Bindings/llvm-c/echo.ll b/llvm/test/Bindings/llvm-c/echo.ll
index 790689aaa3a2f..003c48fc714d9 100644
--- a/llvm/test/Bindings/llvm-c/echo.ll
+++ b/llvm/test/Bindings/llvm-c/echo.ll
@@ -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
 }

diff  --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index d3078db85ba17..56c9c441ad5e9 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -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 @@ static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
     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 @@ static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
   }
 }
 
-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);

diff  --git a/llvm/tools/llvm-c-test/llvm-c-test.h b/llvm/tools/llvm-c-test/llvm-c-test.h
index b828a827c55a2..7c08423d52b7d 100644
--- a/llvm/tools/llvm-c-test/llvm-c-test.h
+++ b/llvm/tools/llvm-c-test/llvm-c-test.h
@@ -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);

diff  --git a/llvm/tools/llvm-c-test/main.c b/llvm/tools/llvm-c-test/main.c
index 5e8adb45d691e..9458f256f66fb 100644
--- a/llvm/tools/llvm-c-test/main.c
+++ b/llvm/tools/llvm-c-test/main.c
@@ -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")) {


        


More information about the llvm-commits mailing list