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