llvm.org GIT mirror llvm / b711faf
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260335 91177308-0d34-0410-b5e6-96231b3b80d8 Amaury Sechet 4 years ago
4 changed file(s) with 184 addition(s) and 80 deletion(s). Raw diff Collapse all Expand all
25792579 */
25802580
25812581 /**
2582 * @defgroup LLVMCCoreValueInstructionExtractValue ExtractValue
2583 * @defgroup LLVMCCoreValueInstructionInsertValue InsertValue
2584 *
2585 * Functions in this group only apply to instructions that map to
2586 * llvm::ExtractValue and llvm::InsertValue instances.
2587 *
2588 * @{
2589 */
2590
2591 /**
2592 * Obtain the number of indices.
2593 */
2594 unsigned LLVMGetNumIndices(LLVMValueRef Inst);
2595
2596 /**
2597 * Obtain the indices as an array.
2598 */
2599 const unsigned *LLVMGetIndices(LLVMValueRef Inst);
2600
2601 /**
2602 * @}
2603 */
2604
2605 /**
25822606 * @}
25832607 */
25842608
21592159 return wrap(unwrap(PhiNode)->getIncomingBlock(Index));
21602160 }
21612161
2162 /*--.. Operations on extractvalue and insertvalue nodes ....................--*/
2163
2164 unsigned LLVMGetNumIndices(LLVMValueRef Inst) {
2165 auto *I = unwrap(Inst);
2166 if (auto *EV = dyn_cast(I))
2167 return EV->getNumIndices();
2168 if (auto *IV = dyn_cast(I))
2169 return IV->getNumIndices();
2170 llvm_unreachable(
2171 "LLVMGetNumIndices applies only to extractvalue and insertvalue!");
2172 }
2173
2174 const unsigned *LLVMGetIndices(LLVMValueRef Inst) {
2175 auto *I = unwrap(Inst);
2176 if (auto *EV = dyn_cast(I))
2177 return EV->getIndices().data();
2178 if (auto *IV = dyn_cast(I))
2179 return IV->getIndices().data();
2180 llvm_unreachable(
2181 "LLVMGetIndices applies only to extractvalue and insertvalue!");
2182 }
2183
21622184
21632185 /*===-- Instruction builders ----------------------------------------------===*/
21642186
11 ; RUN: llvm-as < %s | llvm-c-test --echo > %t.echo
22 ; RUN: diff -w %t.orig %t.echo
33
4 %S = type { i64, %S* }
5
6 define { i64, %S* } @unpackrepack(%S %s) {
7 %1 = extractvalue %S %s, 0
8 %2 = extractvalue %S %s, 1
9 %3 = insertvalue { i64, %S* } undef, %S* %2, 1
10 %4 = insertvalue { i64, %S* } %3, i64 %1, 0
11 ret { i64, %S* } %4
12 }
13
414 declare void @decl()
515
6 ; TODO: label, struct and metadata types
16 ; TODO: label and metadata types
717 define void @types() {
818 %1 = alloca half
919 %2 = alloca float
5353 typedef CAPIDenseMap::Map ValueMap;
5454 typedef CAPIDenseMap::Map BasicBlockMap;
5555
56 static LLVMTypeRef clone_type(LLVMTypeRef Src, LLVMContextRef Ctx) {
57 LLVMTypeKind Kind = LLVMGetTypeKind(Src);
58 switch (Kind) {
59 case LLVMVoidTypeKind:
60 return LLVMVoidTypeInContext(Ctx);
61 case LLVMHalfTypeKind:
62 return LLVMHalfTypeInContext(Ctx);
63 case LLVMFloatTypeKind:
64 return LLVMFloatTypeInContext(Ctx);
65 case LLVMDoubleTypeKind:
66 return LLVMDoubleTypeInContext(Ctx);
67 case LLVMX86_FP80TypeKind:
68 return LLVMX86FP80TypeInContext(Ctx);
69 case LLVMFP128TypeKind:
70 return LLVMFP128TypeInContext(Ctx);
71 case LLVMPPC_FP128TypeKind:
72 return LLVMPPCFP128TypeInContext(Ctx);
73 case LLVMLabelTypeKind:
74 return LLVMLabelTypeInContext(Ctx);
75 case LLVMIntegerTypeKind:
76 return LLVMIntTypeInContext(Ctx, LLVMGetIntTypeWidth(Src));
77 case LLVMFunctionTypeKind: {
78 unsigned ParamCount = LLVMCountParamTypes(Src);
79 LLVMTypeRef* Params = nullptr;
80 if (ParamCount > 0) {
81 Params = (LLVMTypeRef*) malloc(ParamCount * sizeof(LLVMTypeRef));
82 LLVMGetParamTypes(Src, Params);
83 for (unsigned i = 0; i < ParamCount; i++)
84 Params[i] = clone_type(Params[i], Ctx);
85 }
86
87 LLVMTypeRef FunTy = LLVMFunctionType(
88 clone_type(LLVMGetReturnType(Src), Ctx),
89 Params, ParamCount,
90 LLVMIsFunctionVarArg(Src)
91 );
92
93 if (ParamCount > 0)
94 free(Params);
95
96 return FunTy;
97 }
98 case LLVMStructTypeKind:
99 break;
100 case LLVMArrayTypeKind:
101 return LLVMArrayType(
102 clone_type(LLVMGetElementType(Src), Ctx),
103 LLVMGetArrayLength(Src)
104 );
105 case LLVMPointerTypeKind:
106 return LLVMPointerType(
107 clone_type(LLVMGetElementType(Src), Ctx),
108 LLVMGetPointerAddressSpace(Src)
109 );
110 case LLVMVectorTypeKind:
111 return LLVMVectorType(
112 clone_type(LLVMGetElementType(Src), Ctx),
113 LLVMGetVectorSize(Src)
114 );
115 case LLVMMetadataTypeKind:
116 break;
117 case LLVMX86_MMXTypeKind:
118 return LLVMX86MMXTypeInContext(Ctx);
119 default:
120 break;
121 }
122
123 fprintf(stderr, "%d is not a supported typekind\n", Kind);
124 exit(-1);
125 }
56 struct TypeCloner {
57 LLVMModuleRef M;
58 LLVMContextRef Ctx;
59
60 TypeCloner(LLVMModuleRef M): M(M), Ctx(LLVMGetModuleContext(M)) {}
61
62 LLVMTypeRef Clone(LLVMTypeRef Src) {
63 LLVMTypeKind Kind = LLVMGetTypeKind(Src);
64 switch (Kind) {
65 case LLVMVoidTypeKind:
66 return LLVMVoidTypeInContext(Ctx);
67 case LLVMHalfTypeKind:
68 return LLVMHalfTypeInContext(Ctx);
69 case LLVMFloatTypeKind:
70 return LLVMFloatTypeInContext(Ctx);
71 case LLVMDoubleTypeKind:
72 return LLVMDoubleTypeInContext(Ctx);
73 case LLVMX86_FP80TypeKind:
74 return LLVMX86FP80TypeInContext(Ctx);
75 case LLVMFP128TypeKind:
76 return LLVMFP128TypeInContext(Ctx);
77 case LLVMPPC_FP128TypeKind:
78 return LLVMPPCFP128TypeInContext(Ctx);
79 case LLVMLabelTypeKind:
80 return LLVMLabelTypeInContext(Ctx);
81 case LLVMIntegerTypeKind:
82 return LLVMIntTypeInContext(Ctx, LLVMGetIntTypeWidth(Src));
83 case LLVMFunctionTypeKind: {
84 unsigned ParamCount = LLVMCountParamTypes(Src);
85 LLVMTypeRef* Params = nullptr;
86 if (ParamCount > 0) {
87 Params = (LLVMTypeRef*) malloc(ParamCount * sizeof(LLVMTypeRef));
88 LLVMGetParamTypes(Src, Params);
89 for (unsigned i = 0; i < ParamCount; i++)
90 Params[i] = Clone(Params[i]);
91 }
92
93 LLVMTypeRef FunTy = LLVMFunctionType(Clone(LLVMGetReturnType(Src)),
94 Params, ParamCount,
95 LLVMIsFunctionVarArg(Src));
96 if (ParamCount > 0)
97 free(Params);
98 return FunTy;
99 }
100 case LLVMStructTypeKind: {
101 LLVMTypeRef S = nullptr;
102 const char *Name = LLVMGetStructName(Src);
103 if (Name) {
104 S = LLVMGetTypeByName(M, Name);
105 if (S)
106 return S;
107 S = LLVMStructCreateNamed(Ctx, Name);
108 if (LLVMIsOpaqueStruct(Src))
109 return S;
110 }
111
112 unsigned EltCount = LLVMCountStructElementTypes(Src);
113 SmallVector Elts;
114 for (unsigned i = 0; i < EltCount; i++)
115 Elts.push_back(Clone(LLVMStructGetTypeAtIndex(Src, i)));
116 if (Name)
117 LLVMStructSetBody(S, Elts.data(), EltCount, LLVMIsPackedStruct(Src));
118 else
119 S = LLVMStructTypeInContext(Ctx, Elts.data(), EltCount,
120 LLVMIsPackedStruct(Src));
121 return S;
122 }
123 case LLVMArrayTypeKind:
124 return LLVMArrayType(
125 Clone(LLVMGetElementType(Src)),
126 LLVMGetArrayLength(Src)
127 );
128 case LLVMPointerTypeKind:
129 return LLVMPointerType(
130 Clone(LLVMGetElementType(Src)),
131 LLVMGetPointerAddressSpace(Src)
132 );
133 case LLVMVectorTypeKind:
134 return LLVMVectorType(
135 Clone(LLVMGetElementType(Src)),
136 LLVMGetVectorSize(Src)
137 );
138 case LLVMMetadataTypeKind:
139 break;
140 case LLVMX86_MMXTypeKind:
141 return LLVMX86MMXTypeInContext(Ctx);
142 default:
143 break;
144 }
145
146 fprintf(stderr, "%d is not a supported typekind\n", Kind);
147 exit(-1);
148 }
149 };
126150
127151 static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst);
128152
129153 struct FunCloner {
130154 LLVMValueRef Fun;
131155 LLVMModuleRef M;
132 LLVMContextRef Ctx;
133156
134157 ValueMap VMap;
135158 BasicBlockMap BBMap;
136159
137 FunCloner(LLVMValueRef Src, LLVMValueRef Dst)
138 : Fun(Dst), M(LLVMGetGlobalParent(Fun)), Ctx(LLVMGetModuleContext(M)),
139 VMap(clone_params(Src, Dst)) {}
160 FunCloner(LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst),
161 M(LLVMGetGlobalParent(Fun)), VMap(clone_params(Src, Dst)) {}
162
163 LLVMTypeRef CloneType(LLVMTypeRef Src) {
164 return TypeCloner(M).Clone(Src);
165 }
166
167 LLVMTypeRef CloneType(LLVMValueRef Src) {
168 return CloneType(LLVMTypeOf(Src));
169 }
140170
141171 // Try to clone everything in the llvm::Value hierarchy.
142172 LLVMValueRef CloneValue(LLVMValueRef Src) {
162192
163193 // Try literal
164194 if (LLVMIsAConstantInt(Src)) {
165 LLVMTypeRef Ty = clone_type(LLVMTypeOf(Src), Ctx);
195 LLVMTypeRef Ty = CloneType(Src);
166196 return LLVMConstInt(Ty, LLVMConstIntGetZExtValue(Src), false);
167197 }
168198
169199 // Try undef
170200 if (LLVMIsUndef(Src))
171 return LLVMGetUndef(clone_type(LLVMTypeOf(Src), Ctx));
201 return LLVMGetUndef(CloneType(Src));
172202
173203 // This kind of constant is not supported.
174204 report_fatal_error("Unsupported contant type");
182212 }
183213
184214 if (LLVMIsAInstruction(Src)) {
215 auto Ctx = LLVMGetModuleContext(M);
185216 auto Builder = LLVMCreateBuilderInContext(Ctx);
186217 auto BB = DeclareBB(LLVMGetInstructionParent(Src));
187218 LLVMPositionBuilderAtEnd(Builder, BB);
322353 break;
323354 }
324355 case LLVMAlloca: {
325 LLVMTypeRef Ty = clone_type(LLVMGetAllocatedType(Src), Ctx);
356 LLVMTypeRef Ty = CloneType(LLVMGetAllocatedType(Src));
326357 Dst = LLVMBuildAlloca(Builder, Ty, Name);
327358 break;
328359 }
342373 Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
343374 break;
344375 }
376 case LLVMExtractValue: {
377 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
378 if (LLVMGetNumIndices(Src) != 1)
379 report_fatal_error("Expected only one indice");
380 auto I = LLVMGetIndices(Src)[0];
381 Dst = LLVMBuildExtractValue(Builder, Agg, I, Name);
382 break;
383 }
384 case LLVMInsertValue: {
385 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
386 LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1));
387 if (LLVMGetNumIndices(Src) != 1)
388 report_fatal_error("Expected only one indice");
389 auto I = LLVMGetIndices(Src)[0];
390 Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name);
391 break;
392 }
345393 default:
346394 break;
347395 }
397445 return BB;
398446 }
399447
448 auto Ctx = LLVMGetModuleContext(M);
400449 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);
401450 LLVMPositionBuilderAtEnd(Builder, BB);
402451
549598 if (Fun != nullptr)
550599 return Fun;
551600
552 LLVMTypeRef SrcTy = LLVMTypeOf(Src);
553 LLVMTypeRef DstTy = clone_type(SrcTy, LLVMGetModuleContext(M));
601 LLVMTypeRef DstTy = TypeCloner(M).Clone(LLVMTypeOf(Src));
554602 LLVMTypeRef FunTy = LLVMGetElementType(DstTy);
555603
556604 Fun = LLVMAddFunction(M, Name, FunTy);