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