[llvm] r260335 - Add support for struct in C API test

Amaury Sechet via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 9 16:38:51 PST 2016


Author: deadalnix
Date: Tue Feb  9 18:38:50 2016
New Revision: 260335

URL: http://llvm.org/viewvc/llvm-project?rev=260335&view=rev
Log:
Add support for struct in C API test

Summary: As per title. This also include extra support for insertvalue and extracvalue.

Reviewers: bogner, chandlerc, echristo, dblaikie, joker.eph, Wallbraker

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D17055

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

Modified: llvm/trunk/include/llvm-c/Core.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=260335&r1=260334&r2=260335&view=diff
==============================================================================
--- llvm/trunk/include/llvm-c/Core.h (original)
+++ llvm/trunk/include/llvm-c/Core.h Tue Feb  9 18:38:50 2016
@@ -2580,6 +2580,30 @@ LLVMBasicBlockRef LLVMGetIncomingBlock(L
  */
 
 /**
+ * @defgroup LLVMCCoreValueInstructionExtractValue ExtractValue
+ * @defgroup LLVMCCoreValueInstructionInsertValue InsertValue
+ *
+ * Functions in this group only apply to instructions that map to
+ * llvm::ExtractValue and llvm::InsertValue instances.
+ *
+ * @{
+ */
+
+/**
+ * Obtain the number of indices.
+ */
+unsigned LLVMGetNumIndices(LLVMValueRef Inst);
+
+/**
+ * Obtain the indices as an array.
+ */
+const unsigned *LLVMGetIndices(LLVMValueRef Inst);
+
+/**
+ * @}
+ */
+
+/**
  * @}
  */
 

Modified: llvm/trunk/lib/IR/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Core.cpp?rev=260335&r1=260334&r2=260335&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Core.cpp (original)
+++ llvm/trunk/lib/IR/Core.cpp Tue Feb  9 18:38:50 2016
@@ -2160,6 +2160,28 @@ LLVMBasicBlockRef LLVMGetIncomingBlock(L
   return wrap(unwrap<PHINode>(PhiNode)->getIncomingBlock(Index));
 }
 
+/*--.. Operations on extractvalue and insertvalue nodes ....................--*/
+
+unsigned LLVMGetNumIndices(LLVMValueRef Inst) {
+  auto *I = unwrap(Inst);
+  if (auto *EV = dyn_cast<ExtractValueInst>(I))
+    return EV->getNumIndices();
+  if (auto *IV = dyn_cast<InsertValueInst>(I))
+    return IV->getNumIndices();
+  llvm_unreachable(
+    "LLVMGetNumIndices applies only to extractvalue and insertvalue!");
+}
+
+const unsigned *LLVMGetIndices(LLVMValueRef Inst) {
+  auto *I = unwrap(Inst);
+  if (auto *EV = dyn_cast<ExtractValueInst>(I))
+    return EV->getIndices().data();
+  if (auto *IV = dyn_cast<InsertValueInst>(I))
+    return IV->getIndices().data();
+  llvm_unreachable(
+    "LLVMGetIndices applies only to extractvalue and insertvalue!");
+}
+
 
 /*===-- Instruction builders ----------------------------------------------===*/
 

Modified: llvm/trunk/test/Bindings/llvm-c/echo.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/llvm-c/echo.ll?rev=260335&r1=260334&r2=260335&view=diff
==============================================================================
--- llvm/trunk/test/Bindings/llvm-c/echo.ll (original)
+++ llvm/trunk/test/Bindings/llvm-c/echo.ll Tue Feb  9 18:38:50 2016
@@ -2,9 +2,19 @@
 ; RUN: llvm-as < %s | llvm-c-test --echo > %t.echo
 ; RUN: diff -w %t.orig %t.echo
 
+%S = type { i64, %S* }
+
+define { i64, %S* } @unpackrepack(%S %s) {
+  %1 = extractvalue %S %s, 0
+  %2 = extractvalue %S %s, 1
+  %3 = insertvalue { i64, %S* } undef, %S* %2, 1
+  %4 = insertvalue { i64, %S* } %3, i64 %1, 0
+  ret { i64, %S* } %4
+}
+
 declare void @decl()
 
-; TODO: label, struct and metadata types
+; TODO: label and metadata types
 define void @types() {
   %1 = alloca half
   %2 = alloca float

Modified: llvm/trunk/tools/llvm-c-test/echo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-c-test/echo.cpp?rev=260335&r1=260334&r2=260335&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-c-test/echo.cpp (original)
+++ llvm/trunk/tools/llvm-c-test/echo.cpp Tue Feb  9 18:38:50 2016
@@ -54,90 +54,120 @@ struct CAPIDenseMap<T*> {
 typedef CAPIDenseMap<LLVMValueRef>::Map ValueMap;
 typedef CAPIDenseMap<LLVMBasicBlockRef>::Map BasicBlockMap;
 
-static LLVMTypeRef clone_type(LLVMTypeRef Src, LLVMContextRef Ctx) {
-  LLVMTypeKind Kind = LLVMGetTypeKind(Src);
-  switch (Kind) {
-    case LLVMVoidTypeKind:
-      return LLVMVoidTypeInContext(Ctx);
-    case LLVMHalfTypeKind:
-      return LLVMHalfTypeInContext(Ctx);
-    case LLVMFloatTypeKind:
-      return LLVMFloatTypeInContext(Ctx);
-    case LLVMDoubleTypeKind:
-      return LLVMDoubleTypeInContext(Ctx);
-    case LLVMX86_FP80TypeKind:
-      return LLVMX86FP80TypeInContext(Ctx);
-    case LLVMFP128TypeKind:
-      return LLVMFP128TypeInContext(Ctx);
-    case LLVMPPC_FP128TypeKind:
-      return LLVMPPCFP128TypeInContext(Ctx);
-    case LLVMLabelTypeKind:
-      return LLVMLabelTypeInContext(Ctx);
-    case LLVMIntegerTypeKind:
-      return LLVMIntTypeInContext(Ctx, LLVMGetIntTypeWidth(Src));
-    case LLVMFunctionTypeKind: {
-      unsigned ParamCount = LLVMCountParamTypes(Src);
-      LLVMTypeRef* Params = nullptr;
-      if (ParamCount > 0) {
-        Params = (LLVMTypeRef*) malloc(ParamCount * sizeof(LLVMTypeRef));
-        LLVMGetParamTypes(Src, Params);
-        for (unsigned i = 0; i < ParamCount; i++)
-          Params[i] = clone_type(Params[i], Ctx);
-      }
-
-      LLVMTypeRef FunTy = LLVMFunctionType(
-        clone_type(LLVMGetReturnType(Src), Ctx),
-        Params, ParamCount,
-        LLVMIsFunctionVarArg(Src)
-      );
+struct TypeCloner {
+  LLVMModuleRef M;
+  LLVMContextRef Ctx;
 
-      if (ParamCount > 0)
-        free(Params);
+  TypeCloner(LLVMModuleRef M): M(M), Ctx(LLVMGetModuleContext(M)) {}
+
+  LLVMTypeRef Clone(LLVMTypeRef Src) {
+    LLVMTypeKind Kind = LLVMGetTypeKind(Src);
+    switch (Kind) {
+      case LLVMVoidTypeKind:
+        return LLVMVoidTypeInContext(Ctx);
+      case LLVMHalfTypeKind:
+        return LLVMHalfTypeInContext(Ctx);
+      case LLVMFloatTypeKind:
+        return LLVMFloatTypeInContext(Ctx);
+      case LLVMDoubleTypeKind:
+        return LLVMDoubleTypeInContext(Ctx);
+      case LLVMX86_FP80TypeKind:
+        return LLVMX86FP80TypeInContext(Ctx);
+      case LLVMFP128TypeKind:
+        return LLVMFP128TypeInContext(Ctx);
+      case LLVMPPC_FP128TypeKind:
+        return LLVMPPCFP128TypeInContext(Ctx);
+      case LLVMLabelTypeKind:
+        return LLVMLabelTypeInContext(Ctx);
+      case LLVMIntegerTypeKind:
+        return LLVMIntTypeInContext(Ctx, LLVMGetIntTypeWidth(Src));
+      case LLVMFunctionTypeKind: {
+        unsigned ParamCount = LLVMCountParamTypes(Src);
+        LLVMTypeRef* Params = nullptr;
+        if (ParamCount > 0) {
+          Params = (LLVMTypeRef*) malloc(ParamCount * sizeof(LLVMTypeRef));
+          LLVMGetParamTypes(Src, Params);
+          for (unsigned i = 0; i < ParamCount; i++)
+            Params[i] = Clone(Params[i]);
+        }
 
-      return FunTy;
+        LLVMTypeRef FunTy = LLVMFunctionType(Clone(LLVMGetReturnType(Src)),
+                                             Params, ParamCount,
+                                             LLVMIsFunctionVarArg(Src));
+        if (ParamCount > 0)
+          free(Params);
+        return FunTy;
+      }
+      case LLVMStructTypeKind: {
+        LLVMTypeRef S = nullptr;
+        const char *Name = LLVMGetStructName(Src);
+        if (Name) {
+          S = LLVMGetTypeByName(M, Name);
+          if (S)
+            return S;
+          S = LLVMStructCreateNamed(Ctx, Name);
+          if (LLVMIsOpaqueStruct(Src))
+            return S;
+        }
+
+        unsigned EltCount = LLVMCountStructElementTypes(Src);
+        SmallVector<LLVMTypeRef, 8> Elts;
+        for (unsigned i = 0; i < EltCount; i++)
+          Elts.push_back(Clone(LLVMStructGetTypeAtIndex(Src, i)));
+        if (Name)
+          LLVMStructSetBody(S, Elts.data(), EltCount, LLVMIsPackedStruct(Src));
+        else
+          S = LLVMStructTypeInContext(Ctx, Elts.data(), EltCount,
+                                      LLVMIsPackedStruct(Src));
+        return S;
+      }
+      case LLVMArrayTypeKind:
+        return LLVMArrayType(
+          Clone(LLVMGetElementType(Src)),
+          LLVMGetArrayLength(Src)
+        );
+      case LLVMPointerTypeKind:
+        return LLVMPointerType(
+          Clone(LLVMGetElementType(Src)),
+          LLVMGetPointerAddressSpace(Src)
+        );
+      case LLVMVectorTypeKind:
+        return LLVMVectorType(
+          Clone(LLVMGetElementType(Src)),
+          LLVMGetVectorSize(Src)
+        );
+      case LLVMMetadataTypeKind:
+        break;
+      case LLVMX86_MMXTypeKind:
+        return LLVMX86MMXTypeInContext(Ctx);
+      default:
+        break;
     }
-    case LLVMStructTypeKind:
-      break;
-    case LLVMArrayTypeKind:
-      return LLVMArrayType(
-        clone_type(LLVMGetElementType(Src), Ctx),
-        LLVMGetArrayLength(Src)
-      );
-    case LLVMPointerTypeKind:
-      return LLVMPointerType(
-        clone_type(LLVMGetElementType(Src), Ctx),
-        LLVMGetPointerAddressSpace(Src)
-      );
-    case LLVMVectorTypeKind:
-      return LLVMVectorType(
-        clone_type(LLVMGetElementType(Src), Ctx),
-        LLVMGetVectorSize(Src)
-      );
-    case LLVMMetadataTypeKind:
-      break;
-    case LLVMX86_MMXTypeKind:
-      return LLVMX86MMXTypeInContext(Ctx);
-    default:
-      break;
-  }
 
-  fprintf(stderr, "%d is not a supported typekind\n", Kind);
-  exit(-1);
-}
+    fprintf(stderr, "%d is not a supported typekind\n", Kind);
+    exit(-1);
+  }
+};
 
 static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst);
 
 struct FunCloner {
   LLVMValueRef Fun;
   LLVMModuleRef M;
-  LLVMContextRef Ctx;
 
   ValueMap VMap;
   BasicBlockMap BBMap;
 
-  FunCloner(LLVMValueRef Src, LLVMValueRef Dst)
-    : Fun(Dst), M(LLVMGetGlobalParent(Fun)), Ctx(LLVMGetModuleContext(M)),
-      VMap(clone_params(Src, Dst)) {}
+  FunCloner(LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst),
+    M(LLVMGetGlobalParent(Fun)), VMap(clone_params(Src, Dst)) {}
+
+  LLVMTypeRef CloneType(LLVMTypeRef Src) {
+    return TypeCloner(M).Clone(Src);
+  }
+
+  LLVMTypeRef CloneType(LLVMValueRef Src) {
+    return CloneType(LLVMTypeOf(Src));
+  }
 
   // Try to clone everything in the llvm::Value hierarchy.
   LLVMValueRef CloneValue(LLVMValueRef Src) {
@@ -163,13 +193,13 @@ struct FunCloner {
 
       // Try literal
       if (LLVMIsAConstantInt(Src)) {
-        LLVMTypeRef Ty = clone_type(LLVMTypeOf(Src), Ctx);
+        LLVMTypeRef Ty = CloneType(Src);
         return LLVMConstInt(Ty, LLVMConstIntGetZExtValue(Src), false);
       }
 
       // Try undef
       if (LLVMIsUndef(Src))
-        return LLVMGetUndef(clone_type(LLVMTypeOf(Src), Ctx));
+        return LLVMGetUndef(CloneType(Src));
 
       // This kind of constant is not supported.
       report_fatal_error("Unsupported contant type");
@@ -183,6 +213,7 @@ struct FunCloner {
     }
 
     if (LLVMIsAInstruction(Src)) {
+      auto Ctx = LLVMGetModuleContext(M);
       auto Builder = LLVMCreateBuilderInContext(Ctx);
       auto BB = DeclareBB(LLVMGetInstructionParent(Src));
       LLVMPositionBuilderAtEnd(Builder, BB);
@@ -323,7 +354,7 @@ struct FunCloner {
         break;
       }
       case LLVMAlloca: {
-        LLVMTypeRef Ty = clone_type(LLVMGetAllocatedType(Src), Ctx);
+        LLVMTypeRef Ty = CloneType(LLVMGetAllocatedType(Src));
         Dst = LLVMBuildAlloca(Builder, Ty, Name);
         break;
       }
@@ -343,6 +374,23 @@ struct FunCloner {
         Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
         break;
       }
+      case LLVMExtractValue: {
+        LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
+        if (LLVMGetNumIndices(Src) != 1)
+          report_fatal_error("Expected only one indice");
+        auto I = LLVMGetIndices(Src)[0];
+        Dst = LLVMBuildExtractValue(Builder, Agg, I, Name);
+        break;
+      }
+      case LLVMInsertValue: {
+        LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
+        LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1));
+        if (LLVMGetNumIndices(Src) != 1)
+          report_fatal_error("Expected only one indice");
+        auto I = LLVMGetIndices(Src)[0];
+        Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name);
+        break;
+      }
       default:
         break;
     }
@@ -398,6 +446,7 @@ struct FunCloner {
       return BB;
     }
 
+    auto Ctx = LLVMGetModuleContext(M);
     LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);
     LLVMPositionBuilderAtEnd(Builder, BB);
 
@@ -550,8 +599,7 @@ static LLVMValueRef clone_function(LLVMV
   if (Fun != nullptr)
     return Fun;
 
-  LLVMTypeRef SrcTy = LLVMTypeOf(Src);
-  LLVMTypeRef DstTy = clone_type(SrcTy, LLVMGetModuleContext(M));
+  LLVMTypeRef DstTy = TypeCloner(M).Clone(LLVMTypeOf(Src));
   LLVMTypeRef FunTy = LLVMGetElementType(DstTy);
 
   Fun = LLVMAddFunction(M, Name, FunTy);




More information about the llvm-commits mailing list