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