blob: bfe91733617ab5165ceaa455664b71084965ea80 [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
Amaury Sechetc679dbd2016-02-14 09:30:42 +000063 LLVMTypeRef Clone(LLVMValueRef Src) {
64 return Clone(LLVMTypeOf(Src));
65 }
66
Amaury Sechetaad93532016-02-10 00:38:50 +000067 LLVMTypeRef Clone(LLVMTypeRef Src) {
68 LLVMTypeKind Kind = LLVMGetTypeKind(Src);
69 switch (Kind) {
70 case LLVMVoidTypeKind:
71 return LLVMVoidTypeInContext(Ctx);
72 case LLVMHalfTypeKind:
73 return LLVMHalfTypeInContext(Ctx);
74 case LLVMFloatTypeKind:
75 return LLVMFloatTypeInContext(Ctx);
76 case LLVMDoubleTypeKind:
77 return LLVMDoubleTypeInContext(Ctx);
78 case LLVMX86_FP80TypeKind:
79 return LLVMX86FP80TypeInContext(Ctx);
80 case LLVMFP128TypeKind:
81 return LLVMFP128TypeInContext(Ctx);
82 case LLVMPPC_FP128TypeKind:
83 return LLVMPPCFP128TypeInContext(Ctx);
84 case LLVMLabelTypeKind:
85 return LLVMLabelTypeInContext(Ctx);
86 case LLVMIntegerTypeKind:
87 return LLVMIntTypeInContext(Ctx, LLVMGetIntTypeWidth(Src));
88 case LLVMFunctionTypeKind: {
89 unsigned ParamCount = LLVMCountParamTypes(Src);
90 LLVMTypeRef* Params = nullptr;
91 if (ParamCount > 0) {
92 Params = (LLVMTypeRef*) malloc(ParamCount * sizeof(LLVMTypeRef));
93 LLVMGetParamTypes(Src, Params);
94 for (unsigned i = 0; i < ParamCount; i++)
95 Params[i] = Clone(Params[i]);
96 }
97
98 LLVMTypeRef FunTy = LLVMFunctionType(Clone(LLVMGetReturnType(Src)),
99 Params, ParamCount,
100 LLVMIsFunctionVarArg(Src));
101 if (ParamCount > 0)
102 free(Params);
103 return FunTy;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000104 }
Amaury Sechetaad93532016-02-10 00:38:50 +0000105 case LLVMStructTypeKind: {
106 LLVMTypeRef S = nullptr;
107 const char *Name = LLVMGetStructName(Src);
108 if (Name) {
109 S = LLVMGetTypeByName(M, Name);
110 if (S)
111 return S;
112 S = LLVMStructCreateNamed(Ctx, Name);
113 if (LLVMIsOpaqueStruct(Src))
114 return S;
115 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000116
Amaury Sechetaad93532016-02-10 00:38:50 +0000117 unsigned EltCount = LLVMCountStructElementTypes(Src);
118 SmallVector<LLVMTypeRef, 8> Elts;
119 for (unsigned i = 0; i < EltCount; i++)
120 Elts.push_back(Clone(LLVMStructGetTypeAtIndex(Src, i)));
121 if (Name)
122 LLVMStructSetBody(S, Elts.data(), EltCount, LLVMIsPackedStruct(Src));
123 else
124 S = LLVMStructTypeInContext(Ctx, Elts.data(), EltCount,
125 LLVMIsPackedStruct(Src));
126 return S;
127 }
128 case LLVMArrayTypeKind:
129 return LLVMArrayType(
130 Clone(LLVMGetElementType(Src)),
131 LLVMGetArrayLength(Src)
132 );
133 case LLVMPointerTypeKind:
134 return LLVMPointerType(
135 Clone(LLVMGetElementType(Src)),
136 LLVMGetPointerAddressSpace(Src)
137 );
138 case LLVMVectorTypeKind:
139 return LLVMVectorType(
140 Clone(LLVMGetElementType(Src)),
141 LLVMGetVectorSize(Src)
142 );
143 case LLVMMetadataTypeKind:
144 break;
145 case LLVMX86_MMXTypeKind:
146 return LLVMX86MMXTypeInContext(Ctx);
147 default:
148 break;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000149 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000150
Amaury Sechetaad93532016-02-10 00:38:50 +0000151 fprintf(stderr, "%d is not a supported typekind\n", Kind);
152 exit(-1);
153 }
154};
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000155
Amaury Sechetecda4ea2016-02-14 09:14:30 +0000156static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst) {
157 unsigned Count = LLVMCountParams(Src);
158 if (Count != LLVMCountParams(Dst)) {
159 fprintf(stderr, "Parameter count mismatch\n");
160 exit(-1);
161 }
162
163 ValueMap VMap;
164 if (Count == 0)
165 return VMap;
166
167 LLVMValueRef SrcFirst = LLVMGetFirstParam(Src);
168 LLVMValueRef DstFirst = LLVMGetFirstParam(Dst);
169 LLVMValueRef SrcLast = LLVMGetLastParam(Src);
170 LLVMValueRef DstLast = LLVMGetLastParam(Dst);
171
172 LLVMValueRef SrcCur = SrcFirst;
173 LLVMValueRef DstCur = DstFirst;
174 LLVMValueRef SrcNext = nullptr;
175 LLVMValueRef DstNext = nullptr;
176 while (true) {
177 const char *Name = LLVMGetValueName(SrcCur);
178 LLVMSetValueName(DstCur, Name);
179
180 VMap[SrcCur] = DstCur;
181
182 Count--;
183 SrcNext = LLVMGetNextParam(SrcCur);
184 DstNext = LLVMGetNextParam(DstCur);
185 if (SrcNext == nullptr && DstNext == nullptr) {
186 if (SrcCur != SrcLast) {
187 fprintf(stderr, "SrcLast param does not match End\n");
188 exit(-1);
189 }
190
191 if (DstCur != DstLast) {
192 fprintf(stderr, "DstLast param does not match End\n");
193 exit(-1);
194 }
195
196 break;
197 }
198
199 if (SrcNext == nullptr) {
200 fprintf(stderr, "SrcNext was unexpectedly null\n");
201 exit(-1);
202 }
203
204 if (DstNext == nullptr) {
205 fprintf(stderr, "DstNext was unexpectedly null\n");
206 exit(-1);
207 }
208
209 LLVMValueRef SrcPrev = LLVMGetPreviousParam(SrcNext);
210 if (SrcPrev != SrcCur) {
211 fprintf(stderr, "SrcNext.Previous param is not Current\n");
212 exit(-1);
213 }
214
215 LLVMValueRef DstPrev = LLVMGetPreviousParam(DstNext);
216 if (DstPrev != DstCur) {
217 fprintf(stderr, "DstNext.Previous param is not Current\n");
218 exit(-1);
219 }
220
221 SrcCur = SrcNext;
222 DstCur = DstNext;
223 }
224
225 if (Count != 0) {
226 fprintf(stderr, "Parameter count does not match iteration\n");
227 exit(-1);
228 }
229
230 return VMap;
231}
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000232
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000233LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) {
234 if (!LLVMIsAConstant(Cst))
235 report_fatal_error("Expected a constant");
236
237 // Maybe it is a symbol
238 if (LLVMIsAGlobalValue(Cst)) {
239 const char *Name = LLVMGetValueName(Cst);
240
241 // Try function
242 LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
243 if (Dst != nullptr)
244 return Dst;
245
246 // Try global variable
247 Dst = LLVMGetNamedGlobal(M, Name);
248 if (Dst != nullptr)
249 return Dst;
250
251 fprintf(stderr, "Could not find @%s\n", Name);
252 exit(-1);
253 }
254
255 // Try literal
256 if (LLVMIsAConstantInt(Cst))
257 return LLVMConstInt(TypeCloner(M).Clone(Cst),
258 LLVMConstIntGetZExtValue(Cst), false);
259
260 // Try undef
261 if (LLVMIsUndef(Cst))
262 return LLVMGetUndef(TypeCloner(M).Clone(Cst));
263
264 // This kind of constant is not supported.
265 report_fatal_error("Unsupported contant type");
266}
267
Amaury Secheta82042e2016-02-09 22:36:41 +0000268struct FunCloner {
269 LLVMValueRef Fun;
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000270 LLVMModuleRef M;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000271
Amaury Secheta82042e2016-02-09 22:36:41 +0000272 ValueMap VMap;
273 BasicBlockMap BBMap;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000274
Amaury Sechetaad93532016-02-10 00:38:50 +0000275 FunCloner(LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst),
276 M(LLVMGetGlobalParent(Fun)), VMap(clone_params(Src, Dst)) {}
277
278 LLVMTypeRef CloneType(LLVMTypeRef Src) {
279 return TypeCloner(M).Clone(Src);
280 }
281
282 LLVMTypeRef CloneType(LLVMValueRef Src) {
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000283 return TypeCloner(M).Clone(Src);
Amaury Sechetaad93532016-02-10 00:38:50 +0000284 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000285
Amaury Secheta82042e2016-02-09 22:36:41 +0000286 // Try to clone everything in the llvm::Value hierarchy.
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000287 LLVMValueRef CloneValue(LLVMValueRef Src) {
Amaury Secheta82042e2016-02-09 22:36:41 +0000288 // First, the value may be constant.
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000289 if (LLVMIsAConstant(Src))
290 return clone_constant(Src, M);
Amaury Secheta82042e2016-02-09 22:36:41 +0000291
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000292 // Function argument should always be in the map already.
Amaury Sechet2f432082016-02-11 21:37:54 +0000293 auto i = VMap.find(Src);
294 if (i != VMap.end())
295 return i->second;
Amaury Secheta82042e2016-02-09 22:36:41 +0000296
Amaury Sechet2f432082016-02-11 21:37:54 +0000297 if (!LLVMIsAInstruction(Src))
298 report_fatal_error("Expected an instruction");
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000299
Amaury Sechet2f432082016-02-11 21:37:54 +0000300 auto Ctx = LLVMGetModuleContext(M);
301 auto Builder = LLVMCreateBuilderInContext(Ctx);
302 auto BB = DeclareBB(LLVMGetInstructionParent(Src));
303 LLVMPositionBuilderAtEnd(Builder, BB);
304 auto Dst = CloneInstruction(Src, Builder);
305 LLVMDisposeBuilder(Builder);
306 return Dst;
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000307 }
308
309 LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
310 const char *Name = LLVMGetValueName(Src);
311 if (!LLVMIsAInstruction(Src))
312 report_fatal_error("Expected an instruction");
313
Amaury Secheta82042e2016-02-09 22:36:41 +0000314 // Check if this is something we already computed.
315 {
316 auto i = VMap.find(Src);
Amaury Sechet2f432082016-02-11 21:37:54 +0000317 if (i != VMap.end()) {
318 // If we have a hit, it means we already generated the instruction
319 // as a dependancy to somethign else. We need to make sure
320 // it is ordered properly.
321 auto I = i->second;
322 LLVMInstructionRemoveFromParent(I);
323 LLVMInsertIntoBuilderWithName(Builder, I, Name);
324 return I;
325 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000326 }
327
328 // We tried everything, it must be an instruction
329 // that hasn't been generated already.
330 LLVMValueRef Dst = nullptr;
331
332 LLVMOpcode Op = LLVMGetInstructionOpcode(Src);
333 switch(Op) {
334 case LLVMRet: {
335 int OpCount = LLVMGetNumOperands(Src);
336 if (OpCount == 0)
337 Dst = LLVMBuildRetVoid(Builder);
338 else
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000339 Dst = LLVMBuildRet(Builder, CloneValue(LLVMGetOperand(Src, 0)));
Amaury Secheta82042e2016-02-09 22:36:41 +0000340 break;
341 }
342 case LLVMBr: {
Amaury Sechete7e62172016-02-09 23:15:02 +0000343 if (!LLVMIsConditional(Src)) {
344 LLVMValueRef SrcOp = LLVMGetOperand(Src, 0);
345 LLVMBasicBlockRef SrcBB = LLVMValueAsBasicBlock(SrcOp);
346 Dst = LLVMBuildBr(Builder, DeclareBB(SrcBB));
347 break;
348 }
349
350 LLVMValueRef Cond = LLVMGetCondition(Src);
351 LLVMValueRef Else = LLVMGetOperand(Src, 1);
352 LLVMBasicBlockRef ElseBB = DeclareBB(LLVMValueAsBasicBlock(Else));
353 LLVMValueRef Then = LLVMGetOperand(Src, 2);
354 LLVMBasicBlockRef ThenBB = DeclareBB(LLVMValueAsBasicBlock(Then));
355 Dst = LLVMBuildCondBr(Builder, Cond, ThenBB, ElseBB);
Amaury Secheta82042e2016-02-09 22:36:41 +0000356 break;
357 }
358 case LLVMSwitch:
359 case LLVMIndirectBr:
360 case LLVMInvoke:
361 break;
362 case LLVMUnreachable:
363 Dst = LLVMBuildUnreachable(Builder);
364 break;
365 case LLVMAdd: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000366 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
367 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000368 Dst = LLVMBuildAdd(Builder, LHS, RHS, Name);
369 break;
370 }
371 case LLVMSub: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000372 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
373 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000374 Dst = LLVMBuildSub(Builder, LHS, RHS, Name);
375 break;
376 }
377 case LLVMMul: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000378 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
379 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000380 Dst = LLVMBuildMul(Builder, LHS, RHS, Name);
381 break;
382 }
383 case LLVMUDiv: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000384 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
385 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000386 Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name);
387 break;
388 }
389 case LLVMSDiv: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000390 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
391 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000392 Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name);
393 break;
394 }
395 case LLVMURem: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000396 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
397 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000398 Dst = LLVMBuildURem(Builder, LHS, RHS, Name);
399 break;
400 }
401 case LLVMSRem: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000402 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
403 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000404 Dst = LLVMBuildSRem(Builder, LHS, RHS, Name);
405 break;
406 }
407 case LLVMShl: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000408 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
409 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000410 Dst = LLVMBuildShl(Builder, LHS, RHS, Name);
411 break;
412 }
413 case LLVMLShr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000414 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
415 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000416 Dst = LLVMBuildLShr(Builder, LHS, RHS, Name);
417 break;
418 }
419 case LLVMAShr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000420 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
421 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000422 Dst = LLVMBuildAShr(Builder, LHS, RHS, Name);
423 break;
424 }
425 case LLVMAnd: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000426 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
427 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000428 Dst = LLVMBuildAnd(Builder, LHS, RHS, Name);
429 break;
430 }
431 case LLVMOr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000432 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
433 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000434 Dst = LLVMBuildOr(Builder, LHS, RHS, Name);
435 break;
436 }
437 case LLVMXor: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000438 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
439 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000440 Dst = LLVMBuildXor(Builder, LHS, RHS, Name);
441 break;
442 }
443 case LLVMAlloca: {
Amaury Sechetaad93532016-02-10 00:38:50 +0000444 LLVMTypeRef Ty = CloneType(LLVMGetAllocatedType(Src));
Amaury Secheta82042e2016-02-09 22:36:41 +0000445 Dst = LLVMBuildAlloca(Builder, Ty, Name);
446 break;
447 }
Amaury Sechete7e62172016-02-09 23:15:02 +0000448 case LLVMICmp: {
449 LLVMIntPredicate Pred = LLVMGetICmpPredicate(Src);
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000450 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
451 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Sechete7e62172016-02-09 23:15:02 +0000452 Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name);
453 break;
454 }
Amaury Sechet2f432082016-02-11 21:37:54 +0000455 case LLVMPHI: {
456 // We need to agressively set things here because of loops.
457 VMap[Src] = Dst = LLVMBuildPhi(Builder, CloneType(Src), Name);
458
459 SmallVector<LLVMValueRef, 8> Values;
460 SmallVector<LLVMBasicBlockRef, 8> Blocks;
461
462 unsigned IncomingCount = LLVMCountIncoming(Src);
463 for (unsigned i = 0; i < IncomingCount; ++i) {
464 Blocks.push_back(DeclareBB(LLVMGetIncomingBlock(Src, i)));
465 Values.push_back(CloneValue(LLVMGetIncomingValue(Src, i)));
466 }
467
468 LLVMAddIncoming(Dst, Values.data(), Blocks.data(), IncomingCount);
469 return Dst;
470 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000471 case LLVMCall: {
Amaury Secheta82042e2016-02-09 22:36:41 +0000472 SmallVector<LLVMValueRef, 8> Args;
Amaury Sechet5c7b3af2016-02-10 00:09:37 +0000473 int ArgCount = LLVMGetNumArgOperands(Src);
Amaury Secheta82042e2016-02-09 22:36:41 +0000474 for (int i = 0; i < ArgCount; i++)
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000475 Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
Amaury Sechet5c7b3af2016-02-10 00:09:37 +0000476 LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
Amaury Secheta82042e2016-02-09 22:36:41 +0000477 Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
478 break;
479 }
Amaury Sechetaad93532016-02-10 00:38:50 +0000480 case LLVMExtractValue: {
481 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
482 if (LLVMGetNumIndices(Src) != 1)
483 report_fatal_error("Expected only one indice");
484 auto I = LLVMGetIndices(Src)[0];
485 Dst = LLVMBuildExtractValue(Builder, Agg, I, Name);
486 break;
487 }
488 case LLVMInsertValue: {
489 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
490 LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1));
491 if (LLVMGetNumIndices(Src) != 1)
492 report_fatal_error("Expected only one indice");
493 auto I = LLVMGetIndices(Src)[0];
494 Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name);
495 break;
496 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000497 default:
498 break;
499 }
500
501 if (Dst == nullptr) {
502 fprintf(stderr, "%d is not a supported opcode\n", Op);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000503 exit(-1);
504 }
505
Amaury Secheta82042e2016-02-09 22:36:41 +0000506 return VMap[Src] = Dst;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000507 }
508
Amaury Secheta82042e2016-02-09 22:36:41 +0000509 LLVMBasicBlockRef DeclareBB(LLVMBasicBlockRef Src) {
510 // Check if this is something we already computed.
511 {
512 auto i = BBMap.find(Src);
513 if (i != BBMap.end()) {
514 return i->second;
515 }
516 }
517
518 const char *Name = LLVMGetBasicBlockName(Src);
519
520 LLVMValueRef V = LLVMBasicBlockAsValue(Src);
521 if (!LLVMValueIsBasicBlock(V) || LLVMValueAsBasicBlock(V) != Src)
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000522 report_fatal_error("Basic block is not a basic block");
Amaury Secheta82042e2016-02-09 22:36:41 +0000523
524 const char *VName = LLVMGetValueName(V);
525 if (Name != VName)
526 report_fatal_error("Basic block name mismatch");
527
528 LLVMBasicBlockRef BB = LLVMAppendBasicBlock(Fun, Name);
529 return BBMap[Src] = BB;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000530 }
531
Amaury Secheta82042e2016-02-09 22:36:41 +0000532 LLVMBasicBlockRef CloneBB(LLVMBasicBlockRef Src) {
533 LLVMBasicBlockRef BB = DeclareBB(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000534
Amaury Secheta82042e2016-02-09 22:36:41 +0000535 // Make sure ordering is correct.
536 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Src);
537 if (Prev)
538 LLVMMoveBasicBlockAfter(BB, DeclareBB(Prev));
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000539
Amaury Secheta82042e2016-02-09 22:36:41 +0000540 LLVMValueRef First = LLVMGetFirstInstruction(Src);
541 LLVMValueRef Last = LLVMGetLastInstruction(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000542
Amaury Secheta82042e2016-02-09 22:36:41 +0000543 if (First == nullptr) {
544 if (Last != nullptr) {
545 fprintf(stderr, "Has no first instruction, but last one\n");
546 exit(-1);
547 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000548
Amaury Secheta82042e2016-02-09 22:36:41 +0000549 return BB;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000550 }
551
Amaury Sechetaad93532016-02-10 00:38:50 +0000552 auto Ctx = LLVMGetModuleContext(M);
Amaury Secheta82042e2016-02-09 22:36:41 +0000553 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);
554 LLVMPositionBuilderAtEnd(Builder, BB);
555
556 LLVMValueRef Cur = First;
557 LLVMValueRef Next = nullptr;
558 while(true) {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000559 CloneInstruction(Cur, Builder);
Amaury Secheta82042e2016-02-09 22:36:41 +0000560 Next = LLVMGetNextInstruction(Cur);
561 if (Next == nullptr) {
562 if (Cur != Last) {
563 fprintf(stderr, "Final instruction does not match Last\n");
564 exit(-1);
565 }
566
567 break;
568 }
569
570 LLVMValueRef Prev = LLVMGetPreviousInstruction(Next);
571 if (Prev != Cur) {
572 fprintf(stderr, "Next.Previous instruction is not Current\n");
573 exit(-1);
574 }
575
576 Cur = Next;
577 }
578
579 LLVMDisposeBuilder(Builder);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000580 return BB;
581 }
582
Amaury Secheta82042e2016-02-09 22:36:41 +0000583 void CloneBBs(LLVMValueRef Src) {
584 unsigned Count = LLVMCountBasicBlocks(Src);
585 if (Count == 0)
586 return;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000587
Amaury Secheta82042e2016-02-09 22:36:41 +0000588 LLVMBasicBlockRef First = LLVMGetFirstBasicBlock(Src);
589 LLVMBasicBlockRef Last = LLVMGetLastBasicBlock(Src);
590
591 LLVMBasicBlockRef Cur = First;
592 LLVMBasicBlockRef Next = nullptr;
593 while(true) {
594 CloneBB(Cur);
595 Count--;
596 Next = LLVMGetNextBasicBlock(Cur);
597 if (Next == nullptr) {
598 if (Cur != Last) {
599 fprintf(stderr, "Final basic block does not match Last\n");
600 exit(-1);
601 }
602
603 break;
604 }
605
606 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Next);
607 if (Prev != Cur) {
608 fprintf(stderr, "Next.Previous basic bloc is not Current\n");
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000609 exit(-1);
610 }
611
Amaury Secheta82042e2016-02-09 22:36:41 +0000612 Cur = Next;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000613 }
614
Amaury Secheta82042e2016-02-09 22:36:41 +0000615 if (Count != 0) {
616 fprintf(stderr, "Basic block count does not match iterration\n");
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000617 exit(-1);
618 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000619 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000620};
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000621
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000622static LLVMValueRef clone_function(LLVMValueRef Src, LLVMModuleRef M) {
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000623 const char *Name = LLVMGetValueName(Src);
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000624 LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000625 if (Fun != nullptr)
626 return Fun;
627
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000628 LLVMTypeRef FunTy = LLVMGetElementType(TypeCloner(M).Clone(Src));
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000629 Fun = LLVMAddFunction(M, Name, FunTy);
Amaury Secheta82042e2016-02-09 22:36:41 +0000630 FunCloner FC(Src, Fun);
631 FC.CloneBBs(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000632
633 return Fun;
634}
635
636static void clone_functions(LLVMModuleRef Src, LLVMModuleRef Dst) {
637 LLVMValueRef Begin = LLVMGetFirstFunction(Src);
638 LLVMValueRef End = LLVMGetLastFunction(Src);
639
640 LLVMValueRef Cur = Begin;
641 LLVMValueRef Next = nullptr;
642 while (true) {
643 clone_function(Cur, Dst);
644 Next = LLVMGetNextFunction(Cur);
645 if (Next == nullptr) {
646 if (Cur != End) {
647 fprintf(stderr, "Last function does not match End\n");
648 exit(-1);
649 }
650
651 break;
652 }
653
654 LLVMValueRef Prev = LLVMGetPreviousFunction(Next);
655 if (Prev != Cur) {
656 fprintf(stderr, "Next.Previous function is not Current\n");
657 exit(-1);
658 }
659
660 Cur = Next;
661 }
662}
663
Benjamin Kramer9a3bd232016-02-05 13:31:14 +0000664int llvm_echo(void) {
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000665 LLVMEnablePrettyStackTrace();
666
Benjamin Kramer9a3bd232016-02-05 13:31:14 +0000667 LLVMModuleRef Src = llvm_load_module(false, true);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000668
669 LLVMContextRef Ctx = LLVMContextCreate();
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000670 LLVMModuleRef M = LLVMModuleCreateWithNameInContext("<stdin>", Ctx);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000671
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000672 clone_functions(Src, M);
673 char *Str = LLVMPrintModuleToString(M);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000674 fputs(Str, stdout);
675
676 LLVMDisposeMessage(Str);
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000677 LLVMDisposeModule(M);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000678 LLVMContextDispose(Ctx);
679
680 return 0;
681}