1//===-- echo.cpp - tool for testing libLLVM and llvm-c API ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the --echo command in llvm-c-test.
10//
11// This command uses the C API to read a module and output an exact copy of it
12// as output. It is used to check that the resulting module matches the input
13// to validate that the C API can read and write modules properly.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm-c-test.h"
18#include "llvm-c/DebugInfo.h"
19#include "llvm-c/ErrorHandling.h"
20#include "llvm-c/Target.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/Hashing.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/Support/ErrorHandling.h"
25
26#include <stdio.h>
27#include <stdlib.h>
28
29using namespace llvm;
30
31// Provide DenseMapInfo for C API opaque types.
32template<typename T>
33struct CAPIDenseMap {};
34
35// The default DenseMapInfo require to know about pointer alignment.
36// Because the C API uses opaque pointer types, their alignment is unknown.
37// As a result, we need to roll out our own implementation.
38template<typename T>
39struct CAPIDenseMap<T*> {
40 struct CAPIDenseMapInfo {
41 static inline T* getEmptyKey() {
42 uintptr_t Val = static_cast<uintptr_t>(-1);
43 return reinterpret_cast<T*>(Val);
44 }
45 static inline T* getTombstoneKey() {
46 uintptr_t Val = static_cast<uintptr_t>(-2);
47 return reinterpret_cast<T*>(Val);
48 }
49 static unsigned getHashValue(const T *PtrVal) {
50 return hash_value(PtrVal);
51 }
52 static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
53 };
54
55 typedef DenseMap<T*, T*, CAPIDenseMapInfo> Map;
56};
57
58typedef CAPIDenseMap<LLVMValueRef>::Map ValueMap;
59typedef CAPIDenseMap<LLVMBasicBlockRef>::Map BasicBlockMap;
60
61struct TypeCloner {
62 LLVMModuleRef M;
63 LLVMContextRef Ctx;
64
65 TypeCloner(LLVMModuleRef M): M(M), Ctx(LLVMGetModuleContext(M)) {}
66
67 LLVMTypeRef Clone(LLVMValueRef Src) {
68 return Clone(Src: LLVMTypeOf(Val: Src));
69 }
70
71 LLVMTypeRef Clone(LLVMTypeRef Src) {
72 LLVMTypeKind Kind = LLVMGetTypeKind(Ty: Src);
73 switch (Kind) {
74 case LLVMVoidTypeKind:
75 return LLVMVoidTypeInContext(C: Ctx);
76 case LLVMHalfTypeKind:
77 return LLVMHalfTypeInContext(C: Ctx);
78 case LLVMBFloatTypeKind:
79 return LLVMHalfTypeInContext(C: Ctx);
80 case LLVMFloatTypeKind:
81 return LLVMFloatTypeInContext(C: Ctx);
82 case LLVMDoubleTypeKind:
83 return LLVMDoubleTypeInContext(C: Ctx);
84 case LLVMX86_FP80TypeKind:
85 return LLVMX86FP80TypeInContext(C: Ctx);
86 case LLVMFP128TypeKind:
87 return LLVMFP128TypeInContext(C: Ctx);
88 case LLVMPPC_FP128TypeKind:
89 return LLVMPPCFP128TypeInContext(C: Ctx);
90 case LLVMLabelTypeKind:
91 return LLVMLabelTypeInContext(C: Ctx);
92 case LLVMIntegerTypeKind:
93 return LLVMIntTypeInContext(C: Ctx, NumBits: LLVMGetIntTypeWidth(IntegerTy: Src));
94 case LLVMFunctionTypeKind: {
95 unsigned ParamCount = LLVMCountParamTypes(FunctionTy: Src);
96 LLVMTypeRef* Params = nullptr;
97 if (ParamCount > 0) {
98 Params = static_cast<LLVMTypeRef*>(
99 safe_malloc(Sz: ParamCount * sizeof(LLVMTypeRef)));
100 LLVMGetParamTypes(FunctionTy: Src, Dest: Params);
101 for (unsigned i = 0; i < ParamCount; i++)
102 Params[i] = Clone(Src: Params[i]);
103 }
104
105 LLVMTypeRef FunTy = LLVMFunctionType(ReturnType: Clone(Src: LLVMGetReturnType(FunctionTy: Src)),
106 ParamTypes: Params, ParamCount,
107 IsVarArg: LLVMIsFunctionVarArg(FunctionTy: Src));
108 if (ParamCount > 0)
109 free(ptr: Params);
110 return FunTy;
111 }
112 case LLVMStructTypeKind: {
113 LLVMTypeRef S = nullptr;
114 const char *Name = LLVMGetStructName(Ty: Src);
115 if (Name) {
116 S = LLVMGetTypeByName2(C: Ctx, Name);
117 if (S)
118 return S;
119 S = LLVMStructCreateNamed(C: Ctx, Name);
120 if (LLVMIsOpaqueStruct(StructTy: Src))
121 return S;
122 }
123
124 unsigned EltCount = LLVMCountStructElementTypes(StructTy: Src);
125 SmallVector<LLVMTypeRef, 8> Elts;
126 for (unsigned i = 0; i < EltCount; i++)
127 Elts.push_back(Elt: Clone(Src: LLVMStructGetTypeAtIndex(StructTy: Src, i)));
128 if (Name)
129 LLVMStructSetBody(StructTy: S, ElementTypes: Elts.data(), ElementCount: EltCount, Packed: LLVMIsPackedStruct(StructTy: Src));
130 else
131 S = LLVMStructTypeInContext(C: Ctx, ElementTypes: Elts.data(), ElementCount: EltCount,
132 Packed: LLVMIsPackedStruct(StructTy: Src));
133 return S;
134 }
135 case LLVMArrayTypeKind:
136 return LLVMArrayType2(ElementType: Clone(Src: LLVMGetElementType(Ty: Src)),
137 ElementCount: LLVMGetArrayLength2(ArrayTy: Src));
138 case LLVMPointerTypeKind:
139 if (LLVMPointerTypeIsOpaque(Ty: Src))
140 return LLVMPointerTypeInContext(C: Ctx, AddressSpace: LLVMGetPointerAddressSpace(PointerTy: Src));
141 else
142 return LLVMPointerType(ElementType: Clone(Src: LLVMGetElementType(Ty: Src)),
143 AddressSpace: LLVMGetPointerAddressSpace(PointerTy: Src));
144 case LLVMVectorTypeKind:
145 return LLVMVectorType(
146 ElementType: Clone(Src: LLVMGetElementType(Ty: Src)),
147 ElementCount: LLVMGetVectorSize(VectorTy: Src)
148 );
149 case LLVMScalableVectorTypeKind:
150 return LLVMScalableVectorType(ElementType: Clone(Src: LLVMGetElementType(Ty: Src)),
151 ElementCount: LLVMGetVectorSize(VectorTy: Src));
152 case LLVMMetadataTypeKind:
153 return LLVMMetadataTypeInContext(C: Ctx);
154 case LLVMX86_AMXTypeKind:
155 return LLVMX86AMXTypeInContext(C: Ctx);
156 case LLVMX86_MMXTypeKind:
157 return LLVMX86MMXTypeInContext(C: Ctx);
158 case LLVMTokenTypeKind:
159 return LLVMTokenTypeInContext(C: Ctx);
160 case LLVMTargetExtTypeKind: {
161 const char *Name = LLVMGetTargetExtTypeName(TargetExtTy: Src);
162 unsigned NumTypeParams = LLVMGetTargetExtTypeNumTypeParams(TargetExtTy: Src);
163 unsigned NumIntParams = LLVMGetTargetExtTypeNumIntParams(TargetExtTy: Src);
164
165 SmallVector<LLVMTypeRef, 4> TypeParams((size_t)NumTypeParams);
166 SmallVector<unsigned, 4> IntParams((size_t)NumIntParams);
167
168 for (unsigned i = 0; i < TypeParams.size(); i++)
169 TypeParams[i] = Clone(Src: LLVMGetTargetExtTypeTypeParam(TargetExtTy: Src, Idx: i));
170
171 for (unsigned i = 0; i < IntParams.size(); i++)
172 IntParams[i] = LLVMGetTargetExtTypeIntParam(TargetExtTy: Src, Idx: i);
173
174 LLVMTypeRef TargetExtTy = LLVMTargetExtTypeInContext(
175 C: Ctx, Name, TypeParams: TypeParams.data(), TypeParamCount: TypeParams.size(), IntParams: IntParams.data(),
176 IntParamCount: IntParams.size());
177
178 return TargetExtTy;
179 }
180 }
181
182 fprintf(stderr, format: "%d is not a supported typekind\n", Kind);
183 exit(status: -1);
184 }
185};
186
187static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst) {
188 unsigned Count = LLVMCountParams(Fn: Src);
189 if (Count != LLVMCountParams(Fn: Dst))
190 report_fatal_error(reason: "Parameter count mismatch");
191
192 ValueMap VMap;
193 if (Count == 0)
194 return VMap;
195
196 LLVMValueRef SrcFirst = LLVMGetFirstParam(Fn: Src);
197 LLVMValueRef DstFirst = LLVMGetFirstParam(Fn: Dst);
198 LLVMValueRef SrcLast = LLVMGetLastParam(Fn: Src);
199 LLVMValueRef DstLast = LLVMGetLastParam(Fn: Dst);
200
201 LLVMValueRef SrcCur = SrcFirst;
202 LLVMValueRef DstCur = DstFirst;
203 LLVMValueRef SrcNext = nullptr;
204 LLVMValueRef DstNext = nullptr;
205 while (true) {
206 size_t NameLen;
207 const char *Name = LLVMGetValueName2(Val: SrcCur, Length: &NameLen);
208 LLVMSetValueName2(Val: DstCur, Name, NameLen);
209
210 VMap[SrcCur] = DstCur;
211
212 Count--;
213 SrcNext = LLVMGetNextParam(Arg: SrcCur);
214 DstNext = LLVMGetNextParam(Arg: DstCur);
215 if (SrcNext == nullptr && DstNext == nullptr) {
216 if (SrcCur != SrcLast)
217 report_fatal_error(reason: "SrcLast param does not match End");
218 if (DstCur != DstLast)
219 report_fatal_error(reason: "DstLast param does not match End");
220 break;
221 }
222
223 if (SrcNext == nullptr)
224 report_fatal_error(reason: "SrcNext was unexpectedly null");
225 if (DstNext == nullptr)
226 report_fatal_error(reason: "DstNext was unexpectedly null");
227
228 LLVMValueRef SrcPrev = LLVMGetPreviousParam(Arg: SrcNext);
229 if (SrcPrev != SrcCur)
230 report_fatal_error(reason: "SrcNext.Previous param is not Current");
231
232 LLVMValueRef DstPrev = LLVMGetPreviousParam(Arg: DstNext);
233 if (DstPrev != DstCur)
234 report_fatal_error(reason: "DstNext.Previous param is not Current");
235
236 SrcCur = SrcNext;
237 DstCur = DstNext;
238 }
239
240 if (Count != 0)
241 report_fatal_error(reason: "Parameter count does not match iteration");
242
243 return VMap;
244}
245
246static void check_value_kind(LLVMValueRef V, LLVMValueKind K) {
247 if (LLVMGetValueKind(Val: V) != K)
248 report_fatal_error(reason: "LLVMGetValueKind returned incorrect type");
249}
250
251static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M);
252
253static LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) {
254 LLVMValueRef Ret = clone_constant_impl(Cst, M);
255 check_value_kind(V: Ret, K: LLVMGetValueKind(Val: Cst));
256 return Ret;
257}
258
259static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) {
260 if (!LLVMIsAConstant(Val: Cst))
261 report_fatal_error(reason: "Expected a constant");
262
263 // Maybe it is a symbol
264 if (LLVMIsAGlobalValue(Val: Cst)) {
265 size_t NameLen;
266 const char *Name = LLVMGetValueName2(Val: Cst, Length: &NameLen);
267
268 // Try function
269 if (LLVMIsAFunction(Val: Cst)) {
270 check_value_kind(V: Cst, K: LLVMFunctionValueKind);
271
272 LLVMValueRef Dst = nullptr;
273 // Try an intrinsic
274 unsigned ID = LLVMGetIntrinsicID(Fn: Cst);
275 if (ID > 0 && !LLVMIntrinsicIsOverloaded(ID)) {
276 Dst = LLVMGetIntrinsicDeclaration(Mod: M, ID, ParamTypes: nullptr, ParamCount: 0);
277 } else {
278 // Try a normal function
279 Dst = LLVMGetNamedFunction(M, Name);
280 }
281
282 if (Dst)
283 return Dst;
284 report_fatal_error(reason: "Could not find function");
285 }
286
287 // Try global variable
288 if (LLVMIsAGlobalVariable(Val: Cst)) {
289 check_value_kind(V: Cst, K: LLVMGlobalVariableValueKind);
290 LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name);
291 if (Dst)
292 return Dst;
293 report_fatal_error(reason: "Could not find variable");
294 }
295
296 // Try global alias
297 if (LLVMIsAGlobalAlias(Val: Cst)) {
298 check_value_kind(V: Cst, K: LLVMGlobalAliasValueKind);
299 LLVMValueRef Dst = LLVMGetNamedGlobalAlias(M, Name, NameLen);
300 if (Dst)
301 return Dst;
302 report_fatal_error(reason: "Could not find alias");
303 }
304
305 fprintf(stderr, format: "Could not find @%s\n", Name);
306 exit(status: -1);
307 }
308
309 // Try integer literal
310 if (LLVMIsAConstantInt(Val: Cst)) {
311 check_value_kind(V: Cst, K: LLVMConstantIntValueKind);
312 return LLVMConstInt(IntTy: TypeCloner(M).Clone(Src: Cst),
313 N: LLVMConstIntGetZExtValue(ConstantVal: Cst), SignExtend: false);
314 }
315
316 // Try zeroinitializer
317 if (LLVMIsAConstantAggregateZero(Val: Cst)) {
318 check_value_kind(V: Cst, K: LLVMConstantAggregateZeroValueKind);
319 return LLVMConstNull(Ty: TypeCloner(M).Clone(Src: Cst));
320 }
321
322 // Try constant array or constant data array
323 if (LLVMIsAConstantArray(Val: Cst) || LLVMIsAConstantDataArray(Val: Cst)) {
324 check_value_kind(V: Cst, K: LLVMIsAConstantArray(Val: Cst)
325 ? LLVMConstantArrayValueKind
326 : LLVMConstantDataArrayValueKind);
327 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: Cst);
328 uint64_t EltCount = LLVMGetArrayLength2(ArrayTy: Ty);
329 SmallVector<LLVMValueRef, 8> Elts;
330 for (uint64_t i = 0; i < EltCount; i++)
331 Elts.push_back(Elt: clone_constant(Cst: LLVMGetAggregateElement(C: Cst, Idx: i), M));
332 return LLVMConstArray(ElementTy: LLVMGetElementType(Ty), ConstantVals: Elts.data(), Length: EltCount);
333 }
334
335 // Try constant struct
336 if (LLVMIsAConstantStruct(Val: Cst)) {
337 check_value_kind(V: Cst, K: LLVMConstantStructValueKind);
338 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: Cst);
339 unsigned EltCount = LLVMCountStructElementTypes(StructTy: Ty);
340 SmallVector<LLVMValueRef, 8> Elts;
341 for (unsigned i = 0; i < EltCount; i++)
342 Elts.push_back(Elt: clone_constant(Cst: LLVMGetOperand(Val: Cst, Index: i), M));
343 if (LLVMGetStructName(Ty))
344 return LLVMConstNamedStruct(StructTy: Ty, ConstantVals: Elts.data(), Count: EltCount);
345 return LLVMConstStructInContext(C: LLVMGetModuleContext(M), ConstantVals: Elts.data(),
346 Count: EltCount, Packed: LLVMIsPackedStruct(StructTy: Ty));
347 }
348
349 // Try ConstantPointerNull
350 if (LLVMIsAConstantPointerNull(Val: Cst)) {
351 check_value_kind(V: Cst, K: LLVMConstantPointerNullValueKind);
352 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: Cst);
353 return LLVMConstNull(Ty);
354 }
355
356 // Try undef
357 if (LLVMIsUndef(Val: Cst)) {
358 check_value_kind(V: Cst, K: LLVMUndefValueValueKind);
359 return LLVMGetUndef(Ty: TypeCloner(M).Clone(Src: Cst));
360 }
361
362 // Try poison
363 if (LLVMIsPoison(Val: Cst)) {
364 check_value_kind(V: Cst, K: LLVMPoisonValueValueKind);
365 return LLVMGetPoison(Ty: TypeCloner(M).Clone(Src: Cst));
366 }
367
368 // Try null
369 if (LLVMIsNull(Val: Cst)) {
370 check_value_kind(V: Cst, K: LLVMConstantTokenNoneValueKind);
371 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: Cst);
372 return LLVMConstNull(Ty);
373 }
374
375 // Try float literal
376 if (LLVMIsAConstantFP(Val: Cst)) {
377 check_value_kind(V: Cst, K: LLVMConstantFPValueKind);
378 report_fatal_error(reason: "ConstantFP is not supported");
379 }
380
381 // Try ConstantVector or ConstantDataVector
382 if (LLVMIsAConstantVector(Val: Cst) || LLVMIsAConstantDataVector(Val: Cst)) {
383 check_value_kind(V: Cst, K: LLVMIsAConstantVector(Val: Cst)
384 ? LLVMConstantVectorValueKind
385 : LLVMConstantDataVectorValueKind);
386 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: Cst);
387 unsigned EltCount = LLVMGetVectorSize(VectorTy: Ty);
388 SmallVector<LLVMValueRef, 8> Elts;
389 for (unsigned i = 0; i < EltCount; i++)
390 Elts.push_back(Elt: clone_constant(Cst: LLVMGetAggregateElement(C: Cst, Idx: i), M));
391 return LLVMConstVector(ScalarConstantVals: Elts.data(), Size: EltCount);
392 }
393
394 if (LLVMIsAConstantPtrAuth(Val: Cst)) {
395 LLVMValueRef Ptr = clone_constant(Cst: LLVMGetConstantPtrAuthPointer(PtrAuth: Cst), M);
396 LLVMValueRef Key = clone_constant(Cst: LLVMGetConstantPtrAuthKey(PtrAuth: Cst), M);
397 LLVMValueRef Disc =
398 clone_constant(Cst: LLVMGetConstantPtrAuthDiscriminator(PtrAuth: Cst), M);
399 LLVMValueRef AddrDisc =
400 clone_constant(Cst: LLVMGetConstantPtrAuthAddrDiscriminator(PtrAuth: Cst), M);
401 return LLVMConstantPtrAuth(Ptr, Key, Disc, AddrDisc);
402 }
403
404 // At this point, if it's not a constant expression, it's a kind of constant
405 // which is not supported
406 if (!LLVMIsAConstantExpr(Val: Cst))
407 report_fatal_error(reason: "Unsupported constant kind");
408
409 // At this point, it must be a constant expression
410 check_value_kind(V: Cst, K: LLVMConstantExprValueKind);
411
412 LLVMOpcode Op = LLVMGetConstOpcode(ConstantVal: Cst);
413 switch(Op) {
414 case LLVMBitCast:
415 return LLVMConstBitCast(ConstantVal: clone_constant(Cst: LLVMGetOperand(Val: Cst, Index: 0), M),
416 ToType: TypeCloner(M).Clone(Src: Cst));
417 case LLVMGetElementPtr: {
418 LLVMTypeRef ElemTy =
419 TypeCloner(M).Clone(Src: LLVMGetGEPSourceElementType(GEP: Cst));
420 LLVMValueRef Ptr = clone_constant(Cst: LLVMGetOperand(Val: Cst, Index: 0), M);
421 int NumIdx = LLVMGetNumIndices(Inst: Cst);
422 SmallVector<LLVMValueRef, 8> Idx;
423 for (int i = 1; i <= NumIdx; i++)
424 Idx.push_back(Elt: clone_constant(Cst: LLVMGetOperand(Val: Cst, Index: i), M));
425
426 return LLVMConstGEPWithNoWrapFlags(Ty: ElemTy, ConstantVal: Ptr, ConstantIndices: Idx.data(), NumIndices: NumIdx,
427 NoWrapFlags: LLVMGEPGetNoWrapFlags(GEP: Cst));
428 }
429 default:
430 fprintf(stderr, format: "%d is not a supported opcode for constant expressions\n",
431 Op);
432 exit(status: -1);
433 }
434}
435
436static LLVMValueRef clone_inline_asm(LLVMValueRef Asm, LLVMModuleRef M) {
437
438 if (!LLVMIsAInlineAsm(Val: Asm))
439 report_fatal_error(reason: "Expected inline assembly");
440
441 size_t AsmStringSize = 0;
442 const char *AsmString = LLVMGetInlineAsmAsmString(InlineAsmVal: Asm, Len: &AsmStringSize);
443
444 size_t ConstraintStringSize = 0;
445 const char *ConstraintString =
446 LLVMGetInlineAsmConstraintString(InlineAsmVal: Asm, Len: &ConstraintStringSize);
447
448 LLVMInlineAsmDialect AsmDialect = LLVMGetInlineAsmDialect(InlineAsmVal: Asm);
449
450 LLVMTypeRef AsmFunctionType = LLVMGetInlineAsmFunctionType(InlineAsmVal: Asm);
451
452 LLVMBool HasSideEffects = LLVMGetInlineAsmHasSideEffects(InlineAsmVal: Asm);
453 LLVMBool NeedsAlignStack = LLVMGetInlineAsmNeedsAlignedStack(InlineAsmVal: Asm);
454 LLVMBool CanUnwind = LLVMGetInlineAsmCanUnwind(InlineAsmVal: Asm);
455
456 return LLVMGetInlineAsm(Ty: AsmFunctionType, AsmString, AsmStringSize,
457 Constraints: ConstraintString, ConstraintsSize: ConstraintStringSize,
458 HasSideEffects, IsAlignStack: NeedsAlignStack, Dialect: AsmDialect,
459 CanThrow: CanUnwind);
460}
461
462struct FunCloner {
463 LLVMValueRef Fun;
464 LLVMModuleRef M;
465
466 ValueMap VMap;
467 BasicBlockMap BBMap;
468
469 FunCloner(LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst),
470 M(LLVMGetGlobalParent(Global: Fun)), VMap(clone_params(Src, Dst)) {}
471
472 LLVMTypeRef CloneType(LLVMTypeRef Src) {
473 return TypeCloner(M).Clone(Src);
474 }
475
476 LLVMTypeRef CloneType(LLVMValueRef Src) {
477 return TypeCloner(M).Clone(Src);
478 }
479
480 // Try to clone everything in the llvm::Value hierarchy.
481 LLVMValueRef CloneValue(LLVMValueRef Src) {
482 // First, the value may be constant.
483 if (LLVMIsAConstant(Val: Src))
484 return clone_constant(Cst: Src, M);
485
486 // Function argument should always be in the map already.
487 auto i = VMap.find(Val: Src);
488 if (i != VMap.end())
489 return i->second;
490
491 // Inline assembly is a Value, but not an Instruction
492 if (LLVMIsAInlineAsm(Val: Src))
493 return clone_inline_asm(Asm: Src, M);
494
495 if (!LLVMIsAInstruction(Val: Src))
496 report_fatal_error(reason: "Expected an instruction");
497
498 auto Ctx = LLVMGetModuleContext(M);
499 auto Builder = LLVMCreateBuilderInContext(C: Ctx);
500 auto BB = DeclareBB(Src: LLVMGetInstructionParent(Inst: Src));
501 LLVMPositionBuilderAtEnd(Builder, Block: BB);
502 auto Dst = CloneInstruction(Src, Builder);
503 LLVMDisposeBuilder(Builder);
504 return Dst;
505 }
506
507 void CloneAttrs(LLVMValueRef Src, LLVMValueRef Dst) {
508 auto Ctx = LLVMGetModuleContext(M);
509 int ArgCount = LLVMGetNumArgOperands(Instr: Src);
510 for (int i = LLVMAttributeReturnIndex; i <= ArgCount; i++) {
511 for (unsigned k = 0, e = LLVMGetLastEnumAttributeKind(); k < e; ++k) {
512 if (auto SrcA = LLVMGetCallSiteEnumAttribute(C: Src, Idx: i, KindID: k)) {
513 auto Val = LLVMGetEnumAttributeValue(A: SrcA);
514 auto A = LLVMCreateEnumAttribute(C: Ctx, KindID: k, Val);
515 LLVMAddCallSiteAttribute(C: Dst, Idx: i, A);
516 }
517 }
518 }
519 }
520
521 LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
522 check_value_kind(V: Src, K: LLVMInstructionValueKind);
523 if (!LLVMIsAInstruction(Val: Src))
524 report_fatal_error(reason: "Expected an instruction");
525
526 size_t NameLen;
527 const char *Name = LLVMGetValueName2(Val: Src, Length: &NameLen);
528
529 // Check if this is something we already computed.
530 {
531 auto i = VMap.find(Val: Src);
532 if (i != VMap.end()) {
533 // If we have a hit, it means we already generated the instruction
534 // as a dependency to something else. We need to make sure
535 // it is ordered properly.
536 auto I = i->second;
537 LLVMInstructionRemoveFromParent(Inst: I);
538 LLVMInsertIntoBuilderWithName(Builder, Instr: I, Name);
539 return I;
540 }
541 }
542
543 // We tried everything, it must be an instruction
544 // that hasn't been generated already.
545 LLVMValueRef Dst = nullptr;
546
547 LLVMOpcode Op = LLVMGetInstructionOpcode(Inst: Src);
548 switch(Op) {
549 case LLVMRet: {
550 int OpCount = LLVMGetNumOperands(Val: Src);
551 if (OpCount == 0)
552 Dst = LLVMBuildRetVoid(Builder);
553 else
554 Dst = LLVMBuildRet(Builder, V: CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0)));
555 break;
556 }
557 case LLVMBr: {
558 if (!LLVMIsConditional(Branch: Src)) {
559 LLVMValueRef SrcOp = LLVMGetOperand(Val: Src, Index: 0);
560 LLVMBasicBlockRef SrcBB = LLVMValueAsBasicBlock(Val: SrcOp);
561 Dst = LLVMBuildBr(Builder, Dest: DeclareBB(Src: SrcBB));
562 break;
563 }
564
565 LLVMValueRef Cond = LLVMGetCondition(Branch: Src);
566 LLVMValueRef Else = LLVMGetOperand(Val: Src, Index: 1);
567 LLVMBasicBlockRef ElseBB = DeclareBB(Src: LLVMValueAsBasicBlock(Val: Else));
568 LLVMValueRef Then = LLVMGetOperand(Val: Src, Index: 2);
569 LLVMBasicBlockRef ThenBB = DeclareBB(Src: LLVMValueAsBasicBlock(Val: Then));
570 Dst = LLVMBuildCondBr(Builder, If: CloneValue(Src: Cond), Then: ThenBB, Else: ElseBB);
571 break;
572 }
573 case LLVMSwitch:
574 case LLVMIndirectBr:
575 break;
576 case LLVMInvoke: {
577 SmallVector<LLVMValueRef, 8> Args;
578 SmallVector<LLVMOperandBundleRef, 8> Bundles;
579 unsigned ArgCount = LLVMGetNumArgOperands(Instr: Src);
580 for (unsigned i = 0; i < ArgCount; ++i)
581 Args.push_back(Elt: CloneValue(Src: LLVMGetOperand(Val: Src, Index: i)));
582 unsigned BundleCount = LLVMGetNumOperandBundles(C: Src);
583 for (unsigned i = 0; i < BundleCount; ++i) {
584 auto Bundle = LLVMGetOperandBundleAtIndex(C: Src, Index: i);
585 Bundles.push_back(Elt: CloneOB(Src: Bundle));
586 LLVMDisposeOperandBundle(Bundle);
587 }
588 LLVMTypeRef FnTy = CloneType(Src: LLVMGetCalledFunctionType(C: Src));
589 LLVMValueRef Fn = CloneValue(Src: LLVMGetCalledValue(Instr: Src));
590 LLVMBasicBlockRef Then = DeclareBB(Src: LLVMGetNormalDest(InvokeInst: Src));
591 LLVMBasicBlockRef Unwind = DeclareBB(Src: LLVMGetUnwindDest(InvokeInst: Src));
592 Dst = LLVMBuildInvokeWithOperandBundles(
593 Builder, Ty: FnTy, Fn, Args: Args.data(), NumArgs: ArgCount, Then, Catch: Unwind,
594 Bundles: Bundles.data(), NumBundles: Bundles.size(), Name);
595 CloneAttrs(Src, Dst);
596 for (auto Bundle : Bundles)
597 LLVMDisposeOperandBundle(Bundle);
598 break;
599 }
600 case LLVMCallBr: {
601 LLVMTypeRef FnTy = CloneType(Src: LLVMGetCalledFunctionType(C: Src));
602 LLVMValueRef Fn = CloneValue(Src: LLVMGetCalledValue(Instr: Src));
603
604 LLVMBasicBlockRef DefaultDest =
605 DeclareBB(Src: LLVMGetCallBrDefaultDest(CallBr: Src));
606
607 // Clone indirect destinations
608 SmallVector<LLVMBasicBlockRef, 8> IndirectDests;
609 unsigned IndirectDestCount = LLVMGetCallBrNumIndirectDests(CallBr: Src);
610 for (unsigned i = 0; i < IndirectDestCount; ++i)
611 IndirectDests.push_back(Elt: DeclareBB(Src: LLVMGetCallBrIndirectDest(CallBr: Src, Idx: i)));
612
613 // Clone input arguments
614 SmallVector<LLVMValueRef, 8> Args;
615 unsigned ArgCount = LLVMGetNumArgOperands(Instr: Src);
616 for (unsigned i = 0; i < ArgCount; ++i)
617 Args.push_back(Elt: CloneValue(Src: LLVMGetOperand(Val: Src, Index: i)));
618
619 // Clone operand bundles
620 SmallVector<LLVMOperandBundleRef, 8> Bundles;
621 unsigned BundleCount = LLVMGetNumOperandBundles(C: Src);
622 for (unsigned i = 0; i < BundleCount; ++i) {
623 auto Bundle = LLVMGetOperandBundleAtIndex(C: Src, Index: i);
624 Bundles.push_back(Elt: CloneOB(Src: Bundle));
625 LLVMDisposeOperandBundle(Bundle);
626 }
627
628 Dst = LLVMBuildCallBr(B: Builder, Ty: FnTy, Fn, DefaultDest,
629 IndirectDests: IndirectDests.data(), NumIndirectDests: IndirectDests.size(),
630 Args: Args.data(), NumArgs: Args.size(), Bundles: Bundles.data(),
631 NumBundles: Bundles.size(), Name);
632
633 CloneAttrs(Src, Dst);
634
635 for (auto Bundle : Bundles)
636 LLVMDisposeOperandBundle(Bundle);
637
638 break;
639 }
640 case LLVMUnreachable:
641 Dst = LLVMBuildUnreachable(Builder);
642 break;
643 case LLVMAdd: {
644 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
645 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
646 LLVMBool NUW = LLVMGetNUW(ArithInst: Src);
647 LLVMBool NSW = LLVMGetNSW(ArithInst: Src);
648 Dst = LLVMBuildAdd(Builder, LHS, RHS, Name);
649 LLVMSetNUW(ArithInst: Dst, HasNUW: NUW);
650 LLVMSetNSW(ArithInst: Dst, HasNSW: NSW);
651 break;
652 }
653 case LLVMSub: {
654 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
655 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
656 LLVMBool NUW = LLVMGetNUW(ArithInst: Src);
657 LLVMBool NSW = LLVMGetNSW(ArithInst: Src);
658 Dst = LLVMBuildSub(Builder, LHS, RHS, Name);
659 LLVMSetNUW(ArithInst: Dst, HasNUW: NUW);
660 LLVMSetNSW(ArithInst: Dst, HasNSW: NSW);
661 break;
662 }
663 case LLVMMul: {
664 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
665 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
666 LLVMBool NUW = LLVMGetNUW(ArithInst: Src);
667 LLVMBool NSW = LLVMGetNSW(ArithInst: Src);
668 Dst = LLVMBuildMul(Builder, LHS, RHS, Name);
669 LLVMSetNUW(ArithInst: Dst, HasNUW: NUW);
670 LLVMSetNSW(ArithInst: Dst, HasNSW: NSW);
671 break;
672 }
673 case LLVMUDiv: {
674 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
675 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
676 LLVMBool IsExact = LLVMGetExact(DivOrShrInst: Src);
677 Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name);
678 LLVMSetExact(DivOrShrInst: Dst, IsExact);
679 break;
680 }
681 case LLVMSDiv: {
682 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
683 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
684 LLVMBool IsExact = LLVMGetExact(DivOrShrInst: Src);
685 Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name);
686 LLVMSetExact(DivOrShrInst: Dst, IsExact);
687 break;
688 }
689 case LLVMURem: {
690 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
691 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
692 Dst = LLVMBuildURem(Builder, LHS, RHS, Name);
693 break;
694 }
695 case LLVMSRem: {
696 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
697 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
698 Dst = LLVMBuildSRem(Builder, LHS, RHS, Name);
699 break;
700 }
701 case LLVMShl: {
702 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
703 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
704 LLVMBool NUW = LLVMGetNUW(ArithInst: Src);
705 LLVMBool NSW = LLVMGetNSW(ArithInst: Src);
706 Dst = LLVMBuildShl(Builder, LHS, RHS, Name);
707 LLVMSetNUW(ArithInst: Dst, HasNUW: NUW);
708 LLVMSetNSW(ArithInst: Dst, HasNSW: NSW);
709 break;
710 }
711 case LLVMLShr: {
712 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
713 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
714 LLVMBool IsExact = LLVMGetExact(DivOrShrInst: Src);
715 Dst = LLVMBuildLShr(Builder, LHS, RHS, Name);
716 LLVMSetExact(DivOrShrInst: Dst, IsExact);
717 break;
718 }
719 case LLVMAShr: {
720 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
721 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
722 LLVMBool IsExact = LLVMGetExact(DivOrShrInst: Src);
723 Dst = LLVMBuildAShr(Builder, LHS, RHS, Name);
724 LLVMSetExact(DivOrShrInst: Dst, IsExact);
725 break;
726 }
727 case LLVMAnd: {
728 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
729 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
730 Dst = LLVMBuildAnd(Builder, LHS, RHS, Name);
731 break;
732 }
733 case LLVMOr: {
734 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
735 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
736 LLVMBool IsDisjoint = LLVMGetIsDisjoint(Inst: Src);
737 Dst = LLVMBuildOr(Builder, LHS, RHS, Name);
738 LLVMSetIsDisjoint(Inst: Dst, IsDisjoint);
739 break;
740 }
741 case LLVMXor: {
742 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
743 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
744 Dst = LLVMBuildXor(Builder, LHS, RHS, Name);
745 break;
746 }
747 case LLVMAlloca: {
748 LLVMTypeRef Ty = CloneType(Src: LLVMGetAllocatedType(Alloca: Src));
749 Dst = LLVMBuildAlloca(Builder, Ty, Name);
750 LLVMSetAlignment(V: Dst, Bytes: LLVMGetAlignment(V: Src));
751 break;
752 }
753 case LLVMLoad: {
754 LLVMValueRef Ptr = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
755 Dst = LLVMBuildLoad2(Builder, Ty: CloneType(Src), PointerVal: Ptr, Name);
756 LLVMSetAlignment(V: Dst, Bytes: LLVMGetAlignment(V: Src));
757 LLVMSetOrdering(MemoryAccessInst: Dst, Ordering: LLVMGetOrdering(MemoryAccessInst: Src));
758 LLVMSetVolatile(MemoryAccessInst: Dst, IsVolatile: LLVMGetVolatile(MemoryAccessInst: Src));
759 LLVMSetAtomicSingleThread(AtomicInst: Dst, SingleThread: LLVMIsAtomicSingleThread(AtomicInst: Src));
760 break;
761 }
762 case LLVMStore: {
763 LLVMValueRef Val = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
764 LLVMValueRef Ptr = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
765 Dst = LLVMBuildStore(Builder, Val, Ptr);
766 LLVMSetAlignment(V: Dst, Bytes: LLVMGetAlignment(V: Src));
767 LLVMSetOrdering(MemoryAccessInst: Dst, Ordering: LLVMGetOrdering(MemoryAccessInst: Src));
768 LLVMSetVolatile(MemoryAccessInst: Dst, IsVolatile: LLVMGetVolatile(MemoryAccessInst: Src));
769 LLVMSetAtomicSingleThread(AtomicInst: Dst, SingleThread: LLVMIsAtomicSingleThread(AtomicInst: Src));
770 break;
771 }
772 case LLVMGetElementPtr: {
773 LLVMTypeRef ElemTy = CloneType(Src: LLVMGetGEPSourceElementType(GEP: Src));
774 LLVMValueRef Ptr = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
775 SmallVector<LLVMValueRef, 8> Idx;
776 int NumIdx = LLVMGetNumIndices(Inst: Src);
777 for (int i = 1; i <= NumIdx; i++)
778 Idx.push_back(Elt: CloneValue(Src: LLVMGetOperand(Val: Src, Index: i)));
779
780 Dst = LLVMBuildGEPWithNoWrapFlags(B: Builder, Ty: ElemTy, Pointer: Ptr, Indices: Idx.data(),
781 NumIndices: NumIdx, Name,
782 NoWrapFlags: LLVMGEPGetNoWrapFlags(GEP: Src));
783 break;
784 }
785 case LLVMAtomicRMW: {
786 LLVMValueRef Ptr = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
787 LLVMValueRef Val = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
788 LLVMAtomicRMWBinOp BinOp = LLVMGetAtomicRMWBinOp(AtomicRMWInst: Src);
789 LLVMAtomicOrdering Ord = LLVMGetOrdering(MemoryAccessInst: Src);
790 LLVMBool SingleThread = LLVMIsAtomicSingleThread(AtomicInst: Src);
791 Dst = LLVMBuildAtomicRMW(B: Builder, op: BinOp, PTR: Ptr, Val, ordering: Ord, singleThread: SingleThread);
792 LLVMSetAlignment(V: Dst, Bytes: LLVMGetAlignment(V: Src));
793 LLVMSetVolatile(MemoryAccessInst: Dst, IsVolatile: LLVMGetVolatile(MemoryAccessInst: Src));
794 LLVMSetValueName2(Val: Dst, Name, NameLen);
795 break;
796 }
797 case LLVMAtomicCmpXchg: {
798 LLVMValueRef Ptr = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
799 LLVMValueRef Cmp = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
800 LLVMValueRef New = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 2));
801 LLVMAtomicOrdering Succ = LLVMGetCmpXchgSuccessOrdering(CmpXchgInst: Src);
802 LLVMAtomicOrdering Fail = LLVMGetCmpXchgFailureOrdering(CmpXchgInst: Src);
803 LLVMBool SingleThread = LLVMIsAtomicSingleThread(AtomicInst: Src);
804
805 Dst = LLVMBuildAtomicCmpXchg(B: Builder, Ptr, Cmp, New, SuccessOrdering: Succ, FailureOrdering: Fail,
806 SingleThread);
807 LLVMSetAlignment(V: Dst, Bytes: LLVMGetAlignment(V: Src));
808 LLVMSetVolatile(MemoryAccessInst: Dst, IsVolatile: LLVMGetVolatile(MemoryAccessInst: Src));
809 LLVMSetWeak(CmpXchgInst: Dst, IsWeak: LLVMGetWeak(CmpXchgInst: Src));
810 LLVMSetValueName2(Val: Dst, Name, NameLen);
811 break;
812 }
813 case LLVMBitCast: {
814 LLVMValueRef V = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
815 Dst = LLVMBuildBitCast(Builder, Val: V, DestTy: CloneType(Src), Name);
816 break;
817 }
818 case LLVMICmp: {
819 LLVMIntPredicate Pred = LLVMGetICmpPredicate(Inst: Src);
820 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
821 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
822 Dst = LLVMBuildICmp(Builder, Op: Pred, LHS, RHS, Name);
823 break;
824 }
825 case LLVMPHI: {
826 // We need to aggressively set things here because of loops.
827 VMap[Src] = Dst = LLVMBuildPhi(Builder, Ty: CloneType(Src), Name);
828
829 SmallVector<LLVMValueRef, 8> Values;
830 SmallVector<LLVMBasicBlockRef, 8> Blocks;
831
832 unsigned IncomingCount = LLVMCountIncoming(PhiNode: Src);
833 for (unsigned i = 0; i < IncomingCount; ++i) {
834 Blocks.push_back(Elt: DeclareBB(Src: LLVMGetIncomingBlock(PhiNode: Src, Index: i)));
835 Values.push_back(Elt: CloneValue(Src: LLVMGetIncomingValue(PhiNode: Src, Index: i)));
836 }
837
838 LLVMAddIncoming(PhiNode: Dst, IncomingValues: Values.data(), IncomingBlocks: Blocks.data(), Count: IncomingCount);
839 // Copy fast math flags here since we return early
840 if (LLVMCanValueUseFastMathFlags(Inst: Src))
841 LLVMSetFastMathFlags(FPMathInst: Dst, FMF: LLVMGetFastMathFlags(FPMathInst: Src));
842 return Dst;
843 }
844 case LLVMSelect: {
845 LLVMValueRef If = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
846 LLVMValueRef Then = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
847 LLVMValueRef Else = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 2));
848 Dst = LLVMBuildSelect(Builder, If, Then, Else, Name);
849 break;
850 }
851 case LLVMCall: {
852 SmallVector<LLVMValueRef, 8> Args;
853 SmallVector<LLVMOperandBundleRef, 8> Bundles;
854 unsigned ArgCount = LLVMGetNumArgOperands(Instr: Src);
855 for (unsigned i = 0; i < ArgCount; ++i)
856 Args.push_back(Elt: CloneValue(Src: LLVMGetOperand(Val: Src, Index: i)));
857 unsigned BundleCount = LLVMGetNumOperandBundles(C: Src);
858 for (unsigned i = 0; i < BundleCount; ++i) {
859 auto Bundle = LLVMGetOperandBundleAtIndex(C: Src, Index: i);
860 Bundles.push_back(Elt: CloneOB(Src: Bundle));
861 LLVMDisposeOperandBundle(Bundle);
862 }
863 LLVMTypeRef FnTy = CloneType(Src: LLVMGetCalledFunctionType(C: Src));
864 LLVMValueRef Fn = CloneValue(Src: LLVMGetCalledValue(Instr: Src));
865 Dst = LLVMBuildCallWithOperandBundles(Builder, FnTy, Fn, Args: Args.data(),
866 NumArgs: ArgCount, Bundles: Bundles.data(),
867 NumBundles: Bundles.size(), Name);
868 LLVMSetTailCallKind(CallInst: Dst, kind: LLVMGetTailCallKind(CallInst: Src));
869 CloneAttrs(Src, Dst);
870 for (auto Bundle : Bundles)
871 LLVMDisposeOperandBundle(Bundle);
872 break;
873 }
874 case LLVMResume: {
875 Dst = LLVMBuildResume(B: Builder, Exn: CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0)));
876 break;
877 }
878 case LLVMLandingPad: {
879 // The landing pad API is a bit screwed up for historical reasons.
880 Dst = LLVMBuildLandingPad(B: Builder, Ty: CloneType(Src), PersFn: nullptr, NumClauses: 0, Name);
881 unsigned NumClauses = LLVMGetNumClauses(LandingPad: Src);
882 for (unsigned i = 0; i < NumClauses; ++i)
883 LLVMAddClause(LandingPad: Dst, ClauseVal: CloneValue(Src: LLVMGetClause(LandingPad: Src, Idx: i)));
884 LLVMSetCleanup(LandingPad: Dst, Val: LLVMIsCleanup(LandingPad: Src));
885 break;
886 }
887 case LLVMCleanupRet: {
888 LLVMValueRef CatchPad = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
889 LLVMBasicBlockRef Unwind = nullptr;
890 if (LLVMBasicBlockRef UDest = LLVMGetUnwindDest(InvokeInst: Src))
891 Unwind = DeclareBB(Src: UDest);
892 Dst = LLVMBuildCleanupRet(B: Builder, CatchPad, BB: Unwind);
893 break;
894 }
895 case LLVMCatchRet: {
896 LLVMValueRef CatchPad = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
897 LLVMBasicBlockRef SuccBB = DeclareBB(Src: LLVMGetSuccessor(Term: Src, i: 0));
898 Dst = LLVMBuildCatchRet(B: Builder, CatchPad, BB: SuccBB);
899 break;
900 }
901 case LLVMCatchPad: {
902 LLVMValueRef ParentPad = CloneValue(Src: LLVMGetParentCatchSwitch(CatchPad: Src));
903 SmallVector<LLVMValueRef, 8> Args;
904 int ArgCount = LLVMGetNumArgOperands(Instr: Src);
905 for (int i = 0; i < ArgCount; i++)
906 Args.push_back(Elt: CloneValue(Src: LLVMGetOperand(Val: Src, Index: i)));
907 Dst = LLVMBuildCatchPad(B: Builder, ParentPad,
908 Args: Args.data(), NumArgs: ArgCount, Name);
909 break;
910 }
911 case LLVMCleanupPad: {
912 LLVMValueRef ParentPad = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
913 SmallVector<LLVMValueRef, 8> Args;
914 int ArgCount = LLVMGetNumArgOperands(Instr: Src);
915 for (int i = 0; i < ArgCount; i++)
916 Args.push_back(Elt: CloneValue(Src: LLVMGetArgOperand(Funclet: Src, i)));
917 Dst = LLVMBuildCleanupPad(B: Builder, ParentPad,
918 Args: Args.data(), NumArgs: ArgCount, Name);
919 break;
920 }
921 case LLVMCatchSwitch: {
922 LLVMValueRef ParentPad = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
923 LLVMBasicBlockRef UnwindBB = nullptr;
924 if (LLVMBasicBlockRef UDest = LLVMGetUnwindDest(InvokeInst: Src)) {
925 UnwindBB = DeclareBB(Src: UDest);
926 }
927 unsigned NumHandlers = LLVMGetNumHandlers(CatchSwitch: Src);
928 Dst = LLVMBuildCatchSwitch(B: Builder, ParentPad, UnwindBB, NumHandlers, Name);
929 if (NumHandlers > 0) {
930 LLVMBasicBlockRef *Handlers = static_cast<LLVMBasicBlockRef*>(
931 safe_malloc(Sz: NumHandlers * sizeof(LLVMBasicBlockRef)));
932 LLVMGetHandlers(CatchSwitch: Src, Handlers);
933 for (unsigned i = 0; i < NumHandlers; i++)
934 LLVMAddHandler(CatchSwitch: Dst, Dest: DeclareBB(Src: Handlers[i]));
935 free(ptr: Handlers);
936 }
937 break;
938 }
939 case LLVMExtractValue: {
940 LLVMValueRef Agg = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
941 if (LLVMGetNumIndices(Inst: Src) > 1)
942 report_fatal_error(reason: "ExtractValue: Expected only one index");
943 else if (LLVMGetNumIndices(Inst: Src) < 1)
944 report_fatal_error(reason: "ExtractValue: Expected an index");
945 auto I = LLVMGetIndices(Inst: Src)[0];
946 Dst = LLVMBuildExtractValue(Builder, AggVal: Agg, Index: I, Name);
947 break;
948 }
949 case LLVMInsertValue: {
950 LLVMValueRef Agg = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
951 LLVMValueRef V = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
952 if (LLVMGetNumIndices(Inst: Src) > 1)
953 report_fatal_error(reason: "InsertValue: Expected only one index");
954 else if (LLVMGetNumIndices(Inst: Src) < 1)
955 report_fatal_error(reason: "InsertValue: Expected an index");
956 auto I = LLVMGetIndices(Inst: Src)[0];
957 Dst = LLVMBuildInsertValue(Builder, AggVal: Agg, EltVal: V, Index: I, Name);
958 break;
959 }
960 case LLVMExtractElement: {
961 LLVMValueRef Agg = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
962 LLVMValueRef Index = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
963 Dst = LLVMBuildExtractElement(Builder, VecVal: Agg, Index, Name);
964 break;
965 }
966 case LLVMInsertElement: {
967 LLVMValueRef Agg = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
968 LLVMValueRef V = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
969 LLVMValueRef Index = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 2));
970 Dst = LLVMBuildInsertElement(Builder, VecVal: Agg, EltVal: V, Index, Name);
971 break;
972 }
973 case LLVMShuffleVector: {
974 LLVMValueRef Agg0 = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
975 LLVMValueRef Agg1 = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
976 SmallVector<LLVMValueRef, 8> MaskElts;
977 unsigned NumMaskElts = LLVMGetNumMaskElements(ShuffleVectorInst: Src);
978 for (unsigned i = 0; i < NumMaskElts; i++) {
979 int Val = LLVMGetMaskValue(ShuffleVectorInst: Src, Elt: i);
980 if (Val == LLVMGetUndefMaskElem()) {
981 MaskElts.push_back(Elt: LLVMGetUndef(Ty: LLVMInt64Type()));
982 } else {
983 MaskElts.push_back(Elt: LLVMConstInt(IntTy: LLVMInt64Type(), N: Val, SignExtend: true));
984 }
985 }
986 LLVMValueRef Mask = LLVMConstVector(ScalarConstantVals: MaskElts.data(), Size: NumMaskElts);
987 Dst = LLVMBuildShuffleVector(Builder, V1: Agg0, V2: Agg1, Mask, Name);
988 break;
989 }
990 case LLVMFreeze: {
991 LLVMValueRef Arg = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
992 Dst = LLVMBuildFreeze(Builder, Val: Arg, Name);
993 break;
994 }
995 case LLVMFence: {
996 LLVMAtomicOrdering Ordering = LLVMGetOrdering(MemoryAccessInst: Src);
997 LLVMBool IsSingleThreaded = LLVMIsAtomicSingleThread(AtomicInst: Src);
998 Dst = LLVMBuildFence(B: Builder, ordering: Ordering, singleThread: IsSingleThreaded, Name);
999 break;
1000 }
1001 case LLVMZExt: {
1002 LLVMValueRef Val = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1003 LLVMTypeRef DestTy = CloneType(Src: LLVMTypeOf(Val: Src));
1004 LLVMBool NNeg = LLVMGetNNeg(NonNegInst: Src);
1005 Dst = LLVMBuildZExt(Builder, Val, DestTy, Name);
1006 LLVMSetNNeg(NonNegInst: Dst, IsNonNeg: NNeg);
1007 break;
1008 }
1009 case LLVMFAdd: {
1010 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1011 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1012 Dst = LLVMBuildFAdd(Builder, LHS, RHS, Name);
1013 break;
1014 }
1015 case LLVMFSub: {
1016 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1017 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1018 Dst = LLVMBuildFSub(Builder, LHS, RHS, Name);
1019 break;
1020 }
1021 case LLVMFMul: {
1022 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1023 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1024 Dst = LLVMBuildFMul(Builder, LHS, RHS, Name);
1025 break;
1026 }
1027 case LLVMFDiv: {
1028 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1029 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1030 Dst = LLVMBuildFDiv(Builder, LHS, RHS, Name);
1031 break;
1032 }
1033 case LLVMFRem: {
1034 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1035 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1036 Dst = LLVMBuildFRem(Builder, LHS, RHS, Name);
1037 break;
1038 }
1039 case LLVMFNeg: {
1040 LLVMValueRef Val = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1041 Dst = LLVMBuildFNeg(Builder, V: Val, Name);
1042 break;
1043 }
1044 case LLVMFCmp: {
1045 LLVMRealPredicate Pred = LLVMGetFCmpPredicate(Inst: Src);
1046 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1047 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1048 Dst = LLVMBuildFCmp(Builder, Op: Pred, LHS, RHS, Name);
1049 break;
1050 }
1051 default:
1052 break;
1053 }
1054
1055 if (Dst == nullptr) {
1056 fprintf(stderr, format: "%d is not a supported opcode\n", Op);
1057 exit(status: -1);
1058 }
1059
1060 // Copy fast-math flags on instructions that support them
1061 if (LLVMCanValueUseFastMathFlags(Inst: Src))
1062 LLVMSetFastMathFlags(FPMathInst: Dst, FMF: LLVMGetFastMathFlags(FPMathInst: Src));
1063
1064 auto Ctx = LLVMGetModuleContext(M);
1065 size_t NumMetadataEntries;
1066 auto *AllMetadata =
1067 LLVMInstructionGetAllMetadataOtherThanDebugLoc(Instr: Src,
1068 NumEntries: &NumMetadataEntries);
1069 for (unsigned i = 0; i < NumMetadataEntries; ++i) {
1070 unsigned Kind = LLVMValueMetadataEntriesGetKind(Entries: AllMetadata, Index: i);
1071 LLVMMetadataRef MD = LLVMValueMetadataEntriesGetMetadata(Entries: AllMetadata, Index: i);
1072 LLVMSetMetadata(Val: Dst, KindID: Kind, Node: LLVMMetadataAsValue(C: Ctx, MD));
1073 }
1074 LLVMDisposeValueMetadataEntries(Entries: AllMetadata);
1075 LLVMAddMetadataToInst(Builder, Inst: Dst);
1076
1077 check_value_kind(V: Dst, K: LLVMInstructionValueKind);
1078 return VMap[Src] = Dst;
1079 }
1080
1081 LLVMOperandBundleRef CloneOB(LLVMOperandBundleRef Src) {
1082 size_t TagLen;
1083 const char *Tag = LLVMGetOperandBundleTag(Bundle: Src, Len: &TagLen);
1084
1085 SmallVector<LLVMValueRef, 8> Args;
1086 for (unsigned i = 0, n = LLVMGetNumOperandBundleArgs(Bundle: Src); i != n; ++i)
1087 Args.push_back(Elt: CloneValue(Src: LLVMGetOperandBundleArgAtIndex(Bundle: Src, Index: i)));
1088
1089 return LLVMCreateOperandBundle(Tag, TagLen, Args: Args.data(), NumArgs: Args.size());
1090 }
1091
1092 LLVMBasicBlockRef DeclareBB(LLVMBasicBlockRef Src) {
1093 // Check if this is something we already computed.
1094 {
1095 auto i = BBMap.find(Val: Src);
1096 if (i != BBMap.end()) {
1097 return i->second;
1098 }
1099 }
1100
1101 LLVMValueRef V = LLVMBasicBlockAsValue(BB: Src);
1102 if (!LLVMValueIsBasicBlock(Val: V) || LLVMValueAsBasicBlock(Val: V) != Src)
1103 report_fatal_error(reason: "Basic block is not a basic block");
1104
1105 const char *Name = LLVMGetBasicBlockName(BB: Src);
1106 size_t NameLen;
1107 const char *VName = LLVMGetValueName2(Val: V, Length: &NameLen);
1108 if (Name != VName)
1109 report_fatal_error(reason: "Basic block name mismatch");
1110
1111 LLVMBasicBlockRef BB = LLVMAppendBasicBlock(Fn: Fun, Name);
1112 return BBMap[Src] = BB;
1113 }
1114
1115 LLVMBasicBlockRef CloneBB(LLVMBasicBlockRef Src) {
1116 LLVMBasicBlockRef BB = DeclareBB(Src);
1117
1118 // Make sure ordering is correct.
1119 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(BB: Src);
1120 if (Prev)
1121 LLVMMoveBasicBlockAfter(BB, MovePos: DeclareBB(Src: Prev));
1122
1123 LLVMValueRef First = LLVMGetFirstInstruction(BB: Src);
1124 LLVMValueRef Last = LLVMGetLastInstruction(BB: Src);
1125
1126 if (First == nullptr) {
1127 if (Last != nullptr)
1128 report_fatal_error(reason: "Has no first instruction, but last one");
1129 return BB;
1130 }
1131
1132 auto Ctx = LLVMGetModuleContext(M);
1133 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(C: Ctx);
1134 LLVMPositionBuilderAtEnd(Builder, Block: BB);
1135
1136 LLVMValueRef Cur = First;
1137 LLVMValueRef Next = nullptr;
1138 while(true) {
1139 CloneInstruction(Src: Cur, Builder);
1140 Next = LLVMGetNextInstruction(Inst: Cur);
1141 if (Next == nullptr) {
1142 if (Cur != Last)
1143 report_fatal_error(reason: "Final instruction does not match Last");
1144 break;
1145 }
1146
1147 LLVMValueRef Prev = LLVMGetPreviousInstruction(Inst: Next);
1148 if (Prev != Cur)
1149 report_fatal_error(reason: "Next.Previous instruction is not Current");
1150
1151 Cur = Next;
1152 }
1153
1154 LLVMDisposeBuilder(Builder);
1155 return BB;
1156 }
1157
1158 void CloneBBs(LLVMValueRef Src) {
1159 unsigned Count = LLVMCountBasicBlocks(Fn: Src);
1160 if (Count == 0)
1161 return;
1162
1163 LLVMBasicBlockRef First = LLVMGetFirstBasicBlock(Fn: Src);
1164 LLVMBasicBlockRef Last = LLVMGetLastBasicBlock(Fn: Src);
1165
1166 LLVMBasicBlockRef Cur = First;
1167 LLVMBasicBlockRef Next = nullptr;
1168 while(true) {
1169 CloneBB(Src: Cur);
1170 Count--;
1171 Next = LLVMGetNextBasicBlock(BB: Cur);
1172 if (Next == nullptr) {
1173 if (Cur != Last)
1174 report_fatal_error(reason: "Final basic block does not match Last");
1175 break;
1176 }
1177
1178 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(BB: Next);
1179 if (Prev != Cur)
1180 report_fatal_error(reason: "Next.Previous basic bloc is not Current");
1181
1182 Cur = Next;
1183 }
1184
1185 if (Count != 0)
1186 report_fatal_error(reason: "Basic block count does not match iterration");
1187 }
1188};
1189
1190static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
1191 auto Ctx = LLVMGetModuleContext(M);
1192
1193 LLVMValueRef Begin = LLVMGetFirstGlobal(M: Src);
1194 LLVMValueRef End = LLVMGetLastGlobal(M: Src);
1195
1196 LLVMValueRef Cur = Begin;
1197 LLVMValueRef Next = nullptr;
1198 if (!Begin) {
1199 if (End != nullptr)
1200 report_fatal_error(reason: "Range has an end but no beginning");
1201 goto FunDecl;
1202 }
1203
1204 while (true) {
1205 size_t NameLen;
1206 const char *Name = LLVMGetValueName2(Val: Cur, Length: &NameLen);
1207 if (LLVMGetNamedGlobal(M, Name))
1208 report_fatal_error(reason: "GlobalVariable already cloned");
1209 LLVMAddGlobal(M, Ty: TypeCloner(M).Clone(Src: LLVMGlobalGetValueType(Global: Cur)), Name);
1210
1211 Next = LLVMGetNextGlobal(GlobalVar: Cur);
1212 if (Next == nullptr) {
1213 if (Cur != End)
1214 report_fatal_error(reason: "");
1215 break;
1216 }
1217
1218 LLVMValueRef Prev = LLVMGetPreviousGlobal(GlobalVar: Next);
1219 if (Prev != Cur)
1220 report_fatal_error(reason: "Next.Previous global is not Current");
1221
1222 Cur = Next;
1223 }
1224
1225FunDecl:
1226 Begin = LLVMGetFirstFunction(M: Src);
1227 End = LLVMGetLastFunction(M: Src);
1228 if (!Begin) {
1229 if (End != nullptr)
1230 report_fatal_error(reason: "Range has an end but no beginning");
1231 goto AliasDecl;
1232 }
1233
1234 Cur = Begin;
1235 Next = nullptr;
1236 while (true) {
1237 size_t NameLen;
1238 const char *Name = LLVMGetValueName2(Val: Cur, Length: &NameLen);
1239 if (LLVMGetNamedFunction(M, Name))
1240 report_fatal_error(reason: "Function already cloned");
1241 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: LLVMGlobalGetValueType(Global: Cur));
1242
1243 auto F = LLVMAddFunction(M, Name, FunctionTy: Ty);
1244
1245 // Copy attributes
1246 for (int i = LLVMAttributeFunctionIndex, c = LLVMCountParams(Fn: F);
1247 i <= c; ++i) {
1248 for (unsigned k = 0, e = LLVMGetLastEnumAttributeKind(); k < e; ++k) {
1249 if (auto SrcA = LLVMGetEnumAttributeAtIndex(F: Cur, Idx: i, KindID: k)) {
1250 auto Val = LLVMGetEnumAttributeValue(A: SrcA);
1251 auto DstA = LLVMCreateEnumAttribute(C: Ctx, KindID: k, Val);
1252 LLVMAddAttributeAtIndex(F, Idx: i, A: DstA);
1253 }
1254 }
1255 }
1256
1257 Next = LLVMGetNextFunction(Fn: Cur);
1258 if (Next == nullptr) {
1259 if (Cur != End)
1260 report_fatal_error(reason: "Last function does not match End");
1261 break;
1262 }
1263
1264 LLVMValueRef Prev = LLVMGetPreviousFunction(Fn: Next);
1265 if (Prev != Cur)
1266 report_fatal_error(reason: "Next.Previous function is not Current");
1267
1268 Cur = Next;
1269 }
1270
1271AliasDecl:
1272 Begin = LLVMGetFirstGlobalAlias(M: Src);
1273 End = LLVMGetLastGlobalAlias(M: Src);
1274 if (!Begin) {
1275 if (End != nullptr)
1276 report_fatal_error(reason: "Range has an end but no beginning");
1277 goto GlobalIFuncDecl;
1278 }
1279
1280 Cur = Begin;
1281 Next = nullptr;
1282 while (true) {
1283 size_t NameLen;
1284 const char *Name = LLVMGetValueName2(Val: Cur, Length: &NameLen);
1285 if (LLVMGetNamedGlobalAlias(M, Name, NameLen))
1286 report_fatal_error(reason: "Global alias already cloned");
1287 LLVMTypeRef PtrType = TypeCloner(M).Clone(Src: Cur);
1288 LLVMTypeRef ValType = TypeCloner(M).Clone(Src: LLVMGlobalGetValueType(Global: Cur));
1289 unsigned AddrSpace = LLVMGetPointerAddressSpace(PointerTy: PtrType);
1290 // FIXME: Allow NULL aliasee.
1291 LLVMAddAlias2(M, ValueTy: ValType, AddrSpace, Aliasee: LLVMGetUndef(Ty: PtrType), Name);
1292
1293 Next = LLVMGetNextGlobalAlias(GA: Cur);
1294 if (Next == nullptr) {
1295 if (Cur != End)
1296 report_fatal_error(reason: "");
1297 break;
1298 }
1299
1300 LLVMValueRef Prev = LLVMGetPreviousGlobalAlias(GA: Next);
1301 if (Prev != Cur)
1302 report_fatal_error(reason: "Next.Previous global is not Current");
1303
1304 Cur = Next;
1305 }
1306
1307GlobalIFuncDecl:
1308 Begin = LLVMGetFirstGlobalIFunc(M: Src);
1309 End = LLVMGetLastGlobalIFunc(M: Src);
1310 if (!Begin) {
1311 if (End != nullptr)
1312 report_fatal_error(reason: "Range has an end but no beginning");
1313 goto NamedMDDecl;
1314 }
1315
1316 Cur = Begin;
1317 Next = nullptr;
1318 while (true) {
1319 size_t NameLen;
1320 const char *Name = LLVMGetValueName2(Val: Cur, Length: &NameLen);
1321 if (LLVMGetNamedGlobalIFunc(M, Name, NameLen))
1322 report_fatal_error(reason: "Global ifunc already cloned");
1323 LLVMTypeRef CurType = TypeCloner(M).Clone(Src: LLVMGlobalGetValueType(Global: Cur));
1324 // FIXME: Allow NULL resolver.
1325 LLVMAddGlobalIFunc(M, Name, NameLen,
1326 Ty: CurType, /*addressSpace*/ AddrSpace: 0, Resolver: LLVMGetUndef(Ty: CurType));
1327
1328 Next = LLVMGetNextGlobalIFunc(IFunc: Cur);
1329 if (Next == nullptr) {
1330 if (Cur != End)
1331 report_fatal_error(reason: "");
1332 break;
1333 }
1334
1335 LLVMValueRef Prev = LLVMGetPreviousGlobalIFunc(IFunc: Next);
1336 if (Prev != Cur)
1337 report_fatal_error(reason: "Next.Previous global is not Current");
1338
1339 Cur = Next;
1340 }
1341
1342NamedMDDecl:
1343 LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(M: Src);
1344 LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(M: Src);
1345 if (!BeginMD) {
1346 if (EndMD != nullptr)
1347 report_fatal_error(reason: "Range has an end but no beginning");
1348 return;
1349 }
1350
1351 LLVMNamedMDNodeRef CurMD = BeginMD;
1352 LLVMNamedMDNodeRef NextMD = nullptr;
1353 while (true) {
1354 size_t NameLen;
1355 const char *Name = LLVMGetNamedMetadataName(NamedMD: CurMD, NameLen: &NameLen);
1356 if (LLVMGetNamedMetadata(M, Name, NameLen))
1357 report_fatal_error(reason: "Named Metadata Node already cloned");
1358 LLVMGetOrInsertNamedMetadata(M, Name, NameLen);
1359
1360 NextMD = LLVMGetNextNamedMetadata(NamedMDNode: CurMD);
1361 if (NextMD == nullptr) {
1362 if (CurMD != EndMD)
1363 report_fatal_error(reason: "");
1364 break;
1365 }
1366
1367 LLVMNamedMDNodeRef PrevMD = LLVMGetPreviousNamedMetadata(NamedMDNode: NextMD);
1368 if (PrevMD != CurMD)
1369 report_fatal_error(reason: "Next.Previous global is not Current");
1370
1371 CurMD = NextMD;
1372 }
1373}
1374
1375static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
1376 LLVMValueRef Begin = LLVMGetFirstGlobal(M: Src);
1377 LLVMValueRef End = LLVMGetLastGlobal(M: Src);
1378
1379 LLVMValueRef Cur = Begin;
1380 LLVMValueRef Next = nullptr;
1381 if (!Begin) {
1382 if (End != nullptr)
1383 report_fatal_error(reason: "Range has an end but no beginning");
1384 goto FunClone;
1385 }
1386
1387 while (true) {
1388 size_t NameLen;
1389 const char *Name = LLVMGetValueName2(Val: Cur, Length: &NameLen);
1390 LLVMValueRef G = LLVMGetNamedGlobal(M, Name);
1391 if (!G)
1392 report_fatal_error(reason: "GlobalVariable must have been declared already");
1393
1394 if (auto I = LLVMGetInitializer(GlobalVar: Cur))
1395 LLVMSetInitializer(GlobalVar: G, ConstantVal: clone_constant(Cst: I, M));
1396
1397 size_t NumMetadataEntries;
1398 auto *AllMetadata = LLVMGlobalCopyAllMetadata(Value: Cur, NumEntries: &NumMetadataEntries);
1399 for (unsigned i = 0; i < NumMetadataEntries; ++i) {
1400 unsigned Kind = LLVMValueMetadataEntriesGetKind(Entries: AllMetadata, Index: i);
1401 LLVMMetadataRef MD = LLVMValueMetadataEntriesGetMetadata(Entries: AllMetadata, Index: i);
1402 LLVMGlobalSetMetadata(Global: G, Kind, MD);
1403 }
1404 LLVMDisposeValueMetadataEntries(Entries: AllMetadata);
1405
1406 LLVMSetGlobalConstant(GlobalVar: G, IsConstant: LLVMIsGlobalConstant(GlobalVar: Cur));
1407 LLVMSetThreadLocal(GlobalVar: G, IsThreadLocal: LLVMIsThreadLocal(GlobalVar: Cur));
1408 LLVMSetExternallyInitialized(GlobalVar: G, IsExtInit: LLVMIsExternallyInitialized(GlobalVar: Cur));
1409 LLVMSetLinkage(Global: G, Linkage: LLVMGetLinkage(Global: Cur));
1410 LLVMSetSection(Global: G, Section: LLVMGetSection(Global: Cur));
1411 LLVMSetVisibility(Global: G, Viz: LLVMGetVisibility(Global: Cur));
1412 LLVMSetUnnamedAddress(Global: G, UnnamedAddr: LLVMGetUnnamedAddress(Global: Cur));
1413 LLVMSetAlignment(V: G, Bytes: LLVMGetAlignment(V: Cur));
1414
1415 Next = LLVMGetNextGlobal(GlobalVar: Cur);
1416 if (Next == nullptr) {
1417 if (Cur != End)
1418 report_fatal_error(reason: "");
1419 break;
1420 }
1421
1422 LLVMValueRef Prev = LLVMGetPreviousGlobal(GlobalVar: Next);
1423 if (Prev != Cur)
1424 report_fatal_error(reason: "Next.Previous global is not Current");
1425
1426 Cur = Next;
1427 }
1428
1429FunClone:
1430 Begin = LLVMGetFirstFunction(M: Src);
1431 End = LLVMGetLastFunction(M: Src);
1432 if (!Begin) {
1433 if (End != nullptr)
1434 report_fatal_error(reason: "Range has an end but no beginning");
1435 goto AliasClone;
1436 }
1437
1438 Cur = Begin;
1439 Next = nullptr;
1440 while (true) {
1441 size_t NameLen;
1442 const char *Name = LLVMGetValueName2(Val: Cur, Length: &NameLen);
1443 LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
1444 if (!Fun)
1445 report_fatal_error(reason: "Function must have been declared already");
1446
1447 if (LLVMHasPersonalityFn(Fn: Cur)) {
1448 size_t FNameLen;
1449 const char *FName = LLVMGetValueName2(Val: LLVMGetPersonalityFn(Fn: Cur),
1450 Length: &FNameLen);
1451 LLVMValueRef P = LLVMGetNamedFunction(M, Name: FName);
1452 if (!P)
1453 report_fatal_error(reason: "Could not find personality function");
1454 LLVMSetPersonalityFn(Fn: Fun, PersonalityFn: P);
1455 }
1456
1457 size_t NumMetadataEntries;
1458 auto *AllMetadata = LLVMGlobalCopyAllMetadata(Value: Cur, NumEntries: &NumMetadataEntries);
1459 for (unsigned i = 0; i < NumMetadataEntries; ++i) {
1460 unsigned Kind = LLVMValueMetadataEntriesGetKind(Entries: AllMetadata, Index: i);
1461 LLVMMetadataRef MD = LLVMValueMetadataEntriesGetMetadata(Entries: AllMetadata, Index: i);
1462 LLVMGlobalSetMetadata(Global: Fun, Kind, MD);
1463 }
1464 LLVMDisposeValueMetadataEntries(Entries: AllMetadata);
1465
1466 // Copy any prefix data that may be on the function
1467 if (LLVMHasPrefixData(Fn: Cur))
1468 LLVMSetPrefixData(Fn: Fun, prefixData: clone_constant(Cst: LLVMGetPrefixData(Fn: Cur), M));
1469
1470 // Copy any prologue data that may be on the function
1471 if (LLVMHasPrologueData(Fn: Cur))
1472 LLVMSetPrologueData(Fn: Fun, prologueData: clone_constant(Cst: LLVMGetPrologueData(Fn: Cur), M));
1473
1474 FunCloner FC(Cur, Fun);
1475 FC.CloneBBs(Src: Cur);
1476
1477 Next = LLVMGetNextFunction(Fn: Cur);
1478 if (Next == nullptr) {
1479 if (Cur != End)
1480 report_fatal_error(reason: "Last function does not match End");
1481 break;
1482 }
1483
1484 LLVMValueRef Prev = LLVMGetPreviousFunction(Fn: Next);
1485 if (Prev != Cur)
1486 report_fatal_error(reason: "Next.Previous function is not Current");
1487
1488 Cur = Next;
1489 }
1490
1491AliasClone:
1492 Begin = LLVMGetFirstGlobalAlias(M: Src);
1493 End = LLVMGetLastGlobalAlias(M: Src);
1494 if (!Begin) {
1495 if (End != nullptr)
1496 report_fatal_error(reason: "Range has an end but no beginning");
1497 goto GlobalIFuncClone;
1498 }
1499
1500 Cur = Begin;
1501 Next = nullptr;
1502 while (true) {
1503 size_t NameLen;
1504 const char *Name = LLVMGetValueName2(Val: Cur, Length: &NameLen);
1505 LLVMValueRef Alias = LLVMGetNamedGlobalAlias(M, Name, NameLen);
1506 if (!Alias)
1507 report_fatal_error(reason: "Global alias must have been declared already");
1508
1509 if (LLVMValueRef Aliasee = LLVMAliasGetAliasee(Alias: Cur)) {
1510 LLVMAliasSetAliasee(Alias, Aliasee: clone_constant(Cst: Aliasee, M));
1511 }
1512
1513 LLVMSetLinkage(Global: Alias, Linkage: LLVMGetLinkage(Global: Cur));
1514 LLVMSetUnnamedAddress(Global: Alias, UnnamedAddr: LLVMGetUnnamedAddress(Global: Cur));
1515
1516 Next = LLVMGetNextGlobalAlias(GA: Cur);
1517 if (Next == nullptr) {
1518 if (Cur != End)
1519 report_fatal_error(reason: "Last global alias does not match End");
1520 break;
1521 }
1522
1523 LLVMValueRef Prev = LLVMGetPreviousGlobalAlias(GA: Next);
1524 if (Prev != Cur)
1525 report_fatal_error(reason: "Next.Previous global alias is not Current");
1526
1527 Cur = Next;
1528 }
1529
1530GlobalIFuncClone:
1531 Begin = LLVMGetFirstGlobalIFunc(M: Src);
1532 End = LLVMGetLastGlobalIFunc(M: Src);
1533 if (!Begin) {
1534 if (End != nullptr)
1535 report_fatal_error(reason: "Range has an end but no beginning");
1536 goto NamedMDClone;
1537 }
1538
1539 Cur = Begin;
1540 Next = nullptr;
1541 while (true) {
1542 size_t NameLen;
1543 const char *Name = LLVMGetValueName2(Val: Cur, Length: &NameLen);
1544 LLVMValueRef IFunc = LLVMGetNamedGlobalIFunc(M, Name, NameLen);
1545 if (!IFunc)
1546 report_fatal_error(reason: "Global ifunc must have been declared already");
1547
1548 if (LLVMValueRef Resolver = LLVMGetGlobalIFuncResolver(IFunc: Cur)) {
1549 LLVMSetGlobalIFuncResolver(IFunc, Resolver: clone_constant(Cst: Resolver, M));
1550 }
1551
1552 LLVMSetLinkage(Global: IFunc, Linkage: LLVMGetLinkage(Global: Cur));
1553 LLVMSetUnnamedAddress(Global: IFunc, UnnamedAddr: LLVMGetUnnamedAddress(Global: Cur));
1554
1555 Next = LLVMGetNextGlobalIFunc(IFunc: Cur);
1556 if (Next == nullptr) {
1557 if (Cur != End)
1558 report_fatal_error(reason: "Last global alias does not match End");
1559 break;
1560 }
1561
1562 LLVMValueRef Prev = LLVMGetPreviousGlobalIFunc(IFunc: Next);
1563 if (Prev != Cur)
1564 report_fatal_error(reason: "Next.Previous global alias is not Current");
1565
1566 Cur = Next;
1567 }
1568
1569NamedMDClone:
1570 LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(M: Src);
1571 LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(M: Src);
1572 if (!BeginMD) {
1573 if (EndMD != nullptr)
1574 report_fatal_error(reason: "Range has an end but no beginning");
1575 return;
1576 }
1577
1578 LLVMNamedMDNodeRef CurMD = BeginMD;
1579 LLVMNamedMDNodeRef NextMD = nullptr;
1580 while (true) {
1581 size_t NameLen;
1582 const char *Name = LLVMGetNamedMetadataName(NamedMD: CurMD, NameLen: &NameLen);
1583 LLVMNamedMDNodeRef NamedMD = LLVMGetNamedMetadata(M, Name, NameLen);
1584 if (!NamedMD)
1585 report_fatal_error(reason: "Named MD Node must have been declared already");
1586
1587 unsigned OperandCount = LLVMGetNamedMetadataNumOperands(M: Src, Name);
1588 LLVMValueRef *OperandBuf = static_cast<LLVMValueRef *>(
1589 safe_malloc(Sz: OperandCount * sizeof(LLVMValueRef)));
1590 LLVMGetNamedMetadataOperands(M: Src, Name, Dest: OperandBuf);
1591 for (unsigned i = 0, e = OperandCount; i != e; ++i) {
1592 LLVMAddNamedMetadataOperand(M, Name, Val: OperandBuf[i]);
1593 }
1594 free(ptr: OperandBuf);
1595
1596 NextMD = LLVMGetNextNamedMetadata(NamedMDNode: CurMD);
1597 if (NextMD == nullptr) {
1598 if (CurMD != EndMD)
1599 report_fatal_error(reason: "Last Named MD Node does not match End");
1600 break;
1601 }
1602
1603 LLVMNamedMDNodeRef PrevMD = LLVMGetPreviousNamedMetadata(NamedMDNode: NextMD);
1604 if (PrevMD != CurMD)
1605 report_fatal_error(reason: "Next.Previous Named MD Node is not Current");
1606
1607 CurMD = NextMD;
1608 }
1609}
1610
1611int llvm_echo(void) {
1612 LLVMEnablePrettyStackTrace();
1613
1614 LLVMModuleRef Src = llvm_load_module(Lazy: false, New: true);
1615 size_t SourceFileLen;
1616 const char *SourceFileName = LLVMGetSourceFileName(M: Src, Len: &SourceFileLen);
1617 size_t ModuleIdentLen;
1618 const char *ModuleName = LLVMGetModuleIdentifier(M: Src, Len: &ModuleIdentLen);
1619 LLVMContextRef Ctx = LLVMContextCreate();
1620 LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleID: ModuleName, C: Ctx);
1621
1622 LLVMSetSourceFileName(M, Name: SourceFileName, Len: SourceFileLen);
1623 LLVMSetModuleIdentifier(M, Ident: ModuleName, Len: ModuleIdentLen);
1624
1625 LLVMSetTarget(M, Triple: LLVMGetTarget(M: Src));
1626 LLVMSetModuleDataLayout(M, DL: LLVMGetModuleDataLayout(M: Src));
1627 if (strcmp(s1: LLVMGetDataLayoutStr(M), s2: LLVMGetDataLayoutStr(M: Src)))
1628 report_fatal_error(reason: "Inconsistent DataLayout string representation");
1629
1630 size_t ModuleInlineAsmLen;
1631 const char *ModuleAsm = LLVMGetModuleInlineAsm(M: Src, Len: &ModuleInlineAsmLen);
1632 LLVMSetModuleInlineAsm2(M, Asm: ModuleAsm, Len: ModuleInlineAsmLen);
1633
1634 declare_symbols(Src, M);
1635 clone_symbols(Src, M);
1636 char *Str = LLVMPrintModuleToString(M);
1637 fputs(s: Str, stdout);
1638
1639 LLVMDisposeMessage(Message: Str);
1640 LLVMDisposeModule(M: Src);
1641 LLVMDisposeModule(M);
1642 LLVMContextDispose(C: Ctx);
1643
1644 return 0;
1645}
1646