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