blob: b0e47d8f544fe63d513fbe07e7fae7521ba1e967 [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"
Eugene Zelenko1760dc22016-04-05 20:19:49 +000019#include "llvm-c/Core.h"
20#include "llvm-c/ErrorHandling.h"
Amaury Sechet55909672016-02-16 05:11:24 +000021#include "llvm-c/Target.h"
Eugene Zelenko1760dc22016-04-05 20:19:49 +000022#include "llvm-c/Types.h"
Amaury Sechete8ea7d82016-02-04 23:26:19 +000023#include "llvm/ADT/DenseMap.h"
Eugene Zelenko1760dc22016-04-05 20:19:49 +000024#include "llvm/ADT/Hashing.h"
25#include "llvm/ADT/SmallVector.h"
Amaury Secheta82042e2016-02-09 22:36:41 +000026#include "llvm/Support/ErrorHandling.h"
Amaury Sechete8ea7d82016-02-04 23:26:19 +000027
Eugene Zelenko1760dc22016-04-05 20:19:49 +000028#include <cstdio>
29#include <cstdlib>
30#include <cstring>
Amaury Sechete8ea7d82016-02-04 23:26:19 +000031
32using namespace llvm;
33
34// Provide DenseMapInfo for C API opaque types.
35template<typename T>
36struct CAPIDenseMap {};
37
38// The default DenseMapInfo require to know about pointer alignement.
39// Because the C API uses opaques pointer types, their alignement is unknown.
40// As a result, we need to roll out our own implementation.
41template<typename T>
42struct CAPIDenseMap<T*> {
43 struct CAPIDenseMapInfo {
44 static inline T* getEmptyKey() {
45 uintptr_t Val = static_cast<uintptr_t>(-1);
46 return reinterpret_cast<T*>(Val);
47 }
Eugene Zelenko1760dc22016-04-05 20:19:49 +000048
Amaury Sechete8ea7d82016-02-04 23:26:19 +000049 static inline T* getTombstoneKey() {
50 uintptr_t Val = static_cast<uintptr_t>(-2);
51 return reinterpret_cast<T*>(Val);
52 }
Eugene Zelenko1760dc22016-04-05 20:19:49 +000053
Amaury Sechete8ea7d82016-02-04 23:26:19 +000054 static unsigned getHashValue(const T *PtrVal) {
55 return hash_value(PtrVal);
56 }
Eugene Zelenko1760dc22016-04-05 20:19:49 +000057
Amaury Sechete8ea7d82016-02-04 23:26:19 +000058 static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
59 };
60
61 typedef DenseMap<T*, T*, CAPIDenseMapInfo> Map;
62};
63
64typedef CAPIDenseMap<LLVMValueRef>::Map ValueMap;
Amaury Secheta82042e2016-02-09 22:36:41 +000065typedef CAPIDenseMap<LLVMBasicBlockRef>::Map BasicBlockMap;
Amaury Sechete8ea7d82016-02-04 23:26:19 +000066
Amaury Sechetaad93532016-02-10 00:38:50 +000067struct TypeCloner {
68 LLVMModuleRef M;
69 LLVMContextRef Ctx;
70
71 TypeCloner(LLVMModuleRef M): M(M), Ctx(LLVMGetModuleContext(M)) {}
72
Amaury Sechetc679dbd2016-02-14 09:30:42 +000073 LLVMTypeRef Clone(LLVMValueRef Src) {
74 return Clone(LLVMTypeOf(Src));
75 }
76
Amaury Sechetaad93532016-02-10 00:38:50 +000077 LLVMTypeRef Clone(LLVMTypeRef Src) {
78 LLVMTypeKind Kind = LLVMGetTypeKind(Src);
79 switch (Kind) {
80 case LLVMVoidTypeKind:
81 return LLVMVoidTypeInContext(Ctx);
82 case LLVMHalfTypeKind:
83 return LLVMHalfTypeInContext(Ctx);
84 case LLVMFloatTypeKind:
85 return LLVMFloatTypeInContext(Ctx);
86 case LLVMDoubleTypeKind:
87 return LLVMDoubleTypeInContext(Ctx);
88 case LLVMX86_FP80TypeKind:
89 return LLVMX86FP80TypeInContext(Ctx);
90 case LLVMFP128TypeKind:
91 return LLVMFP128TypeInContext(Ctx);
92 case LLVMPPC_FP128TypeKind:
93 return LLVMPPCFP128TypeInContext(Ctx);
94 case LLVMLabelTypeKind:
95 return LLVMLabelTypeInContext(Ctx);
96 case LLVMIntegerTypeKind:
97 return LLVMIntTypeInContext(Ctx, LLVMGetIntTypeWidth(Src));
98 case LLVMFunctionTypeKind: {
99 unsigned ParamCount = LLVMCountParamTypes(Src);
100 LLVMTypeRef* Params = nullptr;
101 if (ParamCount > 0) {
102 Params = (LLVMTypeRef*) malloc(ParamCount * sizeof(LLVMTypeRef));
103 LLVMGetParamTypes(Src, Params);
104 for (unsigned i = 0; i < ParamCount; i++)
105 Params[i] = Clone(Params[i]);
106 }
107
108 LLVMTypeRef FunTy = LLVMFunctionType(Clone(LLVMGetReturnType(Src)),
109 Params, ParamCount,
110 LLVMIsFunctionVarArg(Src));
111 if (ParamCount > 0)
112 free(Params);
113 return FunTy;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000114 }
Amaury Sechetaad93532016-02-10 00:38:50 +0000115 case LLVMStructTypeKind: {
116 LLVMTypeRef S = nullptr;
117 const char *Name = LLVMGetStructName(Src);
118 if (Name) {
119 S = LLVMGetTypeByName(M, Name);
120 if (S)
121 return S;
122 S = LLVMStructCreateNamed(Ctx, Name);
123 if (LLVMIsOpaqueStruct(Src))
124 return S;
125 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000126
Amaury Sechetaad93532016-02-10 00:38:50 +0000127 unsigned EltCount = LLVMCountStructElementTypes(Src);
128 SmallVector<LLVMTypeRef, 8> Elts;
129 for (unsigned i = 0; i < EltCount; i++)
130 Elts.push_back(Clone(LLVMStructGetTypeAtIndex(Src, i)));
131 if (Name)
132 LLVMStructSetBody(S, Elts.data(), EltCount, LLVMIsPackedStruct(Src));
133 else
134 S = LLVMStructTypeInContext(Ctx, Elts.data(), EltCount,
135 LLVMIsPackedStruct(Src));
136 return S;
137 }
138 case LLVMArrayTypeKind:
139 return LLVMArrayType(
140 Clone(LLVMGetElementType(Src)),
141 LLVMGetArrayLength(Src)
142 );
143 case LLVMPointerTypeKind:
144 return LLVMPointerType(
145 Clone(LLVMGetElementType(Src)),
146 LLVMGetPointerAddressSpace(Src)
147 );
148 case LLVMVectorTypeKind:
149 return LLVMVectorType(
150 Clone(LLVMGetElementType(Src)),
151 LLVMGetVectorSize(Src)
152 );
153 case LLVMMetadataTypeKind:
154 break;
155 case LLVMX86_MMXTypeKind:
156 return LLVMX86MMXTypeInContext(Ctx);
157 default:
158 break;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000159 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000160
Amaury Sechetaad93532016-02-10 00:38:50 +0000161 fprintf(stderr, "%d is not a supported typekind\n", Kind);
162 exit(-1);
163 }
164};
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000165
Eugene Zelenko1760dc22016-04-05 20:19:49 +0000166namespace {
167
168ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst) {
Amaury Sechetecda4ea2016-02-14 09:14:30 +0000169 unsigned Count = LLVMCountParams(Src);
Amaury Sechetd01c8612016-02-14 10:06:34 +0000170 if (Count != LLVMCountParams(Dst))
171 report_fatal_error("Parameter count mismatch");
Amaury Sechetecda4ea2016-02-14 09:14:30 +0000172
173 ValueMap VMap;
174 if (Count == 0)
175 return VMap;
176
177 LLVMValueRef SrcFirst = LLVMGetFirstParam(Src);
178 LLVMValueRef DstFirst = LLVMGetFirstParam(Dst);
179 LLVMValueRef SrcLast = LLVMGetLastParam(Src);
180 LLVMValueRef DstLast = LLVMGetLastParam(Dst);
181
182 LLVMValueRef SrcCur = SrcFirst;
183 LLVMValueRef DstCur = DstFirst;
184 LLVMValueRef SrcNext = nullptr;
185 LLVMValueRef DstNext = nullptr;
186 while (true) {
187 const char *Name = LLVMGetValueName(SrcCur);
188 LLVMSetValueName(DstCur, Name);
189
190 VMap[SrcCur] = DstCur;
191
192 Count--;
193 SrcNext = LLVMGetNextParam(SrcCur);
194 DstNext = LLVMGetNextParam(DstCur);
195 if (SrcNext == nullptr && DstNext == nullptr) {
Amaury Sechetd01c8612016-02-14 10:06:34 +0000196 if (SrcCur != SrcLast)
197 report_fatal_error("SrcLast param does not match End");
198 if (DstCur != DstLast)
199 report_fatal_error("DstLast param does not match End");
Amaury Sechetecda4ea2016-02-14 09:14:30 +0000200 break;
201 }
202
Amaury Sechetd01c8612016-02-14 10:06:34 +0000203 if (SrcNext == nullptr)
204 report_fatal_error("SrcNext was unexpectedly null");
205 if (DstNext == nullptr)
206 report_fatal_error("DstNext was unexpectedly null");
Amaury Sechetecda4ea2016-02-14 09:14:30 +0000207
208 LLVMValueRef SrcPrev = LLVMGetPreviousParam(SrcNext);
Amaury Sechetd01c8612016-02-14 10:06:34 +0000209 if (SrcPrev != SrcCur)
210 report_fatal_error("SrcNext.Previous param is not Current");
Amaury Sechetecda4ea2016-02-14 09:14:30 +0000211
212 LLVMValueRef DstPrev = LLVMGetPreviousParam(DstNext);
Amaury Sechetd01c8612016-02-14 10:06:34 +0000213 if (DstPrev != DstCur)
214 report_fatal_error("DstNext.Previous param is not Current");
Amaury Sechetecda4ea2016-02-14 09:14:30 +0000215
216 SrcCur = SrcNext;
217 DstCur = DstNext;
218 }
219
Amaury Sechetd01c8612016-02-14 10:06:34 +0000220 if (Count != 0)
221 report_fatal_error("Parameter count does not match iteration");
Amaury Sechetecda4ea2016-02-14 09:14:30 +0000222
223 return VMap;
224}
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000225
Eugene Zelenko1760dc22016-04-05 20:19:49 +0000226} // end anonymous namespace
227
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000228LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) {
229 if (!LLVMIsAConstant(Cst))
230 report_fatal_error("Expected a constant");
231
232 // Maybe it is a symbol
233 if (LLVMIsAGlobalValue(Cst)) {
234 const char *Name = LLVMGetValueName(Cst);
235
236 // Try function
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000237 if (LLVMIsAFunction(Cst)) {
238 LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
239 if (Dst)
240 return Dst;
241 report_fatal_error("Could not find function");
242 }
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000243
244 // Try global variable
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000245 if (LLVMIsAGlobalVariable(Cst)) {
246 LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name);
247 if (Dst)
248 return Dst;
249 report_fatal_error("Could not find function");
250 }
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000251
252 fprintf(stderr, "Could not find @%s\n", Name);
253 exit(-1);
254 }
255
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000256 // Try integer literal
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000257 if (LLVMIsAConstantInt(Cst))
258 return LLVMConstInt(TypeCloner(M).Clone(Cst),
259 LLVMConstIntGetZExtValue(Cst), false);
260
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000261 // Try zeroinitializer
262 if (LLVMIsAConstantAggregateZero(Cst))
263 return LLVMConstNull(TypeCloner(M).Clone(Cst));
264
265 // Try constant array
266 if (LLVMIsAConstantArray(Cst)) {
267 LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
268 unsigned EltCount = LLVMGetArrayLength(Ty);
269 SmallVector<LLVMValueRef, 8> Elts;
270 for (unsigned i = 0; i < EltCount; i++)
271 Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
272 return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
273 }
274
Amaury Sechetb3256862016-03-13 00:58:25 +0000275 // Try contant data array
276 if (LLVMIsAConstantDataArray(Cst)) {
277 LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
278 unsigned EltCount = LLVMGetArrayLength(Ty);
279 SmallVector<LLVMValueRef, 8> Elts;
280 for (unsigned i = 0; i < EltCount; i++)
281 Elts.push_back(clone_constant(LLVMGetElementAsConstant(Cst, i), M));
282 return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
283 }
284
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000285 // Try constant struct
286 if (LLVMIsAConstantStruct(Cst)) {
287 LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
288 unsigned EltCount = LLVMCountStructElementTypes(Ty);
289 SmallVector<LLVMValueRef, 8> Elts;
290 for (unsigned i = 0; i < EltCount; i++)
291 Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
292 if (LLVMGetStructName(Ty))
293 return LLVMConstNamedStruct(Ty, Elts.data(), EltCount);
294 return LLVMConstStructInContext(LLVMGetModuleContext(M), Elts.data(),
295 EltCount, LLVMIsPackedStruct(Ty));
296 }
297
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000298 // Try undef
299 if (LLVMIsUndef(Cst))
300 return LLVMGetUndef(TypeCloner(M).Clone(Cst));
301
Amaury Sechet40bbe512016-02-17 23:55:59 +0000302 // Try float literal
303 if (LLVMIsAConstantFP(Cst))
304 report_fatal_error("ConstantFP is not supported");
305
Amaury Sechet6b16c232016-02-16 07:33:23 +0000306 // This kind of constant is not supported
307 if (!LLVMIsAConstantExpr(Cst))
308 report_fatal_error("Expected a constant expression");
309
310 // At this point, it must be a constant expression
Amaury Sechet40bbe512016-02-17 23:55:59 +0000311 LLVMOpcode Op = LLVMGetConstOpcode(Cst);
312 switch(Op) {
313 case LLVMBitCast:
314 return LLVMConstBitCast(clone_constant(LLVMGetOperand(Cst, 0), M),
315 TypeCloner(M).Clone(Cst));
316 default:
317 fprintf(stderr, "%d is not a supported opcode\n", Op);
318 exit(-1);
319 }
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000320}
321
Amaury Secheta82042e2016-02-09 22:36:41 +0000322struct FunCloner {
323 LLVMValueRef Fun;
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000324 LLVMModuleRef M;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000325
Amaury Secheta82042e2016-02-09 22:36:41 +0000326 ValueMap VMap;
327 BasicBlockMap BBMap;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000328
Amaury Sechetaad93532016-02-10 00:38:50 +0000329 FunCloner(LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst),
330 M(LLVMGetGlobalParent(Fun)), VMap(clone_params(Src, Dst)) {}
331
332 LLVMTypeRef CloneType(LLVMTypeRef Src) {
333 return TypeCloner(M).Clone(Src);
334 }
335
336 LLVMTypeRef CloneType(LLVMValueRef Src) {
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000337 return TypeCloner(M).Clone(Src);
Amaury Sechetaad93532016-02-10 00:38:50 +0000338 }
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000339
Amaury Secheta82042e2016-02-09 22:36:41 +0000340 // Try to clone everything in the llvm::Value hierarchy.
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000341 LLVMValueRef CloneValue(LLVMValueRef Src) {
Amaury Secheta82042e2016-02-09 22:36:41 +0000342 // First, the value may be constant.
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000343 if (LLVMIsAConstant(Src))
344 return clone_constant(Src, M);
Amaury Secheta82042e2016-02-09 22:36:41 +0000345
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000346 // Function argument should always be in the map already.
Amaury Sechet2f432082016-02-11 21:37:54 +0000347 auto i = VMap.find(Src);
348 if (i != VMap.end())
349 return i->second;
Amaury Secheta82042e2016-02-09 22:36:41 +0000350
Amaury Sechet2f432082016-02-11 21:37:54 +0000351 if (!LLVMIsAInstruction(Src))
352 report_fatal_error("Expected an instruction");
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000353
Amaury Sechet2f432082016-02-11 21:37:54 +0000354 auto Ctx = LLVMGetModuleContext(M);
355 auto Builder = LLVMCreateBuilderInContext(Ctx);
356 auto BB = DeclareBB(LLVMGetInstructionParent(Src));
357 LLVMPositionBuilderAtEnd(Builder, BB);
358 auto Dst = CloneInstruction(Src, Builder);
359 LLVMDisposeBuilder(Builder);
360 return Dst;
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000361 }
362
363 LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
364 const char *Name = LLVMGetValueName(Src);
365 if (!LLVMIsAInstruction(Src))
366 report_fatal_error("Expected an instruction");
367
Amaury Secheta82042e2016-02-09 22:36:41 +0000368 // Check if this is something we already computed.
369 {
370 auto i = VMap.find(Src);
Amaury Sechet2f432082016-02-11 21:37:54 +0000371 if (i != VMap.end()) {
372 // If we have a hit, it means we already generated the instruction
373 // as a dependancy to somethign else. We need to make sure
374 // it is ordered properly.
375 auto I = i->second;
376 LLVMInstructionRemoveFromParent(I);
377 LLVMInsertIntoBuilderWithName(Builder, I, Name);
378 return I;
379 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000380 }
381
382 // We tried everything, it must be an instruction
383 // that hasn't been generated already.
384 LLVMValueRef Dst = nullptr;
385
386 LLVMOpcode Op = LLVMGetInstructionOpcode(Src);
387 switch(Op) {
388 case LLVMRet: {
389 int OpCount = LLVMGetNumOperands(Src);
390 if (OpCount == 0)
391 Dst = LLVMBuildRetVoid(Builder);
392 else
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000393 Dst = LLVMBuildRet(Builder, CloneValue(LLVMGetOperand(Src, 0)));
Amaury Secheta82042e2016-02-09 22:36:41 +0000394 break;
395 }
396 case LLVMBr: {
Amaury Sechete7e62172016-02-09 23:15:02 +0000397 if (!LLVMIsConditional(Src)) {
398 LLVMValueRef SrcOp = LLVMGetOperand(Src, 0);
399 LLVMBasicBlockRef SrcBB = LLVMValueAsBasicBlock(SrcOp);
400 Dst = LLVMBuildBr(Builder, DeclareBB(SrcBB));
401 break;
402 }
403
404 LLVMValueRef Cond = LLVMGetCondition(Src);
405 LLVMValueRef Else = LLVMGetOperand(Src, 1);
406 LLVMBasicBlockRef ElseBB = DeclareBB(LLVMValueAsBasicBlock(Else));
407 LLVMValueRef Then = LLVMGetOperand(Src, 2);
408 LLVMBasicBlockRef ThenBB = DeclareBB(LLVMValueAsBasicBlock(Then));
409 Dst = LLVMBuildCondBr(Builder, Cond, ThenBB, ElseBB);
Amaury Secheta82042e2016-02-09 22:36:41 +0000410 break;
411 }
412 case LLVMSwitch:
413 case LLVMIndirectBr:
Amaury Secheta82042e2016-02-09 22:36:41 +0000414 break;
Amaury Sechete39e8532016-02-18 20:38:32 +0000415 case LLVMInvoke: {
416 SmallVector<LLVMValueRef, 8> Args;
417 int ArgCount = LLVMGetNumArgOperands(Src);
418 for (int i = 0; i < ArgCount; i++)
419 Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
420 LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
421 LLVMBasicBlockRef Then = DeclareBB(LLVMGetNormalDest(Src));
422 LLVMBasicBlockRef Unwind = DeclareBB(LLVMGetUnwindDest(Src));
423 Dst = LLVMBuildInvoke(Builder, Fn, Args.data(), ArgCount,
424 Then, Unwind, Name);
425 break;
426 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000427 case LLVMUnreachable:
428 Dst = LLVMBuildUnreachable(Builder);
429 break;
430 case LLVMAdd: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000431 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
432 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000433 Dst = LLVMBuildAdd(Builder, LHS, RHS, Name);
434 break;
435 }
436 case LLVMSub: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000437 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
438 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000439 Dst = LLVMBuildSub(Builder, LHS, RHS, Name);
440 break;
441 }
442 case LLVMMul: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000443 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
444 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000445 Dst = LLVMBuildMul(Builder, LHS, RHS, Name);
446 break;
447 }
448 case LLVMUDiv: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000449 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
450 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000451 Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name);
452 break;
453 }
454 case LLVMSDiv: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000455 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
456 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000457 Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name);
458 break;
459 }
460 case LLVMURem: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000461 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
462 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000463 Dst = LLVMBuildURem(Builder, LHS, RHS, Name);
464 break;
465 }
466 case LLVMSRem: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000467 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
468 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000469 Dst = LLVMBuildSRem(Builder, LHS, RHS, Name);
470 break;
471 }
472 case LLVMShl: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000473 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
474 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000475 Dst = LLVMBuildShl(Builder, LHS, RHS, Name);
476 break;
477 }
478 case LLVMLShr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000479 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
480 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000481 Dst = LLVMBuildLShr(Builder, LHS, RHS, Name);
482 break;
483 }
484 case LLVMAShr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000485 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
486 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000487 Dst = LLVMBuildAShr(Builder, LHS, RHS, Name);
488 break;
489 }
490 case LLVMAnd: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000491 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
492 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000493 Dst = LLVMBuildAnd(Builder, LHS, RHS, Name);
494 break;
495 }
496 case LLVMOr: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000497 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
498 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000499 Dst = LLVMBuildOr(Builder, LHS, RHS, Name);
500 break;
501 }
502 case LLVMXor: {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000503 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
504 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Secheta82042e2016-02-09 22:36:41 +0000505 Dst = LLVMBuildXor(Builder, LHS, RHS, Name);
506 break;
507 }
508 case LLVMAlloca: {
Amaury Sechetaad93532016-02-10 00:38:50 +0000509 LLVMTypeRef Ty = CloneType(LLVMGetAllocatedType(Src));
Amaury Secheta82042e2016-02-09 22:36:41 +0000510 Dst = LLVMBuildAlloca(Builder, Ty, Name);
511 break;
512 }
Amaury Sechet053ac452016-02-17 22:51:03 +0000513 case LLVMLoad: {
514 LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0));
515 Dst = LLVMBuildLoad(Builder, Ptr, Name);
516 LLVMSetAlignment(Dst, LLVMGetAlignment(Src));
517 break;
518 }
519 case LLVMStore: {
520 LLVMValueRef Val = CloneValue(LLVMGetOperand(Src, 0));
521 LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 1));
522 Dst = LLVMBuildStore(Builder, Val, Ptr);
523 LLVMSetAlignment(Dst, LLVMGetAlignment(Src));
524 break;
525 }
526 case LLVMGetElementPtr: {
527 LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0));
528 SmallVector<LLVMValueRef, 8> Idx;
529 int NumIdx = LLVMGetNumIndices(Src);
530 for (int i = 1; i <= NumIdx; i++)
531 Idx.push_back(CloneValue(LLVMGetOperand(Src, i)));
532 if (LLVMIsInBounds(Src))
533 Dst = LLVMBuildInBoundsGEP(Builder, Ptr, Idx.data(), NumIdx, Name);
534 else
535 Dst = LLVMBuildGEP(Builder, Ptr, Idx.data(), NumIdx, Name);
536 break;
537 }
Mehdi Amini43165d92016-03-19 21:28:28 +0000538 case LLVMAtomicCmpXchg: {
539 LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0));
540 LLVMValueRef Cmp = CloneValue(LLVMGetOperand(Src, 1));
541 LLVMValueRef New = CloneValue(LLVMGetOperand(Src, 2));
542 LLVMAtomicOrdering Succ = LLVMGetCmpXchgSuccessOrdering(Src);
543 LLVMAtomicOrdering Fail = LLVMGetCmpXchgFailureOrdering(Src);
544 LLVMBool SingleThread = LLVMIsAtomicSingleThread(Src);
545
546 Dst = LLVMBuildAtomicCmpXchg(Builder, Ptr, Cmp, New, Succ, Fail,
547 SingleThread);
548 } break;
Amaury Sechet40bbe512016-02-17 23:55:59 +0000549 case LLVMBitCast: {
550 LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 0));
551 Dst = LLVMBuildBitCast(Builder, V, CloneType(Src), Name);
552 break;
553 }
Amaury Sechete7e62172016-02-09 23:15:02 +0000554 case LLVMICmp: {
555 LLVMIntPredicate Pred = LLVMGetICmpPredicate(Src);
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000556 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
557 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Amaury Sechete7e62172016-02-09 23:15:02 +0000558 Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name);
559 break;
560 }
Amaury Sechet2f432082016-02-11 21:37:54 +0000561 case LLVMPHI: {
562 // We need to agressively set things here because of loops.
563 VMap[Src] = Dst = LLVMBuildPhi(Builder, CloneType(Src), Name);
564
565 SmallVector<LLVMValueRef, 8> Values;
566 SmallVector<LLVMBasicBlockRef, 8> Blocks;
567
568 unsigned IncomingCount = LLVMCountIncoming(Src);
569 for (unsigned i = 0; i < IncomingCount; ++i) {
570 Blocks.push_back(DeclareBB(LLVMGetIncomingBlock(Src, i)));
571 Values.push_back(CloneValue(LLVMGetIncomingValue(Src, i)));
572 }
573
574 LLVMAddIncoming(Dst, Values.data(), Blocks.data(), IncomingCount);
575 return Dst;
576 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000577 case LLVMCall: {
Amaury Secheta82042e2016-02-09 22:36:41 +0000578 SmallVector<LLVMValueRef, 8> Args;
Amaury Sechet5c7b3af2016-02-10 00:09:37 +0000579 int ArgCount = LLVMGetNumArgOperands(Src);
Amaury Secheta82042e2016-02-09 22:36:41 +0000580 for (int i = 0; i < ArgCount; i++)
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000581 Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
Amaury Sechet5c7b3af2016-02-10 00:09:37 +0000582 LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
Amaury Secheta82042e2016-02-09 22:36:41 +0000583 Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
Amaury Sechete39e8532016-02-18 20:38:32 +0000584 LLVMSetTailCall(Dst, LLVMIsTailCall(Src));
585 break;
586 }
587 case LLVMResume: {
588 Dst = LLVMBuildResume(Builder, CloneValue(LLVMGetOperand(Src, 0)));
589 break;
590 }
591 case LLVMLandingPad: {
592 // The landing pad API is a bit screwed up for historical reasons.
593 Dst = LLVMBuildLandingPad(Builder, CloneType(Src), nullptr, 0, Name);
594 unsigned NumClauses = LLVMGetNumClauses(Src);
595 for (unsigned i = 0; i < NumClauses; ++i)
596 LLVMAddClause(Dst, CloneValue(LLVMGetClause(Src, i)));
597 LLVMSetCleanup(Dst, LLVMIsCleanup(Src));
Amaury Secheta82042e2016-02-09 22:36:41 +0000598 break;
599 }
Amaury Sechetaad93532016-02-10 00:38:50 +0000600 case LLVMExtractValue: {
601 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
602 if (LLVMGetNumIndices(Src) != 1)
603 report_fatal_error("Expected only one indice");
604 auto I = LLVMGetIndices(Src)[0];
605 Dst = LLVMBuildExtractValue(Builder, Agg, I, Name);
606 break;
607 }
608 case LLVMInsertValue: {
609 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
610 LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1));
611 if (LLVMGetNumIndices(Src) != 1)
612 report_fatal_error("Expected only one indice");
613 auto I = LLVMGetIndices(Src)[0];
614 Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name);
615 break;
616 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000617 default:
618 break;
619 }
620
621 if (Dst == nullptr) {
622 fprintf(stderr, "%d is not a supported opcode\n", Op);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000623 exit(-1);
624 }
625
Amaury Secheta82042e2016-02-09 22:36:41 +0000626 return VMap[Src] = Dst;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000627 }
628
Amaury Secheta82042e2016-02-09 22:36:41 +0000629 LLVMBasicBlockRef DeclareBB(LLVMBasicBlockRef Src) {
630 // Check if this is something we already computed.
631 {
632 auto i = BBMap.find(Src);
633 if (i != BBMap.end()) {
634 return i->second;
635 }
636 }
637
Amaury Secheta82042e2016-02-09 22:36:41 +0000638 LLVMValueRef V = LLVMBasicBlockAsValue(Src);
639 if (!LLVMValueIsBasicBlock(V) || LLVMValueAsBasicBlock(V) != Src)
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000640 report_fatal_error("Basic block is not a basic block");
Amaury Secheta82042e2016-02-09 22:36:41 +0000641
Amaury Sechetd01c8612016-02-14 10:06:34 +0000642 const char *Name = LLVMGetBasicBlockName(Src);
Amaury Secheta82042e2016-02-09 22:36:41 +0000643 const char *VName = LLVMGetValueName(V);
644 if (Name != VName)
645 report_fatal_error("Basic block name mismatch");
646
647 LLVMBasicBlockRef BB = LLVMAppendBasicBlock(Fun, Name);
648 return BBMap[Src] = BB;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000649 }
650
Amaury Secheta82042e2016-02-09 22:36:41 +0000651 LLVMBasicBlockRef CloneBB(LLVMBasicBlockRef Src) {
652 LLVMBasicBlockRef BB = DeclareBB(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000653
Amaury Secheta82042e2016-02-09 22:36:41 +0000654 // Make sure ordering is correct.
655 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Src);
656 if (Prev)
657 LLVMMoveBasicBlockAfter(BB, DeclareBB(Prev));
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000658
Amaury Secheta82042e2016-02-09 22:36:41 +0000659 LLVMValueRef First = LLVMGetFirstInstruction(Src);
660 LLVMValueRef Last = LLVMGetLastInstruction(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000661
Amaury Secheta82042e2016-02-09 22:36:41 +0000662 if (First == nullptr) {
Amaury Sechetd01c8612016-02-14 10:06:34 +0000663 if (Last != nullptr)
664 report_fatal_error("Has no first instruction, but last one");
Amaury Secheta82042e2016-02-09 22:36:41 +0000665 return BB;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000666 }
667
Amaury Sechetaad93532016-02-10 00:38:50 +0000668 auto Ctx = LLVMGetModuleContext(M);
Amaury Secheta82042e2016-02-09 22:36:41 +0000669 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);
670 LLVMPositionBuilderAtEnd(Builder, BB);
671
672 LLVMValueRef Cur = First;
673 LLVMValueRef Next = nullptr;
674 while(true) {
Amaury Sechet1e5d7e22016-02-09 23:41:20 +0000675 CloneInstruction(Cur, Builder);
Amaury Secheta82042e2016-02-09 22:36:41 +0000676 Next = LLVMGetNextInstruction(Cur);
677 if (Next == nullptr) {
Amaury Sechetd01c8612016-02-14 10:06:34 +0000678 if (Cur != Last)
679 report_fatal_error("Final instruction does not match Last");
Amaury Secheta82042e2016-02-09 22:36:41 +0000680 break;
681 }
682
683 LLVMValueRef Prev = LLVMGetPreviousInstruction(Next);
Amaury Sechetd01c8612016-02-14 10:06:34 +0000684 if (Prev != Cur)
685 report_fatal_error("Next.Previous instruction is not Current");
Amaury Secheta82042e2016-02-09 22:36:41 +0000686
687 Cur = Next;
688 }
689
690 LLVMDisposeBuilder(Builder);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000691 return BB;
692 }
693
Amaury Secheta82042e2016-02-09 22:36:41 +0000694 void CloneBBs(LLVMValueRef Src) {
695 unsigned Count = LLVMCountBasicBlocks(Src);
696 if (Count == 0)
697 return;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000698
Amaury Secheta82042e2016-02-09 22:36:41 +0000699 LLVMBasicBlockRef First = LLVMGetFirstBasicBlock(Src);
700 LLVMBasicBlockRef Last = LLVMGetLastBasicBlock(Src);
701
702 LLVMBasicBlockRef Cur = First;
703 LLVMBasicBlockRef Next = nullptr;
704 while(true) {
705 CloneBB(Cur);
706 Count--;
707 Next = LLVMGetNextBasicBlock(Cur);
708 if (Next == nullptr) {
Amaury Sechetd01c8612016-02-14 10:06:34 +0000709 if (Cur != Last)
710 report_fatal_error("Final basic block does not match Last");
Amaury Secheta82042e2016-02-09 22:36:41 +0000711 break;
712 }
713
714 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Next);
Amaury Sechetd01c8612016-02-14 10:06:34 +0000715 if (Prev != Cur)
716 report_fatal_error("Next.Previous basic bloc is not Current");
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000717
Amaury Secheta82042e2016-02-09 22:36:41 +0000718 Cur = Next;
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000719 }
720
Amaury Sechetd01c8612016-02-14 10:06:34 +0000721 if (Count != 0)
722 report_fatal_error("Basic block count does not match iterration");
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000723 }
Amaury Secheta82042e2016-02-09 22:36:41 +0000724};
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000725
Eugene Zelenko1760dc22016-04-05 20:19:49 +0000726namespace {
727
728void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000729 LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
730 LLVMValueRef End = LLVMGetLastGlobal(Src);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000731
732 LLVMValueRef Cur = Begin;
733 LLVMValueRef Next = nullptr;
Amaury Sechet58946a92016-02-17 22:30:05 +0000734 if (!Begin) {
735 if (End != nullptr)
736 report_fatal_error("Range has an end but no begining");
737 goto FunDecl;
738 }
739
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000740 while (true) {
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000741 const char *Name = LLVMGetValueName(Cur);
742 if (LLVMGetNamedGlobal(M, Name))
743 report_fatal_error("GlobalVariable already cloned");
744 LLVMAddGlobal(M, LLVMGetElementType(TypeCloner(M).Clone(Cur)), Name);
745
746 Next = LLVMGetNextGlobal(Cur);
747 if (Next == nullptr) {
748 if (Cur != End)
749 report_fatal_error("");
750 break;
751 }
752
753 LLVMValueRef Prev = LLVMGetPreviousGlobal(Next);
754 if (Prev != Cur)
755 report_fatal_error("Next.Previous global is not Current");
756
757 Cur = Next;
758 }
759
Amaury Sechet58946a92016-02-17 22:30:05 +0000760FunDecl:
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000761 Begin = LLVMGetFirstFunction(Src);
762 End = LLVMGetLastFunction(Src);
763 if (!Begin) {
764 if (End != nullptr)
765 report_fatal_error("Range has an end but no begining");
766 return;
767 }
768
769 Cur = Begin;
770 Next = nullptr;
771 while (true) {
772 const char *Name = LLVMGetValueName(Cur);
773 if (LLVMGetNamedFunction(M, Name))
774 report_fatal_error("Function already cloned");
775 LLVMAddFunction(M, Name, LLVMGetElementType(TypeCloner(M).Clone(Cur)));
776
Amaury Sechetf64e8342016-02-16 07:08:49 +0000777 Next = LLVMGetNextFunction(Cur);
778 if (Next == nullptr) {
779 if (Cur != End)
780 report_fatal_error("Last function does not match End");
781 break;
782 }
783
784 LLVMValueRef Prev = LLVMGetPreviousFunction(Next);
785 if (Prev != Cur)
786 report_fatal_error("Next.Previous function is not Current");
787
788 Cur = Next;
789 }
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000790}
Amaury Sechetf64e8342016-02-16 07:08:49 +0000791
Eugene Zelenko1760dc22016-04-05 20:19:49 +0000792void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000793 LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
794 LLVMValueRef End = LLVMGetLastGlobal(Src);
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000795
796 LLVMValueRef Cur = Begin;
797 LLVMValueRef Next = nullptr;
Amaury Sechet58946a92016-02-17 22:30:05 +0000798 if (!Begin) {
799 if (End != nullptr)
800 report_fatal_error("Range has an end but no begining");
801 goto FunClone;
802 }
803
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000804 while (true) {
805 const char *Name = LLVMGetValueName(Cur);
806 LLVMValueRef G = LLVMGetNamedGlobal(M, Name);
807 if (!G)
808 report_fatal_error("GlobalVariable must have been declared already");
809
810 if (auto I = LLVMGetInitializer(Cur))
811 LLVMSetInitializer(G, clone_constant(I, M));
812
813 LLVMSetGlobalConstant(G, LLVMIsGlobalConstant(Cur));
814 LLVMSetThreadLocal(G, LLVMIsThreadLocal(Cur));
815 LLVMSetExternallyInitialized(G, LLVMIsExternallyInitialized(Cur));
816 LLVMSetLinkage(G, LLVMGetLinkage(Cur));
817 LLVMSetSection(G, LLVMGetSection(Cur));
818 LLVMSetVisibility(G, LLVMGetVisibility(Cur));
819 LLVMSetUnnamedAddr(G, LLVMHasUnnamedAddr(Cur));
820 LLVMSetAlignment(G, LLVMGetAlignment(Cur));
821
822 Next = LLVMGetNextGlobal(Cur);
823 if (Next == nullptr) {
824 if (Cur != End)
825 report_fatal_error("");
826 break;
827 }
828
829 LLVMValueRef Prev = LLVMGetPreviousGlobal(Next);
830 if (Prev != Cur)
831 report_fatal_error("Next.Previous global is not Current");
832
833 Cur = Next;
834 }
835
Amaury Sechet58946a92016-02-17 22:30:05 +0000836FunClone:
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000837 Begin = LLVMGetFirstFunction(Src);
838 End = LLVMGetLastFunction(Src);
839 if (!Begin) {
840 if (End != nullptr)
841 report_fatal_error("Range has an end but no begining");
842 return;
843 }
844
Amaury Sechetf64e8342016-02-16 07:08:49 +0000845 Cur = Begin;
846 Next = nullptr;
847 while (true) {
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000848 const char *Name = LLVMGetValueName(Cur);
849 LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
850 if (!Fun)
851 report_fatal_error("Function must have been declared already");
Amaury Sechete39e8532016-02-18 20:38:32 +0000852
853 if (LLVMHasPersonalityFn(Cur)) {
854 const char *FName = LLVMGetValueName(LLVMGetPersonalityFn(Cur));
855 LLVMValueRef P = LLVMGetNamedFunction(M, FName);
856 if (!P)
857 report_fatal_error("Could not find personality function");
858 LLVMSetPersonalityFn(Fun, P);
859 }
860
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000861 FunCloner FC(Cur, Fun);
862 FC.CloneBBs(Cur);
863
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000864 Next = LLVMGetNextFunction(Cur);
865 if (Next == nullptr) {
Amaury Sechetd01c8612016-02-14 10:06:34 +0000866 if (Cur != End)
867 report_fatal_error("Last function does not match End");
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000868 break;
869 }
870
871 LLVMValueRef Prev = LLVMGetPreviousFunction(Next);
Amaury Sechetd01c8612016-02-14 10:06:34 +0000872 if (Prev != Cur)
873 report_fatal_error("Next.Previous function is not Current");
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000874
875 Cur = Next;
876 }
877}
878
Eugene Zelenko1760dc22016-04-05 20:19:49 +0000879} // end anonymous namespace
880
Benjamin Kramer9a3bd232016-02-05 13:31:14 +0000881int llvm_echo(void) {
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000882 LLVMEnablePrettyStackTrace();
883
Benjamin Kramer9a3bd232016-02-05 13:31:14 +0000884 LLVMModuleRef Src = llvm_load_module(false, true);
Peter Zotov0a2fa0a2016-04-05 13:56:59 +0000885 size_t Len;
886 const char *ModuleName = LLVMGetModuleIdentifier(Src, &Len);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000887 LLVMContextRef Ctx = LLVMContextCreate();
Peter Zotov0a2fa0a2016-04-05 13:56:59 +0000888 LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleName, Ctx);
889
890 // This whole switcharound is done because the C API has no way to
891 // set the source_filename
892 LLVMSetModuleIdentifier(M, "", 0);
893 LLVMGetModuleIdentifier(M, &Len);
894 if (Len != 0)
895 report_fatal_error("LLVM{Set,Get}ModuleIdentifier failed");
896 LLVMSetModuleIdentifier(M, ModuleName, strlen(ModuleName));
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000897
Amaury Sechet55909672016-02-16 05:11:24 +0000898 LLVMSetTarget(M, LLVMGetTarget(Src));
899 LLVMSetModuleDataLayout(M, LLVMGetModuleDataLayout(Src));
900 if (strcmp(LLVMGetDataLayoutStr(M), LLVMGetDataLayoutStr(Src)))
901 report_fatal_error("Inconsistent DataLayout string representation");
902
Amaury Sechete8ba2bf2016-02-17 22:13:33 +0000903 declare_symbols(Src, M);
904 clone_symbols(Src, M);
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000905 char *Str = LLVMPrintModuleToString(M);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000906 fputs(Str, stdout);
907
908 LLVMDisposeMessage(Str);
Amaury Sechetc679dbd2016-02-14 09:30:42 +0000909 LLVMDisposeModule(M);
Amaury Sechete8ea7d82016-02-04 23:26:19 +0000910 LLVMContextDispose(Ctx);
911
912 return 0;
913}