1 //===-- 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 command 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-c/Target.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/Support/ErrorHandling.h"
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 using namespace llvm;
27 
28 // Provide DenseMapInfo for C API opaque types.
29 template<typename T>
30 struct CAPIDenseMap {};
31 
32 // The default DenseMapInfo require to know about pointer alignement.
33 // Because the C API uses opaques pointer types, their alignement is unknown.
34 // As a result, we need to roll out our own implementation.
35 template<typename T>
36 struct CAPIDenseMap<T*> {
37   struct CAPIDenseMapInfo {
getEmptyKeyCAPIDenseMap::CAPIDenseMapInfo38     static inline T* getEmptyKey() {
39       uintptr_t Val = static_cast<uintptr_t>(-1);
40       return reinterpret_cast<T*>(Val);
41     }
getTombstoneKeyCAPIDenseMap::CAPIDenseMapInfo42     static inline T* getTombstoneKey() {
43       uintptr_t Val = static_cast<uintptr_t>(-2);
44       return reinterpret_cast<T*>(Val);
45     }
getHashValueCAPIDenseMap::CAPIDenseMapInfo46     static unsigned getHashValue(const T *PtrVal) {
47       return hash_value(PtrVal);
48     }
isEqualCAPIDenseMap::CAPIDenseMapInfo49     static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
50   };
51 
52   typedef DenseMap<T*, T*, CAPIDenseMapInfo> Map;
53 };
54 
55 typedef CAPIDenseMap<LLVMValueRef>::Map ValueMap;
56 typedef CAPIDenseMap<LLVMBasicBlockRef>::Map BasicBlockMap;
57 
58 struct TypeCloner {
59   LLVMModuleRef M;
60   LLVMContextRef Ctx;
61 
TypeClonerTypeCloner62   TypeCloner(LLVMModuleRef M): M(M), Ctx(LLVMGetModuleContext(M)) {}
63 
CloneTypeCloner64   LLVMTypeRef Clone(LLVMValueRef Src) {
65     return Clone(LLVMTypeOf(Src));
66   }
67 
CloneTypeCloner68   LLVMTypeRef Clone(LLVMTypeRef Src) {
69     LLVMTypeKind Kind = LLVMGetTypeKind(Src);
70     switch (Kind) {
71       case LLVMVoidTypeKind:
72         return LLVMVoidTypeInContext(Ctx);
73       case LLVMHalfTypeKind:
74         return LLVMHalfTypeInContext(Ctx);
75       case LLVMFloatTypeKind:
76         return LLVMFloatTypeInContext(Ctx);
77       case LLVMDoubleTypeKind:
78         return LLVMDoubleTypeInContext(Ctx);
79       case LLVMX86_FP80TypeKind:
80         return LLVMX86FP80TypeInContext(Ctx);
81       case LLVMFP128TypeKind:
82         return LLVMFP128TypeInContext(Ctx);
83       case LLVMPPC_FP128TypeKind:
84         return LLVMPPCFP128TypeInContext(Ctx);
85       case LLVMLabelTypeKind:
86         return LLVMLabelTypeInContext(Ctx);
87       case LLVMIntegerTypeKind:
88         return LLVMIntTypeInContext(Ctx, LLVMGetIntTypeWidth(Src));
89       case LLVMFunctionTypeKind: {
90         unsigned ParamCount = LLVMCountParamTypes(Src);
91         LLVMTypeRef* Params = nullptr;
92         if (ParamCount > 0) {
93           Params = (LLVMTypeRef*) malloc(ParamCount * sizeof(LLVMTypeRef));
94           LLVMGetParamTypes(Src, Params);
95           for (unsigned i = 0; i < ParamCount; i++)
96             Params[i] = Clone(Params[i]);
97         }
98 
99         LLVMTypeRef FunTy = LLVMFunctionType(Clone(LLVMGetReturnType(Src)),
100                                              Params, ParamCount,
101                                              LLVMIsFunctionVarArg(Src));
102         if (ParamCount > 0)
103           free(Params);
104         return FunTy;
105       }
106       case LLVMStructTypeKind: {
107         LLVMTypeRef S = nullptr;
108         const char *Name = LLVMGetStructName(Src);
109         if (Name) {
110           S = LLVMGetTypeByName(M, Name);
111           if (S)
112             return S;
113           S = LLVMStructCreateNamed(Ctx, Name);
114           if (LLVMIsOpaqueStruct(Src))
115             return S;
116         }
117 
118         unsigned EltCount = LLVMCountStructElementTypes(Src);
119         SmallVector<LLVMTypeRef, 8> Elts;
120         for (unsigned i = 0; i < EltCount; i++)
121           Elts.push_back(Clone(LLVMStructGetTypeAtIndex(Src, i)));
122         if (Name)
123           LLVMStructSetBody(S, Elts.data(), EltCount, LLVMIsPackedStruct(Src));
124         else
125           S = LLVMStructTypeInContext(Ctx, Elts.data(), EltCount,
126                                       LLVMIsPackedStruct(Src));
127         return S;
128       }
129       case LLVMArrayTypeKind:
130         return LLVMArrayType(
131           Clone(LLVMGetElementType(Src)),
132           LLVMGetArrayLength(Src)
133         );
134       case LLVMPointerTypeKind:
135         return LLVMPointerType(
136           Clone(LLVMGetElementType(Src)),
137           LLVMGetPointerAddressSpace(Src)
138         );
139       case LLVMVectorTypeKind:
140         return LLVMVectorType(
141           Clone(LLVMGetElementType(Src)),
142           LLVMGetVectorSize(Src)
143         );
144       case LLVMMetadataTypeKind:
145         break;
146       case LLVMX86_MMXTypeKind:
147         return LLVMX86MMXTypeInContext(Ctx);
148       default:
149         break;
150     }
151 
152     fprintf(stderr, "%d is not a supported typekind\n", Kind);
153     exit(-1);
154   }
155 };
156 
clone_params(LLVMValueRef Src,LLVMValueRef Dst)157 static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst) {
158   unsigned Count = LLVMCountParams(Src);
159   if (Count != LLVMCountParams(Dst))
160     report_fatal_error("Parameter count mismatch");
161 
162   ValueMap VMap;
163   if (Count == 0)
164     return VMap;
165 
166   LLVMValueRef SrcFirst = LLVMGetFirstParam(Src);
167   LLVMValueRef DstFirst = LLVMGetFirstParam(Dst);
168   LLVMValueRef SrcLast = LLVMGetLastParam(Src);
169   LLVMValueRef DstLast = LLVMGetLastParam(Dst);
170 
171   LLVMValueRef SrcCur = SrcFirst;
172   LLVMValueRef DstCur = DstFirst;
173   LLVMValueRef SrcNext = nullptr;
174   LLVMValueRef DstNext = nullptr;
175   while (true) {
176     const char *Name = LLVMGetValueName(SrcCur);
177     LLVMSetValueName(DstCur, Name);
178 
179     VMap[SrcCur] = DstCur;
180 
181     Count--;
182     SrcNext = LLVMGetNextParam(SrcCur);
183     DstNext = LLVMGetNextParam(DstCur);
184     if (SrcNext == nullptr && DstNext == nullptr) {
185       if (SrcCur != SrcLast)
186         report_fatal_error("SrcLast param does not match End");
187       if (DstCur != DstLast)
188         report_fatal_error("DstLast param does not match End");
189       break;
190     }
191 
192     if (SrcNext == nullptr)
193       report_fatal_error("SrcNext was unexpectedly null");
194     if (DstNext == nullptr)
195       report_fatal_error("DstNext was unexpectedly null");
196 
197     LLVMValueRef SrcPrev = LLVMGetPreviousParam(SrcNext);
198     if (SrcPrev != SrcCur)
199       report_fatal_error("SrcNext.Previous param is not Current");
200 
201     LLVMValueRef DstPrev = LLVMGetPreviousParam(DstNext);
202     if (DstPrev != DstCur)
203       report_fatal_error("DstNext.Previous param is not Current");
204 
205     SrcCur = SrcNext;
206     DstCur = DstNext;
207   }
208 
209   if (Count != 0)
210     report_fatal_error("Parameter count does not match iteration");
211 
212   return VMap;
213 }
214 
check_value_kind(LLVMValueRef V,LLVMValueKind K)215 static void check_value_kind(LLVMValueRef V, LLVMValueKind K) {
216   if (LLVMGetValueKind(V) != K)
217     report_fatal_error("LLVMGetValueKind returned incorrect type");
218 }
219 
220 static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M);
221 
clone_constant(LLVMValueRef Cst,LLVMModuleRef M)222 static LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) {
223   LLVMValueRef Ret = clone_constant_impl(Cst, M);
224   check_value_kind(Ret, LLVMGetValueKind(Cst));
225   return Ret;
226 }
227 
clone_constant_impl(LLVMValueRef Cst,LLVMModuleRef M)228 static LLVMValueRef clone_constant_impl(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
237     if (LLVMIsAFunction(Cst)) {
238       check_value_kind(Cst, LLVMFunctionValueKind);
239       LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
240       if (Dst)
241         return Dst;
242       report_fatal_error("Could not find function");
243     }
244 
245     // Try global variable
246     if (LLVMIsAGlobalVariable(Cst)) {
247       check_value_kind(Cst, LLVMGlobalVariableValueKind);
248       LLVMValueRef Dst  = LLVMGetNamedGlobal(M, Name);
249       if (Dst)
250         return Dst;
251       report_fatal_error("Could not find function");
252     }
253 
254     fprintf(stderr, "Could not find @%s\n", Name);
255     exit(-1);
256   }
257 
258   // Try integer literal
259   if (LLVMIsAConstantInt(Cst)) {
260     check_value_kind(Cst, LLVMConstantIntValueKind);
261     return LLVMConstInt(TypeCloner(M).Clone(Cst),
262                         LLVMConstIntGetZExtValue(Cst), false);
263   }
264 
265   // Try zeroinitializer
266   if (LLVMIsAConstantAggregateZero(Cst)) {
267     check_value_kind(Cst, LLVMConstantAggregateZeroValueKind);
268     return LLVMConstNull(TypeCloner(M).Clone(Cst));
269   }
270 
271   // Try constant array
272   if (LLVMIsAConstantArray(Cst)) {
273     check_value_kind(Cst, LLVMConstantArrayValueKind);
274     LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
275     unsigned EltCount = LLVMGetArrayLength(Ty);
276     SmallVector<LLVMValueRef, 8> Elts;
277     for (unsigned i = 0; i < EltCount; i++)
278       Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
279     return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
280   }
281 
282   // Try contant data array
283   if (LLVMIsAConstantDataArray(Cst)) {
284     check_value_kind(Cst, LLVMConstantDataArrayValueKind);
285     LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
286     unsigned EltCount = LLVMGetArrayLength(Ty);
287     SmallVector<LLVMValueRef, 8> Elts;
288     for (unsigned i = 0; i < EltCount; i++)
289       Elts.push_back(clone_constant(LLVMGetElementAsConstant(Cst, i), M));
290     return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
291   }
292 
293   // Try constant struct
294   if (LLVMIsAConstantStruct(Cst)) {
295     check_value_kind(Cst, LLVMConstantStructValueKind);
296     LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
297     unsigned EltCount = LLVMCountStructElementTypes(Ty);
298     SmallVector<LLVMValueRef, 8> Elts;
299     for (unsigned i = 0; i < EltCount; i++)
300       Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
301     if (LLVMGetStructName(Ty))
302       return LLVMConstNamedStruct(Ty, Elts.data(), EltCount);
303     return LLVMConstStructInContext(LLVMGetModuleContext(M), Elts.data(),
304                                     EltCount, LLVMIsPackedStruct(Ty));
305   }
306 
307   // Try undef
308   if (LLVMIsUndef(Cst)) {
309     check_value_kind(Cst, LLVMUndefValueValueKind);
310     return LLVMGetUndef(TypeCloner(M).Clone(Cst));
311   }
312 
313   // Try float literal
314   if (LLVMIsAConstantFP(Cst)) {
315     check_value_kind(Cst, LLVMConstantFPValueKind);
316     report_fatal_error("ConstantFP is not supported");
317   }
318 
319   // This kind of constant is not supported
320   if (!LLVMIsAConstantExpr(Cst))
321     report_fatal_error("Expected a constant expression");
322 
323   // At this point, it must be a constant expression
324   check_value_kind(Cst, LLVMConstantExprValueKind);
325 
326   LLVMOpcode Op = LLVMGetConstOpcode(Cst);
327   switch(Op) {
328     case LLVMBitCast:
329       return LLVMConstBitCast(clone_constant(LLVMGetOperand(Cst, 0), M),
330                               TypeCloner(M).Clone(Cst));
331     default:
332       fprintf(stderr, "%d is not a supported opcode\n", Op);
333       exit(-1);
334   }
335 }
336 
337 struct FunCloner {
338   LLVMValueRef Fun;
339   LLVMModuleRef M;
340 
341   ValueMap VMap;
342   BasicBlockMap BBMap;
343 
FunClonerFunCloner344   FunCloner(LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst),
345     M(LLVMGetGlobalParent(Fun)), VMap(clone_params(Src, Dst)) {}
346 
CloneTypeFunCloner347   LLVMTypeRef CloneType(LLVMTypeRef Src) {
348     return TypeCloner(M).Clone(Src);
349   }
350 
CloneTypeFunCloner351   LLVMTypeRef CloneType(LLVMValueRef Src) {
352     return TypeCloner(M).Clone(Src);
353   }
354 
355   // Try to clone everything in the llvm::Value hierarchy.
CloneValueFunCloner356   LLVMValueRef CloneValue(LLVMValueRef Src) {
357     // First, the value may be constant.
358     if (LLVMIsAConstant(Src))
359       return clone_constant(Src, M);
360 
361     // Function argument should always be in the map already.
362     auto i = VMap.find(Src);
363     if (i != VMap.end())
364       return i->second;
365 
366     if (!LLVMIsAInstruction(Src))
367       report_fatal_error("Expected an instruction");
368 
369     auto Ctx = LLVMGetModuleContext(M);
370     auto Builder = LLVMCreateBuilderInContext(Ctx);
371     auto BB = DeclareBB(LLVMGetInstructionParent(Src));
372     LLVMPositionBuilderAtEnd(Builder, BB);
373     auto Dst = CloneInstruction(Src, Builder);
374     LLVMDisposeBuilder(Builder);
375     return Dst;
376   }
377 
CloneAttrsFunCloner378   void CloneAttrs(LLVMValueRef Src, LLVMValueRef Dst) {
379     auto Ctx = LLVMGetModuleContext(M);
380     int ArgCount = LLVMGetNumArgOperands(Src);
381     for (int i = LLVMAttributeReturnIndex; i <= ArgCount; i++) {
382       for (unsigned k = 0, e = LLVMGetLastEnumAttributeKind(); k < e; ++k) {
383         if (auto SrcA = LLVMGetCallSiteEnumAttribute(Src, i, k)) {
384           auto Val = LLVMGetEnumAttributeValue(SrcA);
385           auto A = LLVMCreateEnumAttribute(Ctx, k, Val);
386           LLVMAddCallSiteAttribute(Dst, i, A);
387         }
388       }
389     }
390   }
391 
CloneInstructionFunCloner392   LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
393     check_value_kind(Src, LLVMInstructionValueKind);
394     if (!LLVMIsAInstruction(Src))
395       report_fatal_error("Expected an instruction");
396 
397     const char *Name = LLVMGetValueName(Src);
398 
399     // Check if this is something we already computed.
400     {
401       auto i = VMap.find(Src);
402       if (i != VMap.end()) {
403         // If we have a hit, it means we already generated the instruction
404         // as a dependancy to somethign else. We need to make sure
405         // it is ordered properly.
406         auto I = i->second;
407         LLVMInstructionRemoveFromParent(I);
408         LLVMInsertIntoBuilderWithName(Builder, I, Name);
409         return I;
410       }
411     }
412 
413     // We tried everything, it must be an instruction
414     // that hasn't been generated already.
415     LLVMValueRef Dst = nullptr;
416 
417     LLVMOpcode Op = LLVMGetInstructionOpcode(Src);
418     switch(Op) {
419       case LLVMRet: {
420         int OpCount = LLVMGetNumOperands(Src);
421         if (OpCount == 0)
422           Dst = LLVMBuildRetVoid(Builder);
423         else
424           Dst = LLVMBuildRet(Builder, CloneValue(LLVMGetOperand(Src, 0)));
425         break;
426       }
427       case LLVMBr: {
428         if (!LLVMIsConditional(Src)) {
429           LLVMValueRef SrcOp = LLVMGetOperand(Src, 0);
430           LLVMBasicBlockRef SrcBB = LLVMValueAsBasicBlock(SrcOp);
431           Dst = LLVMBuildBr(Builder, DeclareBB(SrcBB));
432           break;
433         }
434 
435         LLVMValueRef Cond = LLVMGetCondition(Src);
436         LLVMValueRef Else = LLVMGetOperand(Src, 1);
437         LLVMBasicBlockRef ElseBB = DeclareBB(LLVMValueAsBasicBlock(Else));
438         LLVMValueRef Then = LLVMGetOperand(Src, 2);
439         LLVMBasicBlockRef ThenBB = DeclareBB(LLVMValueAsBasicBlock(Then));
440         Dst = LLVMBuildCondBr(Builder, Cond, ThenBB, ElseBB);
441         break;
442       }
443       case LLVMSwitch:
444       case LLVMIndirectBr:
445         break;
446       case LLVMInvoke: {
447         SmallVector<LLVMValueRef, 8> Args;
448         int ArgCount = LLVMGetNumArgOperands(Src);
449         for (int i = 0; i < ArgCount; i++)
450           Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
451         LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
452         LLVMBasicBlockRef Then = DeclareBB(LLVMGetNormalDest(Src));
453         LLVMBasicBlockRef Unwind = DeclareBB(LLVMGetUnwindDest(Src));
454         Dst = LLVMBuildInvoke(Builder, Fn, Args.data(), ArgCount,
455                               Then, Unwind, Name);
456         CloneAttrs(Src, Dst);
457         break;
458       }
459       case LLVMUnreachable:
460         Dst = LLVMBuildUnreachable(Builder);
461         break;
462       case LLVMAdd: {
463         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
464         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
465         Dst = LLVMBuildAdd(Builder, LHS, RHS, Name);
466         break;
467       }
468       case LLVMSub: {
469         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
470         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
471         Dst = LLVMBuildSub(Builder, LHS, RHS, Name);
472         break;
473       }
474       case LLVMMul: {
475         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
476         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
477         Dst = LLVMBuildMul(Builder, LHS, RHS, Name);
478         break;
479       }
480       case LLVMUDiv: {
481         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
482         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
483         Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name);
484         break;
485       }
486       case LLVMSDiv: {
487         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
488         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
489         Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name);
490         break;
491       }
492       case LLVMURem: {
493         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
494         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
495         Dst = LLVMBuildURem(Builder, LHS, RHS, Name);
496         break;
497       }
498       case LLVMSRem: {
499         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
500         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
501         Dst = LLVMBuildSRem(Builder, LHS, RHS, Name);
502         break;
503       }
504       case LLVMShl: {
505         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
506         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
507         Dst = LLVMBuildShl(Builder, LHS, RHS, Name);
508         break;
509       }
510       case LLVMLShr: {
511         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
512         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
513         Dst = LLVMBuildLShr(Builder, LHS, RHS, Name);
514         break;
515       }
516       case LLVMAShr: {
517         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
518         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
519         Dst = LLVMBuildAShr(Builder, LHS, RHS, Name);
520         break;
521       }
522       case LLVMAnd: {
523         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
524         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
525         Dst = LLVMBuildAnd(Builder, LHS, RHS, Name);
526         break;
527       }
528       case LLVMOr: {
529         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
530         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
531         Dst = LLVMBuildOr(Builder, LHS, RHS, Name);
532         break;
533       }
534       case LLVMXor: {
535         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
536         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
537         Dst = LLVMBuildXor(Builder, LHS, RHS, Name);
538         break;
539       }
540       case LLVMAlloca: {
541         LLVMTypeRef Ty = CloneType(LLVMGetAllocatedType(Src));
542         Dst = LLVMBuildAlloca(Builder, Ty, Name);
543         break;
544       }
545       case LLVMLoad: {
546         LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0));
547         Dst = LLVMBuildLoad(Builder, Ptr, Name);
548         LLVMSetAlignment(Dst, LLVMGetAlignment(Src));
549         break;
550       }
551       case LLVMStore: {
552         LLVMValueRef Val = CloneValue(LLVMGetOperand(Src, 0));
553         LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 1));
554         Dst = LLVMBuildStore(Builder, Val, Ptr);
555         LLVMSetAlignment(Dst, LLVMGetAlignment(Src));
556         break;
557       }
558       case LLVMGetElementPtr: {
559         LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0));
560         SmallVector<LLVMValueRef, 8> Idx;
561         int NumIdx = LLVMGetNumIndices(Src);
562         for (int i = 1; i <= NumIdx; i++)
563           Idx.push_back(CloneValue(LLVMGetOperand(Src, i)));
564         if (LLVMIsInBounds(Src))
565           Dst = LLVMBuildInBoundsGEP(Builder, Ptr, Idx.data(), NumIdx, Name);
566         else
567           Dst = LLVMBuildGEP(Builder, Ptr, Idx.data(), NumIdx, Name);
568         break;
569       }
570       case LLVMAtomicCmpXchg: {
571         LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0));
572         LLVMValueRef Cmp = CloneValue(LLVMGetOperand(Src, 1));
573         LLVMValueRef New = CloneValue(LLVMGetOperand(Src, 2));
574         LLVMAtomicOrdering Succ = LLVMGetCmpXchgSuccessOrdering(Src);
575         LLVMAtomicOrdering Fail = LLVMGetCmpXchgFailureOrdering(Src);
576         LLVMBool SingleThread = LLVMIsAtomicSingleThread(Src);
577 
578         Dst = LLVMBuildAtomicCmpXchg(Builder, Ptr, Cmp, New, Succ, Fail,
579                                      SingleThread);
580       } break;
581       case LLVMBitCast: {
582         LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 0));
583         Dst = LLVMBuildBitCast(Builder, V, CloneType(Src), Name);
584         break;
585       }
586       case LLVMICmp: {
587         LLVMIntPredicate Pred = LLVMGetICmpPredicate(Src);
588         LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
589         LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
590         Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name);
591         break;
592       }
593       case LLVMPHI: {
594         // We need to agressively set things here because of loops.
595         VMap[Src] = Dst = LLVMBuildPhi(Builder, CloneType(Src), Name);
596 
597         SmallVector<LLVMValueRef, 8> Values;
598         SmallVector<LLVMBasicBlockRef, 8> Blocks;
599 
600         unsigned IncomingCount = LLVMCountIncoming(Src);
601         for (unsigned i = 0; i < IncomingCount; ++i) {
602           Blocks.push_back(DeclareBB(LLVMGetIncomingBlock(Src, i)));
603           Values.push_back(CloneValue(LLVMGetIncomingValue(Src, i)));
604         }
605 
606         LLVMAddIncoming(Dst, Values.data(), Blocks.data(), IncomingCount);
607         return Dst;
608       }
609       case LLVMCall: {
610         SmallVector<LLVMValueRef, 8> Args;
611         int ArgCount = LLVMGetNumArgOperands(Src);
612         for (int i = 0; i < ArgCount; i++)
613           Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
614         LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
615         Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
616         LLVMSetTailCall(Dst, LLVMIsTailCall(Src));
617         CloneAttrs(Src, Dst);
618         break;
619       }
620       case LLVMResume: {
621         Dst = LLVMBuildResume(Builder, CloneValue(LLVMGetOperand(Src, 0)));
622         break;
623       }
624       case LLVMLandingPad: {
625         // The landing pad API is a bit screwed up for historical reasons.
626         Dst = LLVMBuildLandingPad(Builder, CloneType(Src), nullptr, 0, Name);
627         unsigned NumClauses = LLVMGetNumClauses(Src);
628         for (unsigned i = 0; i < NumClauses; ++i)
629           LLVMAddClause(Dst, CloneValue(LLVMGetClause(Src, i)));
630         LLVMSetCleanup(Dst, LLVMIsCleanup(Src));
631         break;
632       }
633       case LLVMExtractValue: {
634         LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
635         if (LLVMGetNumIndices(Src) != 1)
636           report_fatal_error("Expected only one indice");
637         auto I = LLVMGetIndices(Src)[0];
638         Dst = LLVMBuildExtractValue(Builder, Agg, I, Name);
639         break;
640       }
641       case LLVMInsertValue: {
642         LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
643         LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1));
644         if (LLVMGetNumIndices(Src) != 1)
645           report_fatal_error("Expected only one indice");
646         auto I = LLVMGetIndices(Src)[0];
647         Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name);
648         break;
649       }
650       default:
651         break;
652     }
653 
654     if (Dst == nullptr) {
655       fprintf(stderr, "%d is not a supported opcode\n", Op);
656       exit(-1);
657     }
658 
659     check_value_kind(Dst, LLVMInstructionValueKind);
660     return VMap[Src] = Dst;
661   }
662 
DeclareBBFunCloner663   LLVMBasicBlockRef DeclareBB(LLVMBasicBlockRef Src) {
664     // Check if this is something we already computed.
665     {
666       auto i = BBMap.find(Src);
667       if (i != BBMap.end()) {
668         return i->second;
669       }
670     }
671 
672     LLVMValueRef V = LLVMBasicBlockAsValue(Src);
673     if (!LLVMValueIsBasicBlock(V) || LLVMValueAsBasicBlock(V) != Src)
674       report_fatal_error("Basic block is not a basic block");
675 
676     const char *Name = LLVMGetBasicBlockName(Src);
677     const char *VName = LLVMGetValueName(V);
678     if (Name != VName)
679       report_fatal_error("Basic block name mismatch");
680 
681     LLVMBasicBlockRef BB = LLVMAppendBasicBlock(Fun, Name);
682     return BBMap[Src] = BB;
683   }
684 
CloneBBFunCloner685   LLVMBasicBlockRef CloneBB(LLVMBasicBlockRef Src) {
686     LLVMBasicBlockRef BB = DeclareBB(Src);
687 
688     // Make sure ordering is correct.
689     LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Src);
690     if (Prev)
691       LLVMMoveBasicBlockAfter(BB, DeclareBB(Prev));
692 
693     LLVMValueRef First = LLVMGetFirstInstruction(Src);
694     LLVMValueRef Last = LLVMGetLastInstruction(Src);
695 
696     if (First == nullptr) {
697       if (Last != nullptr)
698         report_fatal_error("Has no first instruction, but last one");
699       return BB;
700     }
701 
702     auto Ctx = LLVMGetModuleContext(M);
703     LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);
704     LLVMPositionBuilderAtEnd(Builder, BB);
705 
706     LLVMValueRef Cur = First;
707     LLVMValueRef Next = nullptr;
708     while(true) {
709       CloneInstruction(Cur, Builder);
710       Next = LLVMGetNextInstruction(Cur);
711       if (Next == nullptr) {
712         if (Cur != Last)
713           report_fatal_error("Final instruction does not match Last");
714         break;
715       }
716 
717       LLVMValueRef Prev = LLVMGetPreviousInstruction(Next);
718       if (Prev != Cur)
719         report_fatal_error("Next.Previous instruction is not Current");
720 
721       Cur = Next;
722     }
723 
724     LLVMDisposeBuilder(Builder);
725     return BB;
726   }
727 
CloneBBsFunCloner728   void CloneBBs(LLVMValueRef Src) {
729     unsigned Count = LLVMCountBasicBlocks(Src);
730     if (Count == 0)
731       return;
732 
733     LLVMBasicBlockRef First = LLVMGetFirstBasicBlock(Src);
734     LLVMBasicBlockRef Last = LLVMGetLastBasicBlock(Src);
735 
736     LLVMBasicBlockRef Cur = First;
737     LLVMBasicBlockRef Next = nullptr;
738     while(true) {
739       CloneBB(Cur);
740       Count--;
741       Next = LLVMGetNextBasicBlock(Cur);
742       if (Next == nullptr) {
743         if (Cur != Last)
744           report_fatal_error("Final basic block does not match Last");
745         break;
746       }
747 
748       LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Next);
749       if (Prev != Cur)
750         report_fatal_error("Next.Previous basic bloc is not Current");
751 
752       Cur = Next;
753     }
754 
755     if (Count != 0)
756       report_fatal_error("Basic block count does not match iterration");
757   }
758 };
759 
declare_symbols(LLVMModuleRef Src,LLVMModuleRef M)760 static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
761   LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
762   LLVMValueRef End = LLVMGetLastGlobal(Src);
763 
764   LLVMValueRef Cur = Begin;
765   LLVMValueRef Next = nullptr;
766   if (!Begin) {
767     if (End != nullptr)
768       report_fatal_error("Range has an end but no begining");
769     goto FunDecl;
770   }
771 
772   while (true) {
773     const char *Name = LLVMGetValueName(Cur);
774     if (LLVMGetNamedGlobal(M, Name))
775       report_fatal_error("GlobalVariable already cloned");
776     LLVMAddGlobal(M, LLVMGetElementType(TypeCloner(M).Clone(Cur)), Name);
777 
778     Next = LLVMGetNextGlobal(Cur);
779     if (Next == nullptr) {
780       if (Cur != End)
781         report_fatal_error("");
782       break;
783     }
784 
785     LLVMValueRef Prev = LLVMGetPreviousGlobal(Next);
786     if (Prev != Cur)
787       report_fatal_error("Next.Previous global is not Current");
788 
789     Cur = Next;
790   }
791 
792 FunDecl:
793   Begin = LLVMGetFirstFunction(Src);
794   End = LLVMGetLastFunction(Src);
795   if (!Begin) {
796     if (End != nullptr)
797       report_fatal_error("Range has an end but no begining");
798     return;
799   }
800 
801   auto Ctx = LLVMGetModuleContext(M);
802 
803   Cur = Begin;
804   Next = nullptr;
805   while (true) {
806     const char *Name = LLVMGetValueName(Cur);
807     if (LLVMGetNamedFunction(M, Name))
808       report_fatal_error("Function already cloned");
809     auto Ty = LLVMGetElementType(TypeCloner(M).Clone(Cur));
810     auto F = LLVMAddFunction(M, Name, Ty);
811 
812     // Copy attributes
813     for (int i = LLVMAttributeFunctionIndex, c = LLVMCountParams(F);
814          i <= c; ++i) {
815       for (unsigned k = 0, e = LLVMGetLastEnumAttributeKind(); k < e; ++k) {
816         if (auto SrcA = LLVMGetEnumAttributeAtIndex(Cur, i, k)) {
817           auto Val = LLVMGetEnumAttributeValue(SrcA);
818           auto DstA = LLVMCreateEnumAttribute(Ctx, k, Val);
819           LLVMAddAttributeAtIndex(F, i, DstA);
820         }
821       }
822     }
823 
824     Next = LLVMGetNextFunction(Cur);
825     if (Next == nullptr) {
826       if (Cur != End)
827         report_fatal_error("Last function does not match End");
828       break;
829     }
830 
831     LLVMValueRef Prev = LLVMGetPreviousFunction(Next);
832     if (Prev != Cur)
833       report_fatal_error("Next.Previous function is not Current");
834 
835     Cur = Next;
836   }
837 }
838 
clone_symbols(LLVMModuleRef Src,LLVMModuleRef M)839 static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
840   LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
841   LLVMValueRef End = LLVMGetLastGlobal(Src);
842 
843   LLVMValueRef Cur = Begin;
844   LLVMValueRef Next = nullptr;
845   if (!Begin) {
846     if (End != nullptr)
847       report_fatal_error("Range has an end but no begining");
848     goto FunClone;
849   }
850 
851   while (true) {
852     const char *Name = LLVMGetValueName(Cur);
853     LLVMValueRef G = LLVMGetNamedGlobal(M, Name);
854     if (!G)
855       report_fatal_error("GlobalVariable must have been declared already");
856 
857     if (auto I = LLVMGetInitializer(Cur))
858       LLVMSetInitializer(G, clone_constant(I, M));
859 
860     LLVMSetGlobalConstant(G, LLVMIsGlobalConstant(Cur));
861     LLVMSetThreadLocal(G, LLVMIsThreadLocal(Cur));
862     LLVMSetExternallyInitialized(G, LLVMIsExternallyInitialized(Cur));
863     LLVMSetLinkage(G, LLVMGetLinkage(Cur));
864     LLVMSetSection(G, LLVMGetSection(Cur));
865     LLVMSetVisibility(G, LLVMGetVisibility(Cur));
866     LLVMSetUnnamedAddr(G, LLVMHasUnnamedAddr(Cur));
867     LLVMSetAlignment(G, LLVMGetAlignment(Cur));
868 
869     Next = LLVMGetNextGlobal(Cur);
870     if (Next == nullptr) {
871       if (Cur != End)
872         report_fatal_error("");
873       break;
874     }
875 
876     LLVMValueRef Prev = LLVMGetPreviousGlobal(Next);
877     if (Prev != Cur)
878       report_fatal_error("Next.Previous global is not Current");
879 
880     Cur = Next;
881   }
882 
883 FunClone:
884   Begin = LLVMGetFirstFunction(Src);
885   End = LLVMGetLastFunction(Src);
886   if (!Begin) {
887     if (End != nullptr)
888       report_fatal_error("Range has an end but no begining");
889     return;
890   }
891 
892   Cur = Begin;
893   Next = nullptr;
894   while (true) {
895     const char *Name = LLVMGetValueName(Cur);
896     LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
897     if (!Fun)
898       report_fatal_error("Function must have been declared already");
899 
900     if (LLVMHasPersonalityFn(Cur)) {
901       const char *FName = LLVMGetValueName(LLVMGetPersonalityFn(Cur));
902       LLVMValueRef P = LLVMGetNamedFunction(M, FName);
903       if (!P)
904         report_fatal_error("Could not find personality function");
905       LLVMSetPersonalityFn(Fun, P);
906     }
907 
908     FunCloner FC(Cur, Fun);
909     FC.CloneBBs(Cur);
910 
911     Next = LLVMGetNextFunction(Cur);
912     if (Next == nullptr) {
913       if (Cur != End)
914         report_fatal_error("Last function does not match End");
915       break;
916     }
917 
918     LLVMValueRef Prev = LLVMGetPreviousFunction(Next);
919     if (Prev != Cur)
920       report_fatal_error("Next.Previous function is not Current");
921 
922     Cur = Next;
923   }
924 }
925 
llvm_echo(void)926 int llvm_echo(void) {
927   LLVMEnablePrettyStackTrace();
928 
929   LLVMModuleRef Src = llvm_load_module(false, true);
930   size_t Len;
931   const char *ModuleName = LLVMGetModuleIdentifier(Src, &Len);
932   LLVMContextRef Ctx = LLVMContextCreate();
933   LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleName, Ctx);
934 
935   // This whole switcharound is done because the C API has no way to
936   // set the source_filename
937   LLVMSetModuleIdentifier(M, "", 0);
938   LLVMGetModuleIdentifier(M, &Len);
939   if (Len != 0)
940       report_fatal_error("LLVM{Set,Get}ModuleIdentifier failed");
941   LLVMSetModuleIdentifier(M, ModuleName, strlen(ModuleName));
942 
943   LLVMSetTarget(M, LLVMGetTarget(Src));
944   LLVMSetModuleDataLayout(M, LLVMGetModuleDataLayout(Src));
945   if (strcmp(LLVMGetDataLayoutStr(M), LLVMGetDataLayoutStr(Src)))
946     report_fatal_error("Inconsistent DataLayout string representation");
947 
948   declare_symbols(Src, M);
949   clone_symbols(Src, M);
950   char *Str = LLVMPrintModuleToString(M);
951   fputs(Str, stdout);
952 
953   LLVMDisposeMessage(Str);
954   LLVMDisposeModule(M);
955   LLVMContextDispose(Ctx);
956 
957   return 0;
958 }
959