@@ -54,90 +54,120 @@ struct CAPIDenseMap<T*> {
54
54
typedef CAPIDenseMap<LLVMValueRef>::Map ValueMap;
55
55
typedef CAPIDenseMap<LLVMBasicBlockRef>::Map BasicBlockMap;
56
56
57
- static LLVMTypeRef clone_type (LLVMTypeRef Src, LLVMContextRef Ctx) {
58
- LLVMTypeKind Kind = LLVMGetTypeKind (Src);
59
- switch (Kind) {
60
- case LLVMVoidTypeKind:
61
- return LLVMVoidTypeInContext (Ctx);
62
- case LLVMHalfTypeKind:
63
- return LLVMHalfTypeInContext (Ctx);
64
- case LLVMFloatTypeKind:
65
- return LLVMFloatTypeInContext (Ctx);
66
- case LLVMDoubleTypeKind:
67
- return LLVMDoubleTypeInContext (Ctx);
68
- case LLVMX86_FP80TypeKind:
69
- return LLVMX86FP80TypeInContext (Ctx);
70
- case LLVMFP128TypeKind:
71
- return LLVMFP128TypeInContext (Ctx);
72
- case LLVMPPC_FP128TypeKind:
73
- return LLVMPPCFP128TypeInContext (Ctx);
74
- case LLVMLabelTypeKind:
75
- return LLVMLabelTypeInContext (Ctx);
76
- case LLVMIntegerTypeKind:
77
- return LLVMIntTypeInContext (Ctx, LLVMGetIntTypeWidth (Src));
78
- case LLVMFunctionTypeKind: {
79
- unsigned ParamCount = LLVMCountParamTypes (Src);
80
- LLVMTypeRef* Params = nullptr ;
81
- if (ParamCount > 0 ) {
82
- Params = (LLVMTypeRef*) malloc (ParamCount * sizeof (LLVMTypeRef));
83
- LLVMGetParamTypes (Src, Params);
84
- for (unsigned i = 0 ; i < ParamCount; i++)
85
- Params[i] = clone_type (Params[i], Ctx);
86
- }
87
-
88
- LLVMTypeRef FunTy = LLVMFunctionType (
89
- clone_type (LLVMGetReturnType (Src), Ctx),
90
- Params, ParamCount,
91
- LLVMIsFunctionVarArg (Src)
92
- );
93
-
94
- if (ParamCount > 0 )
95
- free (Params);
96
-
97
- return FunTy;
57
+ struct TypeCloner {
58
+ LLVMModuleRef M;
59
+ LLVMContextRef Ctx;
60
+
61
+ TypeCloner (LLVMModuleRef M): M(M), Ctx(LLVMGetModuleContext(M)) {}
62
+
63
+ LLVMTypeRef Clone (LLVMTypeRef Src) {
64
+ LLVMTypeKind Kind = LLVMGetTypeKind (Src);
65
+ switch (Kind) {
66
+ case LLVMVoidTypeKind:
67
+ return LLVMVoidTypeInContext (Ctx);
68
+ case LLVMHalfTypeKind:
69
+ return LLVMHalfTypeInContext (Ctx);
70
+ case LLVMFloatTypeKind:
71
+ return LLVMFloatTypeInContext (Ctx);
72
+ case LLVMDoubleTypeKind:
73
+ return LLVMDoubleTypeInContext (Ctx);
74
+ case LLVMX86_FP80TypeKind:
75
+ return LLVMX86FP80TypeInContext (Ctx);
76
+ case LLVMFP128TypeKind:
77
+ return LLVMFP128TypeInContext (Ctx);
78
+ case LLVMPPC_FP128TypeKind:
79
+ return LLVMPPCFP128TypeInContext (Ctx);
80
+ case LLVMLabelTypeKind:
81
+ return LLVMLabelTypeInContext (Ctx);
82
+ case LLVMIntegerTypeKind:
83
+ return LLVMIntTypeInContext (Ctx, LLVMGetIntTypeWidth (Src));
84
+ case LLVMFunctionTypeKind: {
85
+ unsigned ParamCount = LLVMCountParamTypes (Src);
86
+ LLVMTypeRef* Params = nullptr ;
87
+ if (ParamCount > 0 ) {
88
+ Params = (LLVMTypeRef*) malloc (ParamCount * sizeof (LLVMTypeRef));
89
+ LLVMGetParamTypes (Src, Params);
90
+ for (unsigned i = 0 ; i < ParamCount; i++)
91
+ Params[i] = Clone (Params[i]);
92
+ }
93
+
94
+ LLVMTypeRef FunTy = LLVMFunctionType (Clone (LLVMGetReturnType (Src)),
95
+ Params, ParamCount,
96
+ LLVMIsFunctionVarArg (Src));
97
+ if (ParamCount > 0 )
98
+ free (Params);
99
+ return FunTy;
100
+ }
101
+ case LLVMStructTypeKind: {
102
+ LLVMTypeRef S = nullptr ;
103
+ const char *Name = LLVMGetStructName (Src);
104
+ if (Name) {
105
+ S = LLVMGetTypeByName (M, Name);
106
+ if (S)
107
+ return S;
108
+ S = LLVMStructCreateNamed (Ctx, Name);
109
+ if (LLVMIsOpaqueStruct (Src))
110
+ return S;
111
+ }
112
+
113
+ unsigned EltCount = LLVMCountStructElementTypes (Src);
114
+ SmallVector<LLVMTypeRef, 8 > Elts;
115
+ for (unsigned i = 0 ; i < EltCount; i++)
116
+ Elts.push_back (Clone (LLVMStructGetTypeAtIndex (Src, i)));
117
+ if (Name)
118
+ LLVMStructSetBody (S, Elts.data (), EltCount, LLVMIsPackedStruct (Src));
119
+ else
120
+ S = LLVMStructTypeInContext (Ctx, Elts.data (), EltCount,
121
+ LLVMIsPackedStruct (Src));
122
+ return S;
123
+ }
124
+ case LLVMArrayTypeKind:
125
+ return LLVMArrayType (
126
+ Clone (LLVMGetElementType (Src)),
127
+ LLVMGetArrayLength (Src)
128
+ );
129
+ case LLVMPointerTypeKind:
130
+ return LLVMPointerType (
131
+ Clone (LLVMGetElementType (Src)),
132
+ LLVMGetPointerAddressSpace (Src)
133
+ );
134
+ case LLVMVectorTypeKind:
135
+ return LLVMVectorType (
136
+ Clone (LLVMGetElementType (Src)),
137
+ LLVMGetVectorSize (Src)
138
+ );
139
+ case LLVMMetadataTypeKind:
140
+ break ;
141
+ case LLVMX86_MMXTypeKind:
142
+ return LLVMX86MMXTypeInContext (Ctx);
143
+ default :
144
+ break ;
98
145
}
99
- case LLVMStructTypeKind:
100
- break ;
101
- case LLVMArrayTypeKind:
102
- return LLVMArrayType (
103
- clone_type (LLVMGetElementType (Src), Ctx),
104
- LLVMGetArrayLength (Src)
105
- );
106
- case LLVMPointerTypeKind:
107
- return LLVMPointerType (
108
- clone_type (LLVMGetElementType (Src), Ctx),
109
- LLVMGetPointerAddressSpace (Src)
110
- );
111
- case LLVMVectorTypeKind:
112
- return LLVMVectorType (
113
- clone_type (LLVMGetElementType (Src), Ctx),
114
- LLVMGetVectorSize (Src)
115
- );
116
- case LLVMMetadataTypeKind:
117
- break ;
118
- case LLVMX86_MMXTypeKind:
119
- return LLVMX86MMXTypeInContext (Ctx);
120
- default :
121
- break ;
122
- }
123
146
124
- fprintf (stderr, " %d is not a supported typekind\n " , Kind);
125
- exit (-1 );
126
- }
147
+ fprintf (stderr, " %d is not a supported typekind\n " , Kind);
148
+ exit (-1 );
149
+ }
150
+ };
127
151
128
152
static ValueMap clone_params (LLVMValueRef Src, LLVMValueRef Dst);
129
153
130
154
struct FunCloner {
131
155
LLVMValueRef Fun;
132
156
LLVMModuleRef M;
133
- LLVMContextRef Ctx;
134
157
135
158
ValueMap VMap;
136
159
BasicBlockMap BBMap;
137
160
138
- FunCloner (LLVMValueRef Src, LLVMValueRef Dst)
139
- : Fun(Dst), M(LLVMGetGlobalParent(Fun)), Ctx(LLVMGetModuleContext(M)),
140
- VMap (clone_params(Src, Dst)) {}
161
+ FunCloner (LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst),
162
+ M (LLVMGetGlobalParent(Fun)), VMap(clone_params(Src, Dst)) {}
163
+
164
+ LLVMTypeRef CloneType (LLVMTypeRef Src) {
165
+ return TypeCloner (M).Clone (Src);
166
+ }
167
+
168
+ LLVMTypeRef CloneType (LLVMValueRef Src) {
169
+ return CloneType (LLVMTypeOf (Src));
170
+ }
141
171
142
172
// Try to clone everything in the llvm::Value hierarchy.
143
173
LLVMValueRef CloneValue (LLVMValueRef Src) {
@@ -163,13 +193,13 @@ struct FunCloner {
163
193
164
194
// Try literal
165
195
if (LLVMIsAConstantInt (Src)) {
166
- LLVMTypeRef Ty = clone_type ( LLVMTypeOf ( Src), Ctx );
196
+ LLVMTypeRef Ty = CloneType ( Src);
167
197
return LLVMConstInt (Ty, LLVMConstIntGetZExtValue (Src), false );
168
198
}
169
199
170
200
// Try undef
171
201
if (LLVMIsUndef (Src))
172
- return LLVMGetUndef (clone_type ( LLVMTypeOf ( Src), Ctx ));
202
+ return LLVMGetUndef (CloneType ( Src));
173
203
174
204
// This kind of constant is not supported.
175
205
report_fatal_error (" Unsupported contant type" );
@@ -183,6 +213,7 @@ struct FunCloner {
183
213
}
184
214
185
215
if (LLVMIsAInstruction (Src)) {
216
+ auto Ctx = LLVMGetModuleContext (M);
186
217
auto Builder = LLVMCreateBuilderInContext (Ctx);
187
218
auto BB = DeclareBB (LLVMGetInstructionParent (Src));
188
219
LLVMPositionBuilderAtEnd (Builder, BB);
@@ -323,7 +354,7 @@ struct FunCloner {
323
354
break ;
324
355
}
325
356
case LLVMAlloca: {
326
- LLVMTypeRef Ty = clone_type (LLVMGetAllocatedType (Src), Ctx );
357
+ LLVMTypeRef Ty = CloneType (LLVMGetAllocatedType (Src));
327
358
Dst = LLVMBuildAlloca (Builder, Ty, Name);
328
359
break ;
329
360
}
@@ -343,6 +374,23 @@ struct FunCloner {
343
374
Dst = LLVMBuildCall (Builder, Fn, Args.data (), ArgCount, Name);
344
375
break ;
345
376
}
377
+ case LLVMExtractValue: {
378
+ LLVMValueRef Agg = CloneValue (LLVMGetOperand (Src, 0 ));
379
+ if (LLVMGetNumIndices (Src) != 1 )
380
+ report_fatal_error (" Expected only one indice" );
381
+ auto I = LLVMGetIndices (Src)[0 ];
382
+ Dst = LLVMBuildExtractValue (Builder, Agg, I, Name);
383
+ break ;
384
+ }
385
+ case LLVMInsertValue: {
386
+ LLVMValueRef Agg = CloneValue (LLVMGetOperand (Src, 0 ));
387
+ LLVMValueRef V = CloneValue (LLVMGetOperand (Src, 1 ));
388
+ if (LLVMGetNumIndices (Src) != 1 )
389
+ report_fatal_error (" Expected only one indice" );
390
+ auto I = LLVMGetIndices (Src)[0 ];
391
+ Dst = LLVMBuildInsertValue (Builder, Agg, V, I, Name);
392
+ break ;
393
+ }
346
394
default :
347
395
break ;
348
396
}
@@ -398,6 +446,7 @@ struct FunCloner {
398
446
return BB;
399
447
}
400
448
449
+ auto Ctx = LLVMGetModuleContext (M);
401
450
LLVMBuilderRef Builder = LLVMCreateBuilderInContext (Ctx);
402
451
LLVMPositionBuilderAtEnd (Builder, BB);
403
452
@@ -550,8 +599,7 @@ static LLVMValueRef clone_function(LLVMValueRef Src, LLVMModuleRef M) {
550
599
if (Fun != nullptr )
551
600
return Fun;
552
601
553
- LLVMTypeRef SrcTy = LLVMTypeOf (Src);
554
- LLVMTypeRef DstTy = clone_type (SrcTy, LLVMGetModuleContext (M));
602
+ LLVMTypeRef DstTy = TypeCloner (M).Clone (LLVMTypeOf (Src));
555
603
LLVMTypeRef FunTy = LLVMGetElementType (DstTy);
556
604
557
605
Fun = LLVMAddFunction (M, Name, FunTy);
0 commit comments