blob: 8d679b6928ab304a2c7052d8f1c1414e55eb418c [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 Secheta82042e2016-02-09 22:36:41 +0000152static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000153
Amaury Secheta82042e2016-02-09 22:36:41 +0000154struct FunCloner {
155 LLVMValueRef Fun;
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000156 LLVMModuleRef M;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000157
Amaury Secheta82042e2016-02-09 22:36:41 +0000158 ValueMap VMap;
159 BasicBlockMap BBMap;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000160
Amaury Sechetaad93532016-02-10 00:38:50 +0000161 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 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000171
Amaury Secheta82042e2016-02-09 22:36:41 +0000172 // Try to clone everything in the llvm::Value hierarchy.
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000173 LLVMValueRef CloneValue(LLVMValueRef Src) {
Amaury Secheta82042e2016-02-09 22:36:41 +0000174 const char *Name = LLVMGetValueName(Src);
175
176 // First, the value may be constant.
177 if (LLVMIsAConstant(Src)) {
Amaury Secheta82042e2016-02-09 22:36:41 +0000178 // Maybe it is a symbol
179 if (LLVMIsAGlobalValue(Src)) {
180 // Try function
181 LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
182 if (Dst != nullptr)
183 return Dst;
184
185 // Try global variable
186 Dst = LLVMGetNamedGlobal(M, Name);
187 if (Dst != nullptr)
188 return Dst;
189
190 fprintf(stderr, "Could not find @%s\n", Name);
191 exit(-1);
192 }
193
194 // Try literal
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000195 if (LLVMIsAConstantInt(Src)) {
Amaury Sechetaad93532016-02-10 00:38:50 +0000196 LLVMTypeRef Ty = CloneType(Src);
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000197 return LLVMConstInt(Ty, LLVMConstIntGetZExtValue(Src), false);
198 }
199
200 // Try undef
201 if (LLVMIsUndef(Src))
Amaury Sechetaad93532016-02-10 00:38:50 +0000202 return LLVMGetUndef(CloneType(Src));
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000203
204 // This kind of constant is not supported.
205 report_fatal_error("Unsupported contant type");
Amaury Secheta82042e2016-02-09 22:36:41 +0000206 }
207
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000208 // Function argument should always be in the map already.
Amaury Sechet2f432082016-02-11 21:37:54 +0000209 auto i = VMap.find(Src);
210 if (i != VMap.end())
211 return i->second;
Amaury Secheta82042e2016-02-09 22:36:41 +0000212
Amaury Sechet2f432082016-02-11 21:37:54 +0000213 if (!LLVMIsAInstruction(Src))
214 report_fatal_error("Expected an instruction");
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000215
Amaury Sechet2f432082016-02-11 21:37:54 +0000216 auto Ctx = LLVMGetModuleContext(M);
217 auto Builder = LLVMCreateBuilderInContext(Ctx);
218 auto BB = DeclareBB(LLVMGetInstructionParent(Src));
219 LLVMPositionBuilderAtEnd(Builder, BB);
220 auto Dst = CloneInstruction(Src, Builder);
221 LLVMDisposeBuilder(Builder);
222 return Dst;
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000223 }
224
225 LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
226 const char *Name = LLVMGetValueName(Src);
227 if (!LLVMIsAInstruction(Src))
228 report_fatal_error("Expected an instruction");
229
Amaury Secheta82042e2016-02-09 22:36:41 +0000230 // Check if this is something we already computed.
231 {
232 auto i = VMap.find(Src);
Amaury Sechet2f432082016-02-11 21:37:54 +0000233 if (i != VMap.end()) {
234 // If we have a hit, it means we already generated the instruction
235 // as a dependancy to somethign else. We need to make sure
236 // it is ordered properly.
237 auto I = i->second;
238 LLVMInstructionRemoveFromParent(I);
239 LLVMInsertIntoBuilderWithName(Builder, I, Name);
240 return I;
241 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000242 }
243
244 // We tried everything, it must be an instruction
245 // that hasn't been generated already.
246 LLVMValueRef Dst = nullptr;
247
248 LLVMOpcode Op = LLVMGetInstructionOpcode(Src);
249 switch(Op) {
250 case LLVMRet: {
251 int OpCount = LLVMGetNumOperands(Src);
252 if (OpCount == 0)
253 Dst = LLVMBuildRetVoid(Builder);
254 else
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000255 Dst = LLVMBuildRet(Builder, CloneValue(LLVMGetOperand(Src, 0)));
Amaury Secheta82042e2016-02-09 22:36:41 +0000256 break;
257 }
258 case LLVMBr: {
Amaury Sechete7e62172016-02-09 23:15:02 +0000259 if (!LLVMIsConditional(Src)) {
260 LLVMValueRef SrcOp = LLVMGetOperand(Src, 0);
261 LLVMBasicBlockRef SrcBB = LLVMValueAsBasicBlock(SrcOp);
262 Dst = LLVMBuildBr(Builder, DeclareBB(SrcBB));
263 break;
264 }
265
266 LLVMValueRef Cond = LLVMGetCondition(Src);
267 LLVMValueRef Else = LLVMGetOperand(Src, 1);
268 LLVMBasicBlockRef ElseBB = DeclareBB(LLVMValueAsBasicBlock(Else));
269 LLVMValueRef Then = LLVMGetOperand(Src, 2);
270 LLVMBasicBlockRef ThenBB = DeclareBB(LLVMValueAsBasicBlock(Then));
271 Dst = LLVMBuildCondBr(Builder, Cond, ThenBB, ElseBB);
Amaury Secheta82042e2016-02-09 22:36:41 +0000272 break;
273 }
274 case LLVMSwitch:
275 case LLVMIndirectBr:
276 case LLVMInvoke:
277 break;
278 case LLVMUnreachable:
279 Dst = LLVMBuildUnreachable(Builder);
280 break;
281 case LLVMAdd: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000282 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
283 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000284 Dst = LLVMBuildAdd(Builder, LHS, RHS, Name);
285 break;
286 }
287 case LLVMSub: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000288 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
289 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000290 Dst = LLVMBuildSub(Builder, LHS, RHS, Name);
291 break;
292 }
293 case LLVMMul: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000294 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
295 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000296 Dst = LLVMBuildMul(Builder, LHS, RHS, Name);
297 break;
298 }
299 case LLVMUDiv: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000300 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
301 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000302 Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name);
303 break;
304 }
305 case LLVMSDiv: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000306 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
307 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000308 Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name);
309 break;
310 }
311 case LLVMURem: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000312 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
313 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000314 Dst = LLVMBuildURem(Builder, LHS, RHS, Name);
315 break;
316 }
317 case LLVMSRem: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000318 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
319 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000320 Dst = LLVMBuildSRem(Builder, LHS, RHS, Name);
321 break;
322 }
323 case LLVMShl: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000324 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
325 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000326 Dst = LLVMBuildShl(Builder, LHS, RHS, Name);
327 break;
328 }
329 case LLVMLShr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000330 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
331 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000332 Dst = LLVMBuildLShr(Builder, LHS, RHS, Name);
333 break;
334 }
335 case LLVMAShr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000336 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
337 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000338 Dst = LLVMBuildAShr(Builder, LHS, RHS, Name);
339 break;
340 }
341 case LLVMAnd: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000342 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
343 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000344 Dst = LLVMBuildAnd(Builder, LHS, RHS, Name);
345 break;
346 }
347 case LLVMOr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000348 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
349 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000350 Dst = LLVMBuildOr(Builder, LHS, RHS, Name);
351 break;
352 }
353 case LLVMXor: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000354 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
355 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000356 Dst = LLVMBuildXor(Builder, LHS, RHS, Name);
357 break;
358 }
359 case LLVMAlloca: {
Amaury Sechetaad93532016-02-10 00:38:50 +0000360 LLVMTypeRef Ty = CloneType(LLVMGetAllocatedType(Src));
Amaury Secheta82042e2016-02-09 22:36:41 +0000361 Dst = LLVMBuildAlloca(Builder, Ty, Name);
362 break;
363 }
Amaury Sechete7e62172016-02-09 23:15:02 +0000364 case LLVMICmp: {
365 LLVMIntPredicate Pred = LLVMGetICmpPredicate(Src);
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000366 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
367 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Sechete7e62172016-02-09 23:15:02 +0000368 Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name);
369 break;
370 }
Amaury Sechet2f432082016-02-11 21:37:54 +0000371 case LLVMPHI: {
372 // We need to agressively set things here because of loops.
373 VMap[Src] = Dst = LLVMBuildPhi(Builder, CloneType(Src), Name);
374
375 SmallVector<LLVMValueRef, 8> Values;
376 SmallVector<LLVMBasicBlockRef, 8> Blocks;
377
378 unsigned IncomingCount = LLVMCountIncoming(Src);
379 for (unsigned i = 0; i < IncomingCount; ++i) {
380 Blocks.push_back(DeclareBB(LLVMGetIncomingBlock(Src, i)));
381 Values.push_back(CloneValue(LLVMGetIncomingValue(Src, i)));
382 }
383
384 LLVMAddIncoming(Dst, Values.data(), Blocks.data(), IncomingCount);
385 return Dst;
386 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000387 case LLVMCall: {
Amaury Secheta82042e2016-02-09 22:36:41 +0000388 SmallVector<LLVMValueRef, 8> Args;
Amaury Sechet5c7b3af2016-02-10 00:09:37 +0000389 int ArgCount = LLVMGetNumArgOperands(Src);
Amaury Secheta82042e2016-02-09 22:36:41 +0000390 for (int i = 0; i < ArgCount; i++)
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000391 Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
Amaury Sechet5c7b3af2016-02-10 00:09:37 +0000392 LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
Amaury Secheta82042e2016-02-09 22:36:41 +0000393 Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
394 break;
395 }
Amaury Sechetaad93532016-02-10 00:38:50 +0000396 case LLVMExtractValue: {
397 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
398 if (LLVMGetNumIndices(Src) != 1)
399 report_fatal_error("Expected only one indice");
400 auto I = LLVMGetIndices(Src)[0];
401 Dst = LLVMBuildExtractValue(Builder, Agg, I, Name);
402 break;
403 }
404 case LLVMInsertValue: {
405 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
406 LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1));
407 if (LLVMGetNumIndices(Src) != 1)
408 report_fatal_error("Expected only one indice");
409 auto I = LLVMGetIndices(Src)[0];
410 Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name);
411 break;
412 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000413 default:
414 break;
415 }
416
417 if (Dst == nullptr) {
418 fprintf(stderr, "%d is not a supported opcode\n", Op);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000419 exit(-1);
420 }
421
Amaury Secheta82042e2016-02-09 22:36:41 +0000422 return VMap[Src] = Dst;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000423 }
424
Amaury Secheta82042e2016-02-09 22:36:41 +0000425 LLVMBasicBlockRef DeclareBB(LLVMBasicBlockRef Src) {
426 // Check if this is something we already computed.
427 {
428 auto i = BBMap.find(Src);
429 if (i != BBMap.end()) {
430 return i->second;
431 }
432 }
433
434 const char *Name = LLVMGetBasicBlockName(Src);
435
436 LLVMValueRef V = LLVMBasicBlockAsValue(Src);
437 if (!LLVMValueIsBasicBlock(V) || LLVMValueAsBasicBlock(V) != Src)
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000438 report_fatal_error("Basic block is not a basic block");
Amaury Secheta82042e2016-02-09 22:36:41 +0000439
440 const char *VName = LLVMGetValueName(V);
441 if (Name != VName)
442 report_fatal_error("Basic block name mismatch");
443
444 LLVMBasicBlockRef BB = LLVMAppendBasicBlock(Fun, Name);
445 return BBMap[Src] = BB;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000446 }
447
Amaury Secheta82042e2016-02-09 22:36:41 +0000448 LLVMBasicBlockRef CloneBB(LLVMBasicBlockRef Src) {
449 LLVMBasicBlockRef BB = DeclareBB(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000450
Amaury Secheta82042e2016-02-09 22:36:41 +0000451 // Make sure ordering is correct.
452 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Src);
453 if (Prev)
454 LLVMMoveBasicBlockAfter(BB, DeclareBB(Prev));
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000455
Amaury Secheta82042e2016-02-09 22:36:41 +0000456 LLVMValueRef First = LLVMGetFirstInstruction(Src);
457 LLVMValueRef Last = LLVMGetLastInstruction(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000458
Amaury Secheta82042e2016-02-09 22:36:41 +0000459 if (First == nullptr) {
460 if (Last != nullptr) {
461 fprintf(stderr, "Has no first instruction, but last one\n");
462 exit(-1);
463 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000464
Amaury Secheta82042e2016-02-09 22:36:41 +0000465 return BB;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000466 }
467
Amaury Sechetaad93532016-02-10 00:38:50 +0000468 auto Ctx = LLVMGetModuleContext(M);
Amaury Secheta82042e2016-02-09 22:36:41 +0000469 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);
470 LLVMPositionBuilderAtEnd(Builder, BB);
471
472 LLVMValueRef Cur = First;
473 LLVMValueRef Next = nullptr;
474 while(true) {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000475 CloneInstruction(Cur, Builder);
Amaury Secheta82042e2016-02-09 22:36:41 +0000476 Next = LLVMGetNextInstruction(Cur);
477 if (Next == nullptr) {
478 if (Cur != Last) {
479 fprintf(stderr, "Final instruction does not match Last\n");
480 exit(-1);
481 }
482
483 break;
484 }
485
486 LLVMValueRef Prev = LLVMGetPreviousInstruction(Next);
487 if (Prev != Cur) {
488 fprintf(stderr, "Next.Previous instruction is not Current\n");
489 exit(-1);
490 }
491
492 Cur = Next;
493 }
494
495 LLVMDisposeBuilder(Builder);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000496 return BB;
497 }
498
Amaury Secheta82042e2016-02-09 22:36:41 +0000499 void CloneBBs(LLVMValueRef Src) {
500 unsigned Count = LLVMCountBasicBlocks(Src);
501 if (Count == 0)
502 return;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000503
Amaury Secheta82042e2016-02-09 22:36:41 +0000504 LLVMBasicBlockRef First = LLVMGetFirstBasicBlock(Src);
505 LLVMBasicBlockRef Last = LLVMGetLastBasicBlock(Src);
506
507 LLVMBasicBlockRef Cur = First;
508 LLVMBasicBlockRef Next = nullptr;
509 while(true) {
510 CloneBB(Cur);
511 Count--;
512 Next = LLVMGetNextBasicBlock(Cur);
513 if (Next == nullptr) {
514 if (Cur != Last) {
515 fprintf(stderr, "Final basic block does not match Last\n");
516 exit(-1);
517 }
518
519 break;
520 }
521
522 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Next);
523 if (Prev != Cur) {
524 fprintf(stderr, "Next.Previous basic bloc is not Current\n");
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000525 exit(-1);
526 }
527
Amaury Secheta82042e2016-02-09 22:36:41 +0000528 Cur = Next;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000529 }
530
Amaury Secheta82042e2016-02-09 22:36:41 +0000531 if (Count != 0) {
532 fprintf(stderr, "Basic block count does not match iterration\n");
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000533 exit(-1);
534 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000535 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000536};
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000537
538static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst) {
539 unsigned Count = LLVMCountParams(Src);
540 if (Count != LLVMCountParams(Dst)) {
541 fprintf(stderr, "Parameter count mismatch\n");
542 exit(-1);
543 }
544
545 ValueMap VMap;
546 if (Count == 0)
547 return VMap;
548
549 LLVMValueRef SrcFirst = LLVMGetFirstParam(Src);
550 LLVMValueRef DstFirst = LLVMGetFirstParam(Dst);
551 LLVMValueRef SrcLast = LLVMGetLastParam(Src);
552 LLVMValueRef DstLast = LLVMGetLastParam(Dst);
553
554 LLVMValueRef SrcCur = SrcFirst;
555 LLVMValueRef DstCur = DstFirst;
556 LLVMValueRef SrcNext = nullptr;
557 LLVMValueRef DstNext = nullptr;
558 while (true) {
559 const char *Name = LLVMGetValueName(SrcCur);
560 LLVMSetValueName(DstCur, Name);
561
562 VMap[SrcCur] = DstCur;
563
564 Count--;
565 SrcNext = LLVMGetNextParam(SrcCur);
566 DstNext = LLVMGetNextParam(DstCur);
567 if (SrcNext == nullptr && DstNext == nullptr) {
568 if (SrcCur != SrcLast) {
569 fprintf(stderr, "SrcLast param does not match End\n");
570 exit(-1);
571 }
572
573 if (DstCur != DstLast) {
574 fprintf(stderr, "DstLast param does not match End\n");
575 exit(-1);
576 }
577
578 break;
579 }
580
581 if (SrcNext == nullptr) {
582 fprintf(stderr, "SrcNext was unexpectedly null\n");
583 exit(-1);
584 }
585
586 if (DstNext == nullptr) {
587 fprintf(stderr, "DstNext was unexpectedly null\n");
588 exit(-1);
589 }
590
591 LLVMValueRef SrcPrev = LLVMGetPreviousParam(SrcNext);
592 if (SrcPrev != SrcCur) {
593 fprintf(stderr, "SrcNext.Previous param is not Current\n");
594 exit(-1);
595 }
596
597 LLVMValueRef DstPrev = LLVMGetPreviousParam(DstNext);
598 if (DstPrev != DstCur) {
599 fprintf(stderr, "DstNext.Previous param is not Current\n");
600 exit(-1);
601 }
602
603 SrcCur = SrcNext;
604 DstCur = DstNext;
605 }
606
607 if (Count != 0) {
608 fprintf(stderr, "Parameter count does not match iteration\n");
609 exit(-1);
610 }
611
612 return VMap;
613}
614
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000615static LLVMValueRef clone_function(LLVMValueRef Src, LLVMModuleRef M) {
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000616 const char *Name = LLVMGetValueName(Src);
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000617 LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000618 if (Fun != nullptr)
619 return Fun;
620
Amaury Sechetaad93532016-02-10 00:38:50 +0000621 LLVMTypeRef DstTy = TypeCloner(M).Clone(LLVMTypeOf(Src));
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000622 LLVMTypeRef FunTy = LLVMGetElementType(DstTy);
623
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000624 Fun = LLVMAddFunction(M, Name, FunTy);
Amaury Secheta82042e2016-02-09 22:36:41 +0000625 FunCloner FC(Src, Fun);
626 FC.CloneBBs(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000627
628 return Fun;
629}
630
631static void clone_functions(LLVMModuleRef Src, LLVMModuleRef Dst) {
632 LLVMValueRef Begin = LLVMGetFirstFunction(Src);
633 LLVMValueRef End = LLVMGetLastFunction(Src);
634
635 LLVMValueRef Cur = Begin;
636 LLVMValueRef Next = nullptr;
637 while (true) {
638 clone_function(Cur, Dst);
639 Next = LLVMGetNextFunction(Cur);
640 if (Next == nullptr) {
641 if (Cur != End) {
642 fprintf(stderr, "Last function does not match End\n");
643 exit(-1);
644 }
645
646 break;
647 }
648
649 LLVMValueRef Prev = LLVMGetPreviousFunction(Next);
650 if (Prev != Cur) {
651 fprintf(stderr, "Next.Previous function is not Current\n");
652 exit(-1);
653 }
654
655 Cur = Next;
656 }
657}
658
Benjamin Kramer9a3bd232016-02-05 13:31:14 +0000659int llvm_echo(void) {
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000660 LLVMEnablePrettyStackTrace();
661
Benjamin Kramer9a3bd232016-02-05 13:31:14 +0000662 LLVMModuleRef Src = llvm_load_module(false, true);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000663
664 LLVMContextRef Ctx = LLVMContextCreate();
665 LLVMModuleRef Dst = LLVMModuleCreateWithNameInContext("<stdin>", Ctx);
666
667 clone_functions(Src, Dst);
668 char *Str = LLVMPrintModuleToString(Dst);
669 fputs(Str, stdout);
670
671 LLVMDisposeMessage(Str);
672 LLVMDisposeModule(Dst);
673 LLVMContextDispose(Ctx);
674
675 return 0;
676}