blob: 99e3cf0940cec4c7af550965e378527eeef19177 [file] [log] [blame]
Amaury Sechete8ea7d82016-02-04 23:26:19 +00001//===-- echo.cpp - tool for testing libLLVM and llvm-c API ----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the --echo commands in llvm-c-test.
11//
12// This command uses the C API to read a module and output an exact copy of it
13// as output. It is used to check that the resulting module matches the input
14// to validate that the C API can read and write modules properly.
15//
16//===----------------------------------------------------------------------===//
17
18#include "llvm-c-test.h"
19#include "llvm/ADT/DenseMap.h"
Amaury Secheta82042e2016-02-09 22:36:41 +000020#include "llvm/Support/ErrorHandling.h"
Amaury Sechete8ea7d82016-02-04 23:26:19 +000021
22#include <stdio.h>
23#include <stdlib.h>
24
25using namespace llvm;
26
27// Provide DenseMapInfo for C API opaque types.
28template<typename T>
29struct CAPIDenseMap {};
30
31// The default DenseMapInfo require to know about pointer alignement.
32// Because the C API uses opaques pointer types, their alignement is unknown.
33// As a result, we need to roll out our own implementation.
34template<typename T>
35struct CAPIDenseMap<T*> {
36 struct CAPIDenseMapInfo {
37 static inline T* getEmptyKey() {
38 uintptr_t Val = static_cast<uintptr_t>(-1);
39 return reinterpret_cast<T*>(Val);
40 }
41 static inline T* getTombstoneKey() {
42 uintptr_t Val = static_cast<uintptr_t>(-2);
43 return reinterpret_cast<T*>(Val);
44 }
45 static unsigned getHashValue(const T *PtrVal) {
46 return hash_value(PtrVal);
47 }
48 static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
49 };
50
51 typedef DenseMap<T*, T*, CAPIDenseMapInfo> Map;
52};
53
54typedef CAPIDenseMap<LLVMValueRef>::Map ValueMap;
Amaury Secheta82042e2016-02-09 22:36:41 +000055typedef CAPIDenseMap<LLVMBasicBlockRef>::Map BasicBlockMap;
Amaury Sechete8ea7d82016-02-04 23:26:19 +000056
Amaury Sechetaad93532016-02-10 00:38:50 +000057struct 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;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000100 }
Amaury Sechetaad93532016-02-10 00:38:50 +0000101 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 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000112
Amaury Sechetaad93532016-02-10 00:38:50 +0000113 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;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000145 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000146
Amaury Sechetaad93532016-02-10 00:38:50 +0000147 fprintf(stderr, "%d is not a supported typekind\n", Kind);
148 exit(-1);
149 }
150};
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000151
Amaury Sechetecda4ea2016-02-14 09:14:30 +0000152static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst) {
153 unsigned Count = LLVMCountParams(Src);
154 if (Count != LLVMCountParams(Dst)) {
155 fprintf(stderr, "Parameter count mismatch\n");
156 exit(-1);
157 }
158
159 ValueMap VMap;
160 if (Count == 0)
161 return VMap;
162
163 LLVMValueRef SrcFirst = LLVMGetFirstParam(Src);
164 LLVMValueRef DstFirst = LLVMGetFirstParam(Dst);
165 LLVMValueRef SrcLast = LLVMGetLastParam(Src);
166 LLVMValueRef DstLast = LLVMGetLastParam(Dst);
167
168 LLVMValueRef SrcCur = SrcFirst;
169 LLVMValueRef DstCur = DstFirst;
170 LLVMValueRef SrcNext = nullptr;
171 LLVMValueRef DstNext = nullptr;
172 while (true) {
173 const char *Name = LLVMGetValueName(SrcCur);
174 LLVMSetValueName(DstCur, Name);
175
176 VMap[SrcCur] = DstCur;
177
178 Count--;
179 SrcNext = LLVMGetNextParam(SrcCur);
180 DstNext = LLVMGetNextParam(DstCur);
181 if (SrcNext == nullptr && DstNext == nullptr) {
182 if (SrcCur != SrcLast) {
183 fprintf(stderr, "SrcLast param does not match End\n");
184 exit(-1);
185 }
186
187 if (DstCur != DstLast) {
188 fprintf(stderr, "DstLast param does not match End\n");
189 exit(-1);
190 }
191
192 break;
193 }
194
195 if (SrcNext == nullptr) {
196 fprintf(stderr, "SrcNext was unexpectedly null\n");
197 exit(-1);
198 }
199
200 if (DstNext == nullptr) {
201 fprintf(stderr, "DstNext was unexpectedly null\n");
202 exit(-1);
203 }
204
205 LLVMValueRef SrcPrev = LLVMGetPreviousParam(SrcNext);
206 if (SrcPrev != SrcCur) {
207 fprintf(stderr, "SrcNext.Previous param is not Current\n");
208 exit(-1);
209 }
210
211 LLVMValueRef DstPrev = LLVMGetPreviousParam(DstNext);
212 if (DstPrev != DstCur) {
213 fprintf(stderr, "DstNext.Previous param is not Current\n");
214 exit(-1);
215 }
216
217 SrcCur = SrcNext;
218 DstCur = DstNext;
219 }
220
221 if (Count != 0) {
222 fprintf(stderr, "Parameter count does not match iteration\n");
223 exit(-1);
224 }
225
226 return VMap;
227}
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000228
Amaury Secheta82042e2016-02-09 22:36:41 +0000229struct FunCloner {
230 LLVMValueRef Fun;
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000231 LLVMModuleRef M;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000232
Amaury Secheta82042e2016-02-09 22:36:41 +0000233 ValueMap VMap;
234 BasicBlockMap BBMap;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000235
Amaury Sechetaad93532016-02-10 00:38:50 +0000236 FunCloner(LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst),
237 M(LLVMGetGlobalParent(Fun)), VMap(clone_params(Src, Dst)) {}
238
239 LLVMTypeRef CloneType(LLVMTypeRef Src) {
240 return TypeCloner(M).Clone(Src);
241 }
242
243 LLVMTypeRef CloneType(LLVMValueRef Src) {
244 return CloneType(LLVMTypeOf(Src));
245 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000246
Amaury Secheta82042e2016-02-09 22:36:41 +0000247 // Try to clone everything in the llvm::Value hierarchy.
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000248 LLVMValueRef CloneValue(LLVMValueRef Src) {
Amaury Secheta82042e2016-02-09 22:36:41 +0000249 const char *Name = LLVMGetValueName(Src);
250
251 // First, the value may be constant.
252 if (LLVMIsAConstant(Src)) {
Amaury Secheta82042e2016-02-09 22:36:41 +0000253 // Maybe it is a symbol
254 if (LLVMIsAGlobalValue(Src)) {
255 // Try function
256 LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
257 if (Dst != nullptr)
258 return Dst;
259
260 // Try global variable
261 Dst = LLVMGetNamedGlobal(M, Name);
262 if (Dst != nullptr)
263 return Dst;
264
265 fprintf(stderr, "Could not find @%s\n", Name);
266 exit(-1);
267 }
268
269 // Try literal
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000270 if (LLVMIsAConstantInt(Src)) {
Amaury Sechetaad93532016-02-10 00:38:50 +0000271 LLVMTypeRef Ty = CloneType(Src);
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000272 return LLVMConstInt(Ty, LLVMConstIntGetZExtValue(Src), false);
273 }
274
275 // Try undef
276 if (LLVMIsUndef(Src))
Amaury Sechetaad93532016-02-10 00:38:50 +0000277 return LLVMGetUndef(CloneType(Src));
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000278
279 // This kind of constant is not supported.
280 report_fatal_error("Unsupported contant type");
Amaury Secheta82042e2016-02-09 22:36:41 +0000281 }
282
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000283 // Function argument should always be in the map already.
Amaury Sechet2f432082016-02-11 21:37:54 +0000284 auto i = VMap.find(Src);
285 if (i != VMap.end())
286 return i->second;
Amaury Secheta82042e2016-02-09 22:36:41 +0000287
Amaury Sechet2f432082016-02-11 21:37:54 +0000288 if (!LLVMIsAInstruction(Src))
289 report_fatal_error("Expected an instruction");
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000290
Amaury Sechet2f432082016-02-11 21:37:54 +0000291 auto Ctx = LLVMGetModuleContext(M);
292 auto Builder = LLVMCreateBuilderInContext(Ctx);
293 auto BB = DeclareBB(LLVMGetInstructionParent(Src));
294 LLVMPositionBuilderAtEnd(Builder, BB);
295 auto Dst = CloneInstruction(Src, Builder);
296 LLVMDisposeBuilder(Builder);
297 return Dst;
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000298 }
299
300 LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
301 const char *Name = LLVMGetValueName(Src);
302 if (!LLVMIsAInstruction(Src))
303 report_fatal_error("Expected an instruction");
304
Amaury Secheta82042e2016-02-09 22:36:41 +0000305 // Check if this is something we already computed.
306 {
307 auto i = VMap.find(Src);
Amaury Sechet2f432082016-02-11 21:37:54 +0000308 if (i != VMap.end()) {
309 // If we have a hit, it means we already generated the instruction
310 // as a dependancy to somethign else. We need to make sure
311 // it is ordered properly.
312 auto I = i->second;
313 LLVMInstructionRemoveFromParent(I);
314 LLVMInsertIntoBuilderWithName(Builder, I, Name);
315 return I;
316 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000317 }
318
319 // We tried everything, it must be an instruction
320 // that hasn't been generated already.
321 LLVMValueRef Dst = nullptr;
322
323 LLVMOpcode Op = LLVMGetInstructionOpcode(Src);
324 switch(Op) {
325 case LLVMRet: {
326 int OpCount = LLVMGetNumOperands(Src);
327 if (OpCount == 0)
328 Dst = LLVMBuildRetVoid(Builder);
329 else
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000330 Dst = LLVMBuildRet(Builder, CloneValue(LLVMGetOperand(Src, 0)));
Amaury Secheta82042e2016-02-09 22:36:41 +0000331 break;
332 }
333 case LLVMBr: {
Amaury Sechete7e62172016-02-09 23:15:02 +0000334 if (!LLVMIsConditional(Src)) {
335 LLVMValueRef SrcOp = LLVMGetOperand(Src, 0);
336 LLVMBasicBlockRef SrcBB = LLVMValueAsBasicBlock(SrcOp);
337 Dst = LLVMBuildBr(Builder, DeclareBB(SrcBB));
338 break;
339 }
340
341 LLVMValueRef Cond = LLVMGetCondition(Src);
342 LLVMValueRef Else = LLVMGetOperand(Src, 1);
343 LLVMBasicBlockRef ElseBB = DeclareBB(LLVMValueAsBasicBlock(Else));
344 LLVMValueRef Then = LLVMGetOperand(Src, 2);
345 LLVMBasicBlockRef ThenBB = DeclareBB(LLVMValueAsBasicBlock(Then));
346 Dst = LLVMBuildCondBr(Builder, Cond, ThenBB, ElseBB);
Amaury Secheta82042e2016-02-09 22:36:41 +0000347 break;
348 }
349 case LLVMSwitch:
350 case LLVMIndirectBr:
351 case LLVMInvoke:
352 break;
353 case LLVMUnreachable:
354 Dst = LLVMBuildUnreachable(Builder);
355 break;
356 case LLVMAdd: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000357 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
358 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000359 Dst = LLVMBuildAdd(Builder, LHS, RHS, Name);
360 break;
361 }
362 case LLVMSub: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000363 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
364 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000365 Dst = LLVMBuildSub(Builder, LHS, RHS, Name);
366 break;
367 }
368 case LLVMMul: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000369 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
370 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000371 Dst = LLVMBuildMul(Builder, LHS, RHS, Name);
372 break;
373 }
374 case LLVMUDiv: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000375 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
376 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000377 Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name);
378 break;
379 }
380 case LLVMSDiv: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000381 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
382 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000383 Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name);
384 break;
385 }
386 case LLVMURem: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000387 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
388 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000389 Dst = LLVMBuildURem(Builder, LHS, RHS, Name);
390 break;
391 }
392 case LLVMSRem: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000393 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
394 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000395 Dst = LLVMBuildSRem(Builder, LHS, RHS, Name);
396 break;
397 }
398 case LLVMShl: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000399 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
400 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000401 Dst = LLVMBuildShl(Builder, LHS, RHS, Name);
402 break;
403 }
404 case LLVMLShr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000405 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
406 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000407 Dst = LLVMBuildLShr(Builder, LHS, RHS, Name);
408 break;
409 }
410 case LLVMAShr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000411 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
412 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000413 Dst = LLVMBuildAShr(Builder, LHS, RHS, Name);
414 break;
415 }
416 case LLVMAnd: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000417 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
418 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000419 Dst = LLVMBuildAnd(Builder, LHS, RHS, Name);
420 break;
421 }
422 case LLVMOr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000423 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
424 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000425 Dst = LLVMBuildOr(Builder, LHS, RHS, Name);
426 break;
427 }
428 case LLVMXor: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000429 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
430 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000431 Dst = LLVMBuildXor(Builder, LHS, RHS, Name);
432 break;
433 }
434 case LLVMAlloca: {
Amaury Sechetaad93532016-02-10 00:38:50 +0000435 LLVMTypeRef Ty = CloneType(LLVMGetAllocatedType(Src));
Amaury Secheta82042e2016-02-09 22:36:41 +0000436 Dst = LLVMBuildAlloca(Builder, Ty, Name);
437 break;
438 }
Amaury Sechete7e62172016-02-09 23:15:02 +0000439 case LLVMICmp: {
440 LLVMIntPredicate Pred = LLVMGetICmpPredicate(Src);
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000441 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
442 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Sechete7e62172016-02-09 23:15:02 +0000443 Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name);
444 break;
445 }
Amaury Sechet2f432082016-02-11 21:37:54 +0000446 case LLVMPHI: {
447 // We need to agressively set things here because of loops.
448 VMap[Src] = Dst = LLVMBuildPhi(Builder, CloneType(Src), Name);
449
450 SmallVector<LLVMValueRef, 8> Values;
451 SmallVector<LLVMBasicBlockRef, 8> Blocks;
452
453 unsigned IncomingCount = LLVMCountIncoming(Src);
454 for (unsigned i = 0; i < IncomingCount; ++i) {
455 Blocks.push_back(DeclareBB(LLVMGetIncomingBlock(Src, i)));
456 Values.push_back(CloneValue(LLVMGetIncomingValue(Src, i)));
457 }
458
459 LLVMAddIncoming(Dst, Values.data(), Blocks.data(), IncomingCount);
460 return Dst;
461 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000462 case LLVMCall: {
Amaury Secheta82042e2016-02-09 22:36:41 +0000463 SmallVector<LLVMValueRef, 8> Args;
Amaury Sechet5c7b3af2016-02-10 00:09:37 +0000464 int ArgCount = LLVMGetNumArgOperands(Src);
Amaury Secheta82042e2016-02-09 22:36:41 +0000465 for (int i = 0; i < ArgCount; i++)
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000466 Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
Amaury Sechet5c7b3af2016-02-10 00:09:37 +0000467 LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
Amaury Secheta82042e2016-02-09 22:36:41 +0000468 Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
469 break;
470 }
Amaury Sechetaad93532016-02-10 00:38:50 +0000471 case LLVMExtractValue: {
472 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
473 if (LLVMGetNumIndices(Src) != 1)
474 report_fatal_error("Expected only one indice");
475 auto I = LLVMGetIndices(Src)[0];
476 Dst = LLVMBuildExtractValue(Builder, Agg, I, Name);
477 break;
478 }
479 case LLVMInsertValue: {
480 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
481 LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1));
482 if (LLVMGetNumIndices(Src) != 1)
483 report_fatal_error("Expected only one indice");
484 auto I = LLVMGetIndices(Src)[0];
485 Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name);
486 break;
487 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000488 default:
489 break;
490 }
491
492 if (Dst == nullptr) {
493 fprintf(stderr, "%d is not a supported opcode\n", Op);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000494 exit(-1);
495 }
496
Amaury Secheta82042e2016-02-09 22:36:41 +0000497 return VMap[Src] = Dst;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000498 }
499
Amaury Secheta82042e2016-02-09 22:36:41 +0000500 LLVMBasicBlockRef DeclareBB(LLVMBasicBlockRef Src) {
501 // Check if this is something we already computed.
502 {
503 auto i = BBMap.find(Src);
504 if (i != BBMap.end()) {
505 return i->second;
506 }
507 }
508
509 const char *Name = LLVMGetBasicBlockName(Src);
510
511 LLVMValueRef V = LLVMBasicBlockAsValue(Src);
512 if (!LLVMValueIsBasicBlock(V) || LLVMValueAsBasicBlock(V) != Src)
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000513 report_fatal_error("Basic block is not a basic block");
Amaury Secheta82042e2016-02-09 22:36:41 +0000514
515 const char *VName = LLVMGetValueName(V);
516 if (Name != VName)
517 report_fatal_error("Basic block name mismatch");
518
519 LLVMBasicBlockRef BB = LLVMAppendBasicBlock(Fun, Name);
520 return BBMap[Src] = BB;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000521 }
522
Amaury Secheta82042e2016-02-09 22:36:41 +0000523 LLVMBasicBlockRef CloneBB(LLVMBasicBlockRef Src) {
524 LLVMBasicBlockRef BB = DeclareBB(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000525
Amaury Secheta82042e2016-02-09 22:36:41 +0000526 // Make sure ordering is correct.
527 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Src);
528 if (Prev)
529 LLVMMoveBasicBlockAfter(BB, DeclareBB(Prev));
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000530
Amaury Secheta82042e2016-02-09 22:36:41 +0000531 LLVMValueRef First = LLVMGetFirstInstruction(Src);
532 LLVMValueRef Last = LLVMGetLastInstruction(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000533
Amaury Secheta82042e2016-02-09 22:36:41 +0000534 if (First == nullptr) {
535 if (Last != nullptr) {
536 fprintf(stderr, "Has no first instruction, but last one\n");
537 exit(-1);
538 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000539
Amaury Secheta82042e2016-02-09 22:36:41 +0000540 return BB;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000541 }
542
Amaury Sechetaad93532016-02-10 00:38:50 +0000543 auto Ctx = LLVMGetModuleContext(M);
Amaury Secheta82042e2016-02-09 22:36:41 +0000544 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);
545 LLVMPositionBuilderAtEnd(Builder, BB);
546
547 LLVMValueRef Cur = First;
548 LLVMValueRef Next = nullptr;
549 while(true) {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000550 CloneInstruction(Cur, Builder);
Amaury Secheta82042e2016-02-09 22:36:41 +0000551 Next = LLVMGetNextInstruction(Cur);
552 if (Next == nullptr) {
553 if (Cur != Last) {
554 fprintf(stderr, "Final instruction does not match Last\n");
555 exit(-1);
556 }
557
558 break;
559 }
560
561 LLVMValueRef Prev = LLVMGetPreviousInstruction(Next);
562 if (Prev != Cur) {
563 fprintf(stderr, "Next.Previous instruction is not Current\n");
564 exit(-1);
565 }
566
567 Cur = Next;
568 }
569
570 LLVMDisposeBuilder(Builder);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000571 return BB;
572 }
573
Amaury Secheta82042e2016-02-09 22:36:41 +0000574 void CloneBBs(LLVMValueRef Src) {
575 unsigned Count = LLVMCountBasicBlocks(Src);
576 if (Count == 0)
577 return;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000578
Amaury Secheta82042e2016-02-09 22:36:41 +0000579 LLVMBasicBlockRef First = LLVMGetFirstBasicBlock(Src);
580 LLVMBasicBlockRef Last = LLVMGetLastBasicBlock(Src);
581
582 LLVMBasicBlockRef Cur = First;
583 LLVMBasicBlockRef Next = nullptr;
584 while(true) {
585 CloneBB(Cur);
586 Count--;
587 Next = LLVMGetNextBasicBlock(Cur);
588 if (Next == nullptr) {
589 if (Cur != Last) {
590 fprintf(stderr, "Final basic block does not match Last\n");
591 exit(-1);
592 }
593
594 break;
595 }
596
597 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Next);
598 if (Prev != Cur) {
599 fprintf(stderr, "Next.Previous basic bloc is not Current\n");
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000600 exit(-1);
601 }
602
Amaury Secheta82042e2016-02-09 22:36:41 +0000603 Cur = Next;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000604 }
605
Amaury Secheta82042e2016-02-09 22:36:41 +0000606 if (Count != 0) {
607 fprintf(stderr, "Basic block count does not match iterration\n");
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000608 exit(-1);
609 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000610 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000611};
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000612
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000613static LLVMValueRef clone_function(LLVMValueRef Src, LLVMModuleRef M) {
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000614 const char *Name = LLVMGetValueName(Src);
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000615 LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000616 if (Fun != nullptr)
617 return Fun;
618
Amaury Sechetaad93532016-02-10 00:38:50 +0000619 LLVMTypeRef DstTy = TypeCloner(M).Clone(LLVMTypeOf(Src));
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000620 LLVMTypeRef FunTy = LLVMGetElementType(DstTy);
621
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000622 Fun = LLVMAddFunction(M, Name, FunTy);
Amaury Secheta82042e2016-02-09 22:36:41 +0000623 FunCloner FC(Src, Fun);
624 FC.CloneBBs(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000625
626 return Fun;
627}
628
629static void clone_functions(LLVMModuleRef Src, LLVMModuleRef Dst) {
630 LLVMValueRef Begin = LLVMGetFirstFunction(Src);
631 LLVMValueRef End = LLVMGetLastFunction(Src);
632
633 LLVMValueRef Cur = Begin;
634 LLVMValueRef Next = nullptr;
635 while (true) {
636 clone_function(Cur, Dst);
637 Next = LLVMGetNextFunction(Cur);
638 if (Next == nullptr) {
639 if (Cur != End) {
640 fprintf(stderr, "Last function does not match End\n");
641 exit(-1);
642 }
643
644 break;
645 }
646
647 LLVMValueRef Prev = LLVMGetPreviousFunction(Next);
648 if (Prev != Cur) {
649 fprintf(stderr, "Next.Previous function is not Current\n");
650 exit(-1);
651 }
652
653 Cur = Next;
654 }
655}
656
Benjamin Kramer9a3bd232016-02-05 13:31:14 +0000657int llvm_echo(void) {
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000658 LLVMEnablePrettyStackTrace();
659
Benjamin Kramer9a3bd232016-02-05 13:31:14 +0000660 LLVMModuleRef Src = llvm_load_module(false, true);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000661
662 LLVMContextRef Ctx = LLVMContextCreate();
663 LLVMModuleRef Dst = LLVMModuleCreateWithNameInContext("<stdin>", Ctx);
664
665 clone_functions(Src, Dst);
666 char *Str = LLVMPrintModuleToString(Dst);
667 fputs(Str, stdout);
668
669 LLVMDisposeMessage(Str);
670 LLVMDisposeModule(Dst);
671 LLVMContextDispose(Ctx);
672
673 return 0;
674}