1//===-- echo.cpp - tool for testing libLLVM and llvm-c API ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the --echo command in llvm-c-test.
10//
11// This command uses the C API to read a module and output an exact copy of it
12// as output. It is used to check that the resulting module matches the input
13// to validate that the C API can read and write modules properly.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm-c-test.h"
18#include "llvm-c/DebugInfo.h"
19#include "llvm-c/ErrorHandling.h"
20#include "llvm-c/Target.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/Hashing.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/Support/ErrorHandling.h"
25
26#include <stdio.h>
27#include <stdlib.h>
28
29using namespace llvm;
30
31// Provide DenseMapInfo for C API opaque types.
32template<typename T>
33struct CAPIDenseMap {};
34
35// The default DenseMapInfo require to know about pointer alignment.
36// Because the C API uses opaque pointer types, their alignment is unknown.
37// As a result, we need to roll out our own implementation.
38template<typename T>
39struct CAPIDenseMap<T*> {
40 struct CAPIDenseMapInfo {
41 static inline T* getEmptyKey() {
42 uintptr_t Val = static_cast<uintptr_t>(-1);
43 return reinterpret_cast<T*>(Val);
44 }
45 static inline T* getTombstoneKey() {
46 uintptr_t Val = static_cast<uintptr_t>(-2);
47 return reinterpret_cast<T*>(Val);
48 }
49 static unsigned getHashValue(const T *PtrVal) {
50 return hash_value(PtrVal);
51 }
52 static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
53 };
54
55 typedef DenseMap<T*, T*, CAPIDenseMapInfo> Map;
56};
57
58typedef CAPIDenseMap<LLVMValueRef>::Map ValueMap;
59typedef CAPIDenseMap<LLVMBasicBlockRef>::Map BasicBlockMap;
60
61struct TypeCloner {
62 LLVMModuleRef M;
63 LLVMContextRef Ctx;
64
65 TypeCloner(LLVMModuleRef M): M(M), Ctx(LLVMGetModuleContext(M)) {}
66
67 LLVMTypeRef Clone(LLVMValueRef Src) {
68 return Clone(Src: LLVMTypeOf(Val: Src));
69 }
70
71 LLVMTypeRef Clone(LLVMTypeRef Src) {
72 LLVMTypeKind Kind = LLVMGetTypeKind(Ty: Src);
73 switch (Kind) {
74 case LLVMVoidTypeKind:
75 return LLVMVoidTypeInContext(C: Ctx);
76 case LLVMHalfTypeKind:
77 return LLVMHalfTypeInContext(C: Ctx);
78 case LLVMBFloatTypeKind:
79 return LLVMHalfTypeInContext(C: Ctx);
80 case LLVMFloatTypeKind:
81 return LLVMFloatTypeInContext(C: Ctx);
82 case LLVMDoubleTypeKind:
83 return LLVMDoubleTypeInContext(C: Ctx);
84 case LLVMX86_FP80TypeKind:
85 return LLVMX86FP80TypeInContext(C: Ctx);
86 case LLVMFP128TypeKind:
87 return LLVMFP128TypeInContext(C: Ctx);
88 case LLVMPPC_FP128TypeKind:
89 return LLVMPPCFP128TypeInContext(C: Ctx);
90 case LLVMLabelTypeKind:
91 return LLVMLabelTypeInContext(C: Ctx);
92 case LLVMIntegerTypeKind:
93 return LLVMIntTypeInContext(C: Ctx, NumBits: LLVMGetIntTypeWidth(IntegerTy: Src));
94 case LLVMFunctionTypeKind: {
95 unsigned ParamCount = LLVMCountParamTypes(FunctionTy: Src);
96 LLVMTypeRef* Params = nullptr;
97 if (ParamCount > 0) {
98 Params = static_cast<LLVMTypeRef*>(
99 safe_malloc(Sz: ParamCount * sizeof(LLVMTypeRef)));
100 LLVMGetParamTypes(FunctionTy: Src, Dest: Params);
101 for (unsigned i = 0; i < ParamCount; i++)
102 Params[i] = Clone(Src: Params[i]);
103 }
104
105 LLVMTypeRef FunTy = LLVMFunctionType(ReturnType: Clone(Src: LLVMGetReturnType(FunctionTy: Src)),
106 ParamTypes: Params, ParamCount,
107 IsVarArg: LLVMIsFunctionVarArg(FunctionTy: Src));
108 if (ParamCount > 0)
109 free(ptr: Params);
110 return FunTy;
111 }
112 case LLVMStructTypeKind: {
113 LLVMTypeRef S = nullptr;
114 const char *Name = LLVMGetStructName(Ty: Src);
115 if (Name) {
116 S = LLVMGetTypeByName2(C: Ctx, Name);
117 if (S)
118 return S;
119 S = LLVMStructCreateNamed(C: Ctx, Name);
120 if (LLVMIsOpaqueStruct(StructTy: Src))
121 return S;
122 }
123
124 unsigned EltCount = LLVMCountStructElementTypes(StructTy: Src);
125 SmallVector<LLVMTypeRef, 8> Elts;
126 for (unsigned i = 0; i < EltCount; i++)
127 Elts.push_back(Elt: Clone(Src: LLVMStructGetTypeAtIndex(StructTy: Src, i)));
128 if (Name)
129 LLVMStructSetBody(StructTy: S, ElementTypes: Elts.data(), ElementCount: EltCount, Packed: LLVMIsPackedStruct(StructTy: Src));
130 else
131 S = LLVMStructTypeInContext(C: Ctx, ElementTypes: Elts.data(), ElementCount: EltCount,
132 Packed: LLVMIsPackedStruct(StructTy: Src));
133 return S;
134 }
135 case LLVMArrayTypeKind:
136 return LLVMArrayType2(ElementType: Clone(Src: LLVMGetElementType(Ty: Src)),
137 ElementCount: LLVMGetArrayLength2(ArrayTy: Src));
138 case LLVMPointerTypeKind:
139 if (LLVMPointerTypeIsOpaque(Ty: Src))
140 return LLVMPointerTypeInContext(C: Ctx, AddressSpace: LLVMGetPointerAddressSpace(PointerTy: Src));
141 else
142 return LLVMPointerType(ElementType: Clone(Src: LLVMGetElementType(Ty: Src)),
143 AddressSpace: LLVMGetPointerAddressSpace(PointerTy: Src));
144 case LLVMVectorTypeKind:
145 return LLVMVectorType(
146 ElementType: Clone(Src: LLVMGetElementType(Ty: Src)),
147 ElementCount: LLVMGetVectorSize(VectorTy: Src)
148 );
149 case LLVMScalableVectorTypeKind:
150 return LLVMScalableVectorType(ElementType: Clone(Src: LLVMGetElementType(Ty: Src)),
151 ElementCount: LLVMGetVectorSize(VectorTy: Src));
152 case LLVMMetadataTypeKind:
153 return LLVMMetadataTypeInContext(C: Ctx);
154 case LLVMX86_AMXTypeKind:
155 return LLVMX86AMXTypeInContext(C: Ctx);
156 case LLVMTokenTypeKind:
157 return LLVMTokenTypeInContext(C: Ctx);
158 case LLVMTargetExtTypeKind: {
159 const char *Name = LLVMGetTargetExtTypeName(TargetExtTy: Src);
160 unsigned NumTypeParams = LLVMGetTargetExtTypeNumTypeParams(TargetExtTy: Src);
161 unsigned NumIntParams = LLVMGetTargetExtTypeNumIntParams(TargetExtTy: Src);
162
163 SmallVector<LLVMTypeRef, 4> TypeParams((size_t)NumTypeParams);
164 SmallVector<unsigned, 4> IntParams((size_t)NumIntParams);
165
166 for (unsigned i = 0; i < TypeParams.size(); i++)
167 TypeParams[i] = Clone(Src: LLVMGetTargetExtTypeTypeParam(TargetExtTy: Src, Idx: i));
168
169 for (unsigned i = 0; i < IntParams.size(); i++)
170 IntParams[i] = LLVMGetTargetExtTypeIntParam(TargetExtTy: Src, Idx: i);
171
172 LLVMTypeRef TargetExtTy = LLVMTargetExtTypeInContext(
173 C: Ctx, Name, TypeParams: TypeParams.data(), TypeParamCount: TypeParams.size(), IntParams: IntParams.data(),
174 IntParamCount: IntParams.size());
175
176 return TargetExtTy;
177 }
178 }
179
180 fprintf(stderr, format: "%d is not a supported typekind\n", Kind);
181 exit(status: -1);
182 }
183};
184
185static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst) {
186 unsigned Count = LLVMCountParams(Fn: Src);
187 if (Count != LLVMCountParams(Fn: Dst))
188 report_fatal_error(reason: "Parameter count mismatch");
189
190 ValueMap VMap;
191 if (Count == 0)
192 return VMap;
193
194 LLVMValueRef SrcFirst = LLVMGetFirstParam(Fn: Src);
195 LLVMValueRef DstFirst = LLVMGetFirstParam(Fn: Dst);
196 LLVMValueRef SrcLast = LLVMGetLastParam(Fn: Src);
197 LLVMValueRef DstLast = LLVMGetLastParam(Fn: Dst);
198
199 LLVMValueRef SrcCur = SrcFirst;
200 LLVMValueRef DstCur = DstFirst;
201 LLVMValueRef SrcNext = nullptr;
202 LLVMValueRef DstNext = nullptr;
203 while (true) {
204 size_t NameLen;
205 const char *Name = LLVMGetValueName2(Val: SrcCur, Length: &NameLen);
206 LLVMSetValueName2(Val: DstCur, Name, NameLen);
207
208 VMap[SrcCur] = DstCur;
209
210 Count--;
211 SrcNext = LLVMGetNextParam(Arg: SrcCur);
212 DstNext = LLVMGetNextParam(Arg: DstCur);
213 if (SrcNext == nullptr && DstNext == nullptr) {
214 if (SrcCur != SrcLast)
215 report_fatal_error(reason: "SrcLast param does not match End");
216 if (DstCur != DstLast)
217 report_fatal_error(reason: "DstLast param does not match End");
218 break;
219 }
220
221 if (SrcNext == nullptr)
222 report_fatal_error(reason: "SrcNext was unexpectedly null");
223 if (DstNext == nullptr)
224 report_fatal_error(reason: "DstNext was unexpectedly null");
225
226 LLVMValueRef SrcPrev = LLVMGetPreviousParam(Arg: SrcNext);
227 if (SrcPrev != SrcCur)
228 report_fatal_error(reason: "SrcNext.Previous param is not Current");
229
230 LLVMValueRef DstPrev = LLVMGetPreviousParam(Arg: DstNext);
231 if (DstPrev != DstCur)
232 report_fatal_error(reason: "DstNext.Previous param is not Current");
233
234 SrcCur = SrcNext;
235 DstCur = DstNext;
236 }
237
238 if (Count != 0)
239 report_fatal_error(reason: "Parameter count does not match iteration");
240
241 return VMap;
242}
243
244static void check_value_kind(LLVMValueRef V, LLVMValueKind K) {
245 if (LLVMGetValueKind(Val: V) != K)
246 report_fatal_error(reason: "LLVMGetValueKind returned incorrect type");
247}
248
249static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M);
250
251static LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) {
252 LLVMValueRef Ret = clone_constant_impl(Cst, M);
253 check_value_kind(V: Ret, K: LLVMGetValueKind(Val: Cst));
254 return Ret;
255}
256
257static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) {
258 if (!LLVMIsAConstant(Val: Cst))
259 report_fatal_error(reason: "Expected a constant");
260
261 // Maybe it is a symbol
262 if (LLVMIsAGlobalValue(Val: Cst)) {
263 size_t NameLen;
264 const char *Name = LLVMGetValueName2(Val: Cst, Length: &NameLen);
265
266 // Try function
267 if (LLVMIsAFunction(Val: Cst)) {
268 check_value_kind(V: Cst, K: LLVMFunctionValueKind);
269
270 LLVMValueRef Dst = nullptr;
271 // Try an intrinsic
272 unsigned ID = LLVMGetIntrinsicID(Fn: Cst);
273 if (ID > 0 && !LLVMIntrinsicIsOverloaded(ID)) {
274 Dst = LLVMGetIntrinsicDeclaration(Mod: M, ID, ParamTypes: nullptr, ParamCount: 0);
275 } else {
276 // Try a normal function
277 Dst = LLVMGetNamedFunction(M, Name);
278 }
279
280 if (Dst)
281 return Dst;
282 report_fatal_error(reason: "Could not find function");
283 }
284
285 // Try global variable
286 if (LLVMIsAGlobalVariable(Val: Cst)) {
287 check_value_kind(V: Cst, K: LLVMGlobalVariableValueKind);
288 LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name);
289 if (Dst)
290 return Dst;
291 report_fatal_error(reason: "Could not find variable");
292 }
293
294 // Try global alias
295 if (LLVMIsAGlobalAlias(Val: Cst)) {
296 check_value_kind(V: Cst, K: LLVMGlobalAliasValueKind);
297 LLVMValueRef Dst = LLVMGetNamedGlobalAlias(M, Name, NameLen);
298 if (Dst)
299 return Dst;
300 report_fatal_error(reason: "Could not find alias");
301 }
302
303 fprintf(stderr, format: "Could not find @%s\n", Name);
304 exit(status: -1);
305 }
306
307 // Try integer literal
308 if (LLVMIsAConstantInt(Val: Cst)) {
309 check_value_kind(V: Cst, K: LLVMConstantIntValueKind);
310 return LLVMConstInt(IntTy: TypeCloner(M).Clone(Src: Cst),
311 N: LLVMConstIntGetZExtValue(ConstantVal: Cst), SignExtend: false);
312 }
313
314 // Try zeroinitializer
315 if (LLVMIsAConstantAggregateZero(Val: Cst)) {
316 check_value_kind(V: Cst, K: LLVMConstantAggregateZeroValueKind);
317 return LLVMConstNull(Ty: TypeCloner(M).Clone(Src: Cst));
318 }
319
320 // Try constant data array
321 if (LLVMIsAConstantDataArray(Val: Cst)) {
322 check_value_kind(V: Cst, K: LLVMConstantDataArrayValueKind);
323 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: Cst);
324 size_t SizeInBytes;
325 const char *Data = LLVMGetRawDataValues(c: Cst, SizeInBytes: &SizeInBytes);
326 return LLVMConstDataArray(ElementTy: LLVMGetElementType(Ty), Data, SizeInBytes);
327 }
328
329 // Try constant array
330 if (LLVMIsAConstantArray(Val: Cst)) {
331 check_value_kind(V: Cst, K: LLVMConstantArrayValueKind);
332 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: Cst);
333 uint64_t EltCount = LLVMGetArrayLength2(ArrayTy: Ty);
334 SmallVector<LLVMValueRef, 8> Elts;
335 for (uint64_t i = 0; i < EltCount; i++)
336 Elts.push_back(Elt: clone_constant(Cst: LLVMGetAggregateElement(C: Cst, Idx: i), M));
337 return LLVMConstArray(ElementTy: LLVMGetElementType(Ty), ConstantVals: Elts.data(), Length: EltCount);
338 }
339
340 // Try constant struct
341 if (LLVMIsAConstantStruct(Val: Cst)) {
342 check_value_kind(V: Cst, K: LLVMConstantStructValueKind);
343 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: Cst);
344 unsigned EltCount = LLVMCountStructElementTypes(StructTy: Ty);
345 SmallVector<LLVMValueRef, 8> Elts;
346 for (unsigned i = 0; i < EltCount; i++)
347 Elts.push_back(Elt: clone_constant(Cst: LLVMGetOperand(Val: Cst, Index: i), M));
348 if (LLVMGetStructName(Ty))
349 return LLVMConstNamedStruct(StructTy: Ty, ConstantVals: Elts.data(), Count: EltCount);
350 return LLVMConstStructInContext(C: LLVMGetModuleContext(M), ConstantVals: Elts.data(),
351 Count: EltCount, Packed: LLVMIsPackedStruct(StructTy: Ty));
352 }
353
354 // Try ConstantPointerNull
355 if (LLVMIsAConstantPointerNull(Val: Cst)) {
356 check_value_kind(V: Cst, K: LLVMConstantPointerNullValueKind);
357 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: Cst);
358 return LLVMConstNull(Ty);
359 }
360
361 // Try undef
362 if (LLVMIsUndef(Val: Cst)) {
363 check_value_kind(V: Cst, K: LLVMUndefValueValueKind);
364 return LLVMGetUndef(Ty: TypeCloner(M).Clone(Src: Cst));
365 }
366
367 // Try poison
368 if (LLVMIsPoison(Val: Cst)) {
369 check_value_kind(V: Cst, K: LLVMPoisonValueValueKind);
370 return LLVMGetPoison(Ty: TypeCloner(M).Clone(Src: Cst));
371 }
372
373 // Try null
374 if (LLVMIsNull(Val: Cst)) {
375 check_value_kind(V: Cst, K: LLVMConstantTokenNoneValueKind);
376 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: Cst);
377 return LLVMConstNull(Ty);
378 }
379
380 // Try float literal
381 if (LLVMIsAConstantFP(Val: Cst)) {
382 check_value_kind(V: Cst, K: LLVMConstantFPValueKind);
383 report_fatal_error(reason: "ConstantFP is not supported");
384 }
385
386 // Try ConstantVector or ConstantDataVector
387 if (LLVMIsAConstantVector(Val: Cst) || LLVMIsAConstantDataVector(Val: Cst)) {
388 check_value_kind(V: Cst, K: LLVMIsAConstantVector(Val: Cst)
389 ? LLVMConstantVectorValueKind
390 : LLVMConstantDataVectorValueKind);
391 LLVMTypeRef Ty = TypeCloner(M).Clone(Src: Cst);
392 unsigned EltCount = LLVMGetVectorSize(VectorTy: Ty);
393 SmallVector<LLVMValueRef, 8> Elts;
394 for (unsigned i = 0; i < EltCount; i++)
395 Elts.push_back(Elt: clone_constant(Cst: LLVMGetAggregateElement(C: Cst, Idx: i), M));
396 return LLVMConstVector(ScalarConstantVals: Elts.data(), Size: EltCount);
397 }
398
399 if (LLVMIsAConstantPtrAuth(Val: Cst)) {
400 LLVMValueRef Ptr = clone_constant(Cst: LLVMGetConstantPtrAuthPointer(PtrAuth: Cst), M);
401 LLVMValueRef Key = clone_constant(Cst: LLVMGetConstantPtrAuthKey(PtrAuth: Cst), M);
402 LLVMValueRef Disc =
403 clone_constant(Cst: LLVMGetConstantPtrAuthDiscriminator(PtrAuth: Cst), M);
404 LLVMValueRef AddrDisc =
405 clone_constant(Cst: LLVMGetConstantPtrAuthAddrDiscriminator(PtrAuth: Cst), M);
406 return LLVMConstantPtrAuth(Ptr, Key, Disc, AddrDisc);
407 }
408
409 // At this point, if it's not a constant expression, it's a kind of constant
410 // which is not supported
411 if (!LLVMIsAConstantExpr(Val: Cst))
412 report_fatal_error(reason: "Unsupported constant kind");
413
414 // At this point, it must be a constant expression
415 check_value_kind(V: Cst, K: LLVMConstantExprValueKind);
416
417 LLVMOpcode Op = LLVMGetConstOpcode(ConstantVal: Cst);
418 switch(Op) {
419 case LLVMBitCast:
420 return LLVMConstBitCast(ConstantVal: clone_constant(Cst: LLVMGetOperand(Val: Cst, Index: 0), M),
421 ToType: TypeCloner(M).Clone(Src: Cst));
422 case LLVMGetElementPtr: {
423 LLVMTypeRef ElemTy =
424 TypeCloner(M).Clone(Src: LLVMGetGEPSourceElementType(GEP: Cst));
425 LLVMValueRef Ptr = clone_constant(Cst: LLVMGetOperand(Val: Cst, Index: 0), M);
426 int NumIdx = LLVMGetNumIndices(Inst: Cst);
427 SmallVector<LLVMValueRef, 8> Idx;
428 for (int i = 1; i <= NumIdx; i++)
429 Idx.push_back(Elt: clone_constant(Cst: LLVMGetOperand(Val: Cst, Index: i), M));
430
431 return LLVMConstGEPWithNoWrapFlags(Ty: ElemTy, ConstantVal: Ptr, ConstantIndices: Idx.data(), NumIndices: NumIdx,
432 NoWrapFlags: LLVMGEPGetNoWrapFlags(GEP: Cst));
433 }
434 default:
435 fprintf(stderr, format: "%d is not a supported opcode for constant expressions\n",
436 Op);
437 exit(status: -1);
438 }
439}
440
441static LLVMValueRef clone_inline_asm(LLVMValueRef Asm, LLVMModuleRef M) {
442
443 if (!LLVMIsAInlineAsm(Val: Asm))
444 report_fatal_error(reason: "Expected inline assembly");
445
446 size_t AsmStringSize = 0;
447 const char *AsmString = LLVMGetInlineAsmAsmString(InlineAsmVal: Asm, Len: &AsmStringSize);
448
449 size_t ConstraintStringSize = 0;
450 const char *ConstraintString =
451 LLVMGetInlineAsmConstraintString(InlineAsmVal: Asm, Len: &ConstraintStringSize);
452
453 LLVMInlineAsmDialect AsmDialect = LLVMGetInlineAsmDialect(InlineAsmVal: Asm);
454
455 LLVMTypeRef AsmFunctionType = LLVMGetInlineAsmFunctionType(InlineAsmVal: Asm);
456
457 LLVMBool HasSideEffects = LLVMGetInlineAsmHasSideEffects(InlineAsmVal: Asm);
458 LLVMBool NeedsAlignStack = LLVMGetInlineAsmNeedsAlignedStack(InlineAsmVal: Asm);
459 LLVMBool CanUnwind = LLVMGetInlineAsmCanUnwind(InlineAsmVal: Asm);
460
461 return LLVMGetInlineAsm(Ty: AsmFunctionType, AsmString, AsmStringSize,
462 Constraints: ConstraintString, ConstraintsSize: ConstraintStringSize,
463 HasSideEffects, IsAlignStack: NeedsAlignStack, Dialect: AsmDialect,
464 CanThrow: CanUnwind);
465}
466
467struct FunCloner {
468 LLVMValueRef Fun;
469 LLVMModuleRef M;
470
471 ValueMap VMap;
472 BasicBlockMap BBMap;
473
474 FunCloner(LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst),
475 M(LLVMGetGlobalParent(Global: Fun)), VMap(clone_params(Src, Dst)) {}
476
477 LLVMTypeRef CloneType(LLVMTypeRef Src) {
478 return TypeCloner(M).Clone(Src);
479 }
480
481 LLVMTypeRef CloneType(LLVMValueRef Src) {
482 return TypeCloner(M).Clone(Src);
483 }
484
485 // Try to clone everything in the llvm::Value hierarchy.
486 LLVMValueRef CloneValue(LLVMValueRef Src) {
487 // First, the value may be constant.
488 if (LLVMIsAConstant(Val: Src))
489 return clone_constant(Cst: Src, M);
490
491 // Function argument should always be in the map already.
492 auto i = VMap.find(Val: Src);
493 if (i != VMap.end())
494 return i->second;
495
496 // Inline assembly is a Value, but not an Instruction
497 if (LLVMIsAInlineAsm(Val: Src))
498 return clone_inline_asm(Asm: Src, M);
499
500 if (!LLVMIsAInstruction(Val: Src))
501 report_fatal_error(reason: "Expected an instruction");
502
503 auto Ctx = LLVMGetModuleContext(M);
504 auto Builder = LLVMCreateBuilderInContext(C: Ctx);
505 auto BB = DeclareBB(Src: LLVMGetInstructionParent(Inst: Src));
506 LLVMPositionBuilderAtEnd(Builder, Block: BB);
507 auto Dst = CloneInstruction(Src, Builder);
508 LLVMDisposeBuilder(Builder);
509 return Dst;
510 }
511
512 void CloneAttrs(LLVMValueRef Src, LLVMValueRef Dst) {
513 auto Ctx = LLVMGetModuleContext(M);
514 int ArgCount = LLVMGetNumArgOperands(Instr: Src);
515 for (int i = LLVMAttributeReturnIndex; i <= ArgCount; i++) {
516 for (unsigned k = 0, e = LLVMGetLastEnumAttributeKind(); k < e; ++k) {
517 if (auto SrcA = LLVMGetCallSiteEnumAttribute(C: Src, Idx: i, KindID: k)) {
518 auto Val = LLVMGetEnumAttributeValue(A: SrcA);
519 auto A = LLVMCreateEnumAttribute(C: Ctx, KindID: k, Val);
520 LLVMAddCallSiteAttribute(C: Dst, Idx: i, A);
521 }
522 }
523 }
524 }
525
526 LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
527 check_value_kind(V: Src, K: LLVMInstructionValueKind);
528 if (!LLVMIsAInstruction(Val: Src))
529 report_fatal_error(reason: "Expected an instruction");
530 LLVMContextRef Ctx = LLVMGetTypeContext(Ty: LLVMTypeOf(Val: Src));
531
532 size_t NameLen;
533 const char *Name = LLVMGetValueName2(Val: Src, Length: &NameLen);
534
535 // Check if this is something we already computed.
536 {
537 auto i = VMap.find(Val: Src);
538 if (i != VMap.end()) {
539 // If we have a hit, it means we already generated the instruction
540 // as a dependency to something else. We need to make sure
541 // it is ordered properly.
542 auto I = i->second;
543 LLVMInstructionRemoveFromParent(Inst: I);
544 LLVMInsertIntoBuilderWithName(Builder, Instr: I, Name);
545 return I;
546 }
547 }
548
549 // We tried everything, it must be an instruction
550 // that hasn't been generated already.
551 LLVMValueRef Dst = nullptr;
552
553 LLVMOpcode Op = LLVMGetInstructionOpcode(Inst: Src);
554 switch(Op) {
555 case LLVMRet: {
556 int OpCount = LLVMGetNumOperands(Val: Src);
557 if (OpCount == 0)
558 Dst = LLVMBuildRetVoid(Builder);
559 else
560 Dst = LLVMBuildRet(Builder, V: CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0)));
561 break;
562 }
563 case LLVMBr: {
564 if (!LLVMIsConditional(Branch: Src)) {
565 LLVMValueRef SrcOp = LLVMGetOperand(Val: Src, Index: 0);
566 LLVMBasicBlockRef SrcBB = LLVMValueAsBasicBlock(Val: SrcOp);
567 Dst = LLVMBuildBr(Builder, Dest: DeclareBB(Src: SrcBB));
568 break;
569 }
570
571 LLVMValueRef Cond = LLVMGetCondition(Branch: Src);
572 LLVMValueRef Else = LLVMGetOperand(Val: Src, Index: 1);
573 LLVMBasicBlockRef ElseBB = DeclareBB(Src: LLVMValueAsBasicBlock(Val: Else));
574 LLVMValueRef Then = LLVMGetOperand(Val: Src, Index: 2);
575 LLVMBasicBlockRef ThenBB = DeclareBB(Src: LLVMValueAsBasicBlock(Val: Then));
576 Dst = LLVMBuildCondBr(Builder, If: CloneValue(Src: Cond), Then: ThenBB, Else: ElseBB);
577 break;
578 }
579 case LLVMSwitch:
580 case LLVMIndirectBr:
581 break;
582 case LLVMInvoke: {
583 SmallVector<LLVMValueRef, 8> Args;
584 SmallVector<LLVMOperandBundleRef, 8> Bundles;
585 unsigned ArgCount = LLVMGetNumArgOperands(Instr: Src);
586 for (unsigned i = 0; i < ArgCount; ++i)
587 Args.push_back(Elt: CloneValue(Src: LLVMGetOperand(Val: Src, Index: i)));
588 unsigned BundleCount = LLVMGetNumOperandBundles(C: Src);
589 for (unsigned i = 0; i < BundleCount; ++i) {
590 auto Bundle = LLVMGetOperandBundleAtIndex(C: Src, Index: i);
591 Bundles.push_back(Elt: CloneOB(Src: Bundle));
592 LLVMDisposeOperandBundle(Bundle);
593 }
594 LLVMTypeRef FnTy = CloneType(Src: LLVMGetCalledFunctionType(C: Src));
595 LLVMValueRef Fn = CloneValue(Src: LLVMGetCalledValue(Instr: Src));
596 LLVMBasicBlockRef Then = DeclareBB(Src: LLVMGetNormalDest(InvokeInst: Src));
597 LLVMBasicBlockRef Unwind = DeclareBB(Src: LLVMGetUnwindDest(InvokeInst: Src));
598 Dst = LLVMBuildInvokeWithOperandBundles(
599 Builder, Ty: FnTy, Fn, Args: Args.data(), NumArgs: ArgCount, Then, Catch: Unwind,
600 Bundles: Bundles.data(), NumBundles: Bundles.size(), Name);
601 CloneAttrs(Src, Dst);
602 for (auto Bundle : Bundles)
603 LLVMDisposeOperandBundle(Bundle);
604 break;
605 }
606 case LLVMCallBr: {
607 LLVMTypeRef FnTy = CloneType(Src: LLVMGetCalledFunctionType(C: Src));
608 LLVMValueRef Fn = CloneValue(Src: LLVMGetCalledValue(Instr: Src));
609
610 LLVMBasicBlockRef DefaultDest =
611 DeclareBB(Src: LLVMGetCallBrDefaultDest(CallBr: Src));
612
613 // Clone indirect destinations
614 SmallVector<LLVMBasicBlockRef, 8> IndirectDests;
615 unsigned IndirectDestCount = LLVMGetCallBrNumIndirectDests(CallBr: Src);
616 for (unsigned i = 0; i < IndirectDestCount; ++i)
617 IndirectDests.push_back(Elt: DeclareBB(Src: LLVMGetCallBrIndirectDest(CallBr: Src, Idx: i)));
618
619 // Clone input arguments
620 SmallVector<LLVMValueRef, 8> Args;
621 unsigned ArgCount = LLVMGetNumArgOperands(Instr: Src);
622 for (unsigned i = 0; i < ArgCount; ++i)
623 Args.push_back(Elt: CloneValue(Src: LLVMGetOperand(Val: Src, Index: i)));
624
625 // Clone operand bundles
626 SmallVector<LLVMOperandBundleRef, 8> Bundles;
627 unsigned BundleCount = LLVMGetNumOperandBundles(C: Src);
628 for (unsigned i = 0; i < BundleCount; ++i) {
629 auto Bundle = LLVMGetOperandBundleAtIndex(C: Src, Index: i);
630 Bundles.push_back(Elt: CloneOB(Src: Bundle));
631 LLVMDisposeOperandBundle(Bundle);
632 }
633
634 Dst = LLVMBuildCallBr(B: Builder, Ty: FnTy, Fn, DefaultDest,
635 IndirectDests: IndirectDests.data(), NumIndirectDests: IndirectDests.size(),
636 Args: Args.data(), NumArgs: Args.size(), Bundles: Bundles.data(),
637 NumBundles: Bundles.size(), Name);
638
639 CloneAttrs(Src, Dst);
640
641 for (auto Bundle : Bundles)
642 LLVMDisposeOperandBundle(Bundle);
643
644 break;
645 }
646 case LLVMUnreachable:
647 Dst = LLVMBuildUnreachable(Builder);
648 break;
649 case LLVMAdd: {
650 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
651 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
652 LLVMBool NUW = LLVMGetNUW(ArithInst: Src);
653 LLVMBool NSW = LLVMGetNSW(ArithInst: Src);
654 Dst = LLVMBuildAdd(Builder, LHS, RHS, Name);
655 LLVMSetNUW(ArithInst: Dst, HasNUW: NUW);
656 LLVMSetNSW(ArithInst: Dst, HasNSW: NSW);
657 break;
658 }
659 case LLVMSub: {
660 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
661 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
662 LLVMBool NUW = LLVMGetNUW(ArithInst: Src);
663 LLVMBool NSW = LLVMGetNSW(ArithInst: Src);
664 Dst = LLVMBuildSub(Builder, LHS, RHS, Name);
665 LLVMSetNUW(ArithInst: Dst, HasNUW: NUW);
666 LLVMSetNSW(ArithInst: Dst, HasNSW: NSW);
667 break;
668 }
669 case LLVMMul: {
670 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
671 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
672 LLVMBool NUW = LLVMGetNUW(ArithInst: Src);
673 LLVMBool NSW = LLVMGetNSW(ArithInst: Src);
674 Dst = LLVMBuildMul(Builder, LHS, RHS, Name);
675 LLVMSetNUW(ArithInst: Dst, HasNUW: NUW);
676 LLVMSetNSW(ArithInst: Dst, HasNSW: NSW);
677 break;
678 }
679 case LLVMUDiv: {
680 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
681 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
682 LLVMBool IsExact = LLVMGetExact(DivOrShrInst: Src);
683 Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name);
684 LLVMSetExact(DivOrShrInst: Dst, IsExact);
685 break;
686 }
687 case LLVMSDiv: {
688 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
689 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
690 LLVMBool IsExact = LLVMGetExact(DivOrShrInst: Src);
691 Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name);
692 LLVMSetExact(DivOrShrInst: Dst, IsExact);
693 break;
694 }
695 case LLVMURem: {
696 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
697 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
698 Dst = LLVMBuildURem(Builder, LHS, RHS, Name);
699 break;
700 }
701 case LLVMSRem: {
702 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
703 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
704 Dst = LLVMBuildSRem(Builder, LHS, RHS, Name);
705 break;
706 }
707 case LLVMShl: {
708 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
709 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
710 LLVMBool NUW = LLVMGetNUW(ArithInst: Src);
711 LLVMBool NSW = LLVMGetNSW(ArithInst: Src);
712 Dst = LLVMBuildShl(Builder, LHS, RHS, Name);
713 LLVMSetNUW(ArithInst: Dst, HasNUW: NUW);
714 LLVMSetNSW(ArithInst: Dst, HasNSW: NSW);
715 break;
716 }
717 case LLVMLShr: {
718 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
719 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
720 LLVMBool IsExact = LLVMGetExact(DivOrShrInst: Src);
721 Dst = LLVMBuildLShr(Builder, LHS, RHS, Name);
722 LLVMSetExact(DivOrShrInst: Dst, IsExact);
723 break;
724 }
725 case LLVMAShr: {
726 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
727 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
728 LLVMBool IsExact = LLVMGetExact(DivOrShrInst: Src);
729 Dst = LLVMBuildAShr(Builder, LHS, RHS, Name);
730 LLVMSetExact(DivOrShrInst: Dst, IsExact);
731 break;
732 }
733 case LLVMAnd: {
734 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
735 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
736 Dst = LLVMBuildAnd(Builder, LHS, RHS, Name);
737 break;
738 }
739 case LLVMOr: {
740 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
741 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
742 LLVMBool IsDisjoint = LLVMGetIsDisjoint(Inst: Src);
743 Dst = LLVMBuildOr(Builder, LHS, RHS, Name);
744 LLVMSetIsDisjoint(Inst: Dst, IsDisjoint);
745 break;
746 }
747 case LLVMXor: {
748 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
749 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
750 Dst = LLVMBuildXor(Builder, LHS, RHS, Name);
751 break;
752 }
753 case LLVMAlloca: {
754 LLVMTypeRef Ty = CloneType(Src: LLVMGetAllocatedType(Alloca: Src));
755 Dst = LLVMBuildAlloca(Builder, Ty, Name);
756 LLVMSetAlignment(V: Dst, Bytes: LLVMGetAlignment(V: Src));
757 break;
758 }
759 case LLVMLoad: {
760 LLVMValueRef Ptr = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
761 Dst = LLVMBuildLoad2(Builder, Ty: CloneType(Src), PointerVal: Ptr, Name);
762 LLVMSetAlignment(V: Dst, Bytes: LLVMGetAlignment(V: Src));
763 LLVMSetOrdering(MemoryAccessInst: Dst, Ordering: LLVMGetOrdering(MemoryAccessInst: Src));
764 LLVMSetVolatile(MemoryAccessInst: Dst, IsVolatile: LLVMGetVolatile(MemoryAccessInst: Src));
765 if (LLVMIsAtomic(Inst: Src))
766 LLVMSetAtomicSyncScopeID(AtomicInst: Dst, SSID: LLVMGetAtomicSyncScopeID(AtomicInst: Src));
767 break;
768 }
769 case LLVMStore: {
770 LLVMValueRef Val = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
771 LLVMValueRef Ptr = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
772 Dst = LLVMBuildStore(Builder, Val, Ptr);
773 LLVMSetAlignment(V: Dst, Bytes: LLVMGetAlignment(V: Src));
774 LLVMSetOrdering(MemoryAccessInst: Dst, Ordering: LLVMGetOrdering(MemoryAccessInst: Src));
775 LLVMSetVolatile(MemoryAccessInst: Dst, IsVolatile: LLVMGetVolatile(MemoryAccessInst: Src));
776 if (LLVMIsAtomic(Inst: Src))
777 LLVMSetAtomicSyncScopeID(AtomicInst: Dst, SSID: LLVMGetAtomicSyncScopeID(AtomicInst: Src));
778 break;
779 }
780 case LLVMGetElementPtr: {
781 LLVMTypeRef ElemTy = CloneType(Src: LLVMGetGEPSourceElementType(GEP: Src));
782 LLVMValueRef Ptr = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
783 SmallVector<LLVMValueRef, 8> Idx;
784 int NumIdx = LLVMGetNumIndices(Inst: Src);
785 for (int i = 1; i <= NumIdx; i++)
786 Idx.push_back(Elt: CloneValue(Src: LLVMGetOperand(Val: Src, Index: i)));
787
788 Dst = LLVMBuildGEPWithNoWrapFlags(B: Builder, Ty: ElemTy, Pointer: Ptr, Indices: Idx.data(),
789 NumIndices: NumIdx, Name,
790 NoWrapFlags: LLVMGEPGetNoWrapFlags(GEP: Src));
791 break;
792 }
793 case LLVMAtomicRMW: {
794 LLVMValueRef Ptr = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
795 LLVMValueRef Val = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
796 LLVMAtomicRMWBinOp BinOp = LLVMGetAtomicRMWBinOp(AtomicRMWInst: Src);
797 LLVMAtomicOrdering Ord = LLVMGetOrdering(MemoryAccessInst: Src);
798 Dst = LLVMBuildAtomicRMWSyncScope(B: Builder, op: BinOp, PTR: Ptr, Val, ordering: Ord,
799 SSID: LLVMGetAtomicSyncScopeID(AtomicInst: Src));
800 LLVMSetAlignment(V: Dst, Bytes: LLVMGetAlignment(V: Src));
801 LLVMSetVolatile(MemoryAccessInst: Dst, IsVolatile: LLVMGetVolatile(MemoryAccessInst: Src));
802 LLVMSetValueName2(Val: Dst, Name, NameLen);
803 break;
804 }
805 case LLVMAtomicCmpXchg: {
806 LLVMValueRef Ptr = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
807 LLVMValueRef Cmp = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
808 LLVMValueRef New = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 2));
809 LLVMAtomicOrdering Succ = LLVMGetCmpXchgSuccessOrdering(CmpXchgInst: Src);
810 LLVMAtomicOrdering Fail = LLVMGetCmpXchgFailureOrdering(CmpXchgInst: Src);
811 Dst = LLVMBuildAtomicCmpXchgSyncScope(
812 B: Builder, Ptr, Cmp, New, SuccessOrdering: Succ, FailureOrdering: Fail, SSID: LLVMGetAtomicSyncScopeID(AtomicInst: Src));
813 LLVMSetAlignment(V: Dst, Bytes: LLVMGetAlignment(V: Src));
814 LLVMSetVolatile(MemoryAccessInst: Dst, IsVolatile: LLVMGetVolatile(MemoryAccessInst: Src));
815 LLVMSetWeak(CmpXchgInst: Dst, IsWeak: LLVMGetWeak(CmpXchgInst: Src));
816 LLVMSetValueName2(Val: Dst, Name, NameLen);
817 break;
818 }
819 case LLVMBitCast: {
820 LLVMValueRef V = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
821 Dst = LLVMBuildBitCast(Builder, Val: V, DestTy: CloneType(Src), Name);
822 break;
823 }
824 case LLVMICmp: {
825 LLVMIntPredicate Pred = LLVMGetICmpPredicate(Inst: Src);
826 LLVMBool IsSameSign = LLVMGetICmpSameSign(Inst: Src);
827 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
828 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
829 Dst = LLVMBuildICmp(Builder, Op: Pred, LHS, RHS, Name);
830 LLVMSetICmpSameSign(Inst: Dst, SameSign: IsSameSign);
831 break;
832 }
833 case LLVMPHI: {
834 // We need to aggressively set things here because of loops.
835 VMap[Src] = Dst = LLVMBuildPhi(Builder, Ty: CloneType(Src), Name);
836
837 SmallVector<LLVMValueRef, 8> Values;
838 SmallVector<LLVMBasicBlockRef, 8> Blocks;
839
840 unsigned IncomingCount = LLVMCountIncoming(PhiNode: Src);
841 for (unsigned i = 0; i < IncomingCount; ++i) {
842 Blocks.push_back(Elt: DeclareBB(Src: LLVMGetIncomingBlock(PhiNode: Src, Index: i)));
843 Values.push_back(Elt: CloneValue(Src: LLVMGetIncomingValue(PhiNode: Src, Index: i)));
844 }
845
846 LLVMAddIncoming(PhiNode: Dst, IncomingValues: Values.data(), IncomingBlocks: Blocks.data(), Count: IncomingCount);
847 // Copy fast math flags here since we return early
848 if (LLVMCanValueUseFastMathFlags(Inst: Src))
849 LLVMSetFastMathFlags(FPMathInst: Dst, FMF: LLVMGetFastMathFlags(FPMathInst: Src));
850 return Dst;
851 }
852 case LLVMSelect: {
853 LLVMValueRef If = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
854 LLVMValueRef Then = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
855 LLVMValueRef Else = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 2));
856 Dst = LLVMBuildSelect(Builder, If, Then, Else, Name);
857 break;
858 }
859 case LLVMCall: {
860 SmallVector<LLVMValueRef, 8> Args;
861 SmallVector<LLVMOperandBundleRef, 8> Bundles;
862 unsigned ArgCount = LLVMGetNumArgOperands(Instr: Src);
863 for (unsigned i = 0; i < ArgCount; ++i)
864 Args.push_back(Elt: CloneValue(Src: LLVMGetOperand(Val: Src, Index: i)));
865 unsigned BundleCount = LLVMGetNumOperandBundles(C: Src);
866 for (unsigned i = 0; i < BundleCount; ++i) {
867 auto Bundle = LLVMGetOperandBundleAtIndex(C: Src, Index: i);
868 Bundles.push_back(Elt: CloneOB(Src: Bundle));
869 LLVMDisposeOperandBundle(Bundle);
870 }
871 LLVMTypeRef FnTy = CloneType(Src: LLVMGetCalledFunctionType(C: Src));
872 LLVMValueRef Fn = CloneValue(Src: LLVMGetCalledValue(Instr: Src));
873 Dst = LLVMBuildCallWithOperandBundles(Builder, FnTy, Fn, Args: Args.data(),
874 NumArgs: ArgCount, Bundles: Bundles.data(),
875 NumBundles: Bundles.size(), Name);
876 LLVMSetTailCallKind(CallInst: Dst, kind: LLVMGetTailCallKind(CallInst: Src));
877 CloneAttrs(Src, Dst);
878 for (auto Bundle : Bundles)
879 LLVMDisposeOperandBundle(Bundle);
880 break;
881 }
882 case LLVMResume: {
883 Dst = LLVMBuildResume(B: Builder, Exn: CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0)));
884 break;
885 }
886 case LLVMLandingPad: {
887 // The landing pad API is a bit screwed up for historical reasons.
888 Dst = LLVMBuildLandingPad(B: Builder, Ty: CloneType(Src), PersFn: nullptr, NumClauses: 0, Name);
889 unsigned NumClauses = LLVMGetNumClauses(LandingPad: Src);
890 for (unsigned i = 0; i < NumClauses; ++i)
891 LLVMAddClause(LandingPad: Dst, ClauseVal: CloneValue(Src: LLVMGetClause(LandingPad: Src, Idx: i)));
892 LLVMSetCleanup(LandingPad: Dst, Val: LLVMIsCleanup(LandingPad: Src));
893 break;
894 }
895 case LLVMCleanupRet: {
896 LLVMValueRef CatchPad = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
897 LLVMBasicBlockRef Unwind = nullptr;
898 if (LLVMBasicBlockRef UDest = LLVMGetUnwindDest(InvokeInst: Src))
899 Unwind = DeclareBB(Src: UDest);
900 Dst = LLVMBuildCleanupRet(B: Builder, CatchPad, BB: Unwind);
901 break;
902 }
903 case LLVMCatchRet: {
904 LLVMValueRef CatchPad = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
905 LLVMBasicBlockRef SuccBB = DeclareBB(Src: LLVMGetSuccessor(Term: Src, i: 0));
906 Dst = LLVMBuildCatchRet(B: Builder, CatchPad, BB: SuccBB);
907 break;
908 }
909 case LLVMCatchPad: {
910 LLVMValueRef ParentPad = CloneValue(Src: LLVMGetParentCatchSwitch(CatchPad: Src));
911 SmallVector<LLVMValueRef, 8> Args;
912 int ArgCount = LLVMGetNumArgOperands(Instr: Src);
913 for (int i = 0; i < ArgCount; i++)
914 Args.push_back(Elt: CloneValue(Src: LLVMGetOperand(Val: Src, Index: i)));
915 Dst = LLVMBuildCatchPad(B: Builder, ParentPad,
916 Args: Args.data(), NumArgs: ArgCount, Name);
917 break;
918 }
919 case LLVMCleanupPad: {
920 LLVMValueRef ParentPad = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
921 SmallVector<LLVMValueRef, 8> Args;
922 int ArgCount = LLVMGetNumArgOperands(Instr: Src);
923 for (int i = 0; i < ArgCount; i++)
924 Args.push_back(Elt: CloneValue(Src: LLVMGetArgOperand(Funclet: Src, i)));
925 Dst = LLVMBuildCleanupPad(B: Builder, ParentPad,
926 Args: Args.data(), NumArgs: ArgCount, Name);
927 break;
928 }
929 case LLVMCatchSwitch: {
930 LLVMValueRef ParentPad = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
931 LLVMBasicBlockRef UnwindBB = nullptr;
932 if (LLVMBasicBlockRef UDest = LLVMGetUnwindDest(InvokeInst: Src)) {
933 UnwindBB = DeclareBB(Src: UDest);
934 }
935 unsigned NumHandlers = LLVMGetNumHandlers(CatchSwitch: Src);
936 Dst = LLVMBuildCatchSwitch(B: Builder, ParentPad, UnwindBB, NumHandlers, Name);
937 if (NumHandlers > 0) {
938 LLVMBasicBlockRef *Handlers = static_cast<LLVMBasicBlockRef*>(
939 safe_malloc(Sz: NumHandlers * sizeof(LLVMBasicBlockRef)));
940 LLVMGetHandlers(CatchSwitch: Src, Handlers);
941 for (unsigned i = 0; i < NumHandlers; i++)
942 LLVMAddHandler(CatchSwitch: Dst, Dest: DeclareBB(Src: Handlers[i]));
943 free(ptr: Handlers);
944 }
945 break;
946 }
947 case LLVMExtractValue: {
948 LLVMValueRef Agg = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
949 if (LLVMGetNumIndices(Inst: Src) > 1)
950 report_fatal_error(reason: "ExtractValue: Expected only one index");
951 else if (LLVMGetNumIndices(Inst: Src) < 1)
952 report_fatal_error(reason: "ExtractValue: Expected an index");
953 auto I = LLVMGetIndices(Inst: Src)[0];
954 Dst = LLVMBuildExtractValue(Builder, AggVal: Agg, Index: I, Name);
955 break;
956 }
957 case LLVMInsertValue: {
958 LLVMValueRef Agg = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
959 LLVMValueRef V = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
960 if (LLVMGetNumIndices(Inst: Src) > 1)
961 report_fatal_error(reason: "InsertValue: Expected only one index");
962 else if (LLVMGetNumIndices(Inst: Src) < 1)
963 report_fatal_error(reason: "InsertValue: Expected an index");
964 auto I = LLVMGetIndices(Inst: Src)[0];
965 Dst = LLVMBuildInsertValue(Builder, AggVal: Agg, EltVal: V, Index: I, Name);
966 break;
967 }
968 case LLVMExtractElement: {
969 LLVMValueRef Agg = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
970 LLVMValueRef Index = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
971 Dst = LLVMBuildExtractElement(Builder, VecVal: Agg, Index, Name);
972 break;
973 }
974 case LLVMInsertElement: {
975 LLVMValueRef Agg = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
976 LLVMValueRef V = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
977 LLVMValueRef Index = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 2));
978 Dst = LLVMBuildInsertElement(Builder, VecVal: Agg, EltVal: V, Index, Name);
979 break;
980 }
981 case LLVMShuffleVector: {
982 LLVMValueRef Agg0 = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
983 LLVMValueRef Agg1 = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
984 SmallVector<LLVMValueRef, 8> MaskElts;
985 unsigned NumMaskElts = LLVMGetNumMaskElements(ShuffleVectorInst: Src);
986 for (unsigned i = 0; i < NumMaskElts; i++) {
987 int Val = LLVMGetMaskValue(ShuffleVectorInst: Src, Elt: i);
988 if (Val == LLVMGetUndefMaskElem()) {
989 MaskElts.push_back(Elt: LLVMGetUndef(Ty: LLVMInt64Type()));
990 } else {
991 MaskElts.push_back(Elt: LLVMConstInt(IntTy: LLVMInt64Type(), N: Val, SignExtend: true));
992 }
993 }
994 LLVMValueRef Mask = LLVMConstVector(ScalarConstantVals: MaskElts.data(), Size: NumMaskElts);
995 Dst = LLVMBuildShuffleVector(Builder, V1: Agg0, V2: Agg1, Mask, Name);
996 break;
997 }
998 case LLVMFreeze: {
999 LLVMValueRef Arg = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1000 Dst = LLVMBuildFreeze(Builder, Val: Arg, Name);
1001 break;
1002 }
1003 case LLVMFence: {
1004 LLVMAtomicOrdering Ordering = LLVMGetOrdering(MemoryAccessInst: Src);
1005 Dst = LLVMBuildFenceSyncScope(B: Builder, ordering: Ordering,
1006 SSID: LLVMGetAtomicSyncScopeID(AtomicInst: Src), Name);
1007 break;
1008 }
1009 case LLVMZExt: {
1010 LLVMValueRef Val = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1011 LLVMTypeRef DestTy = CloneType(Src: LLVMTypeOf(Val: Src));
1012 LLVMBool NNeg = LLVMGetNNeg(NonNegInst: Src);
1013 Dst = LLVMBuildZExt(Builder, Val, DestTy, Name);
1014 LLVMSetNNeg(NonNegInst: Dst, IsNonNeg: NNeg);
1015 break;
1016 }
1017 case LLVMFAdd: {
1018 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1019 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1020 Dst = LLVMBuildFAdd(Builder, LHS, RHS, Name);
1021 break;
1022 }
1023 case LLVMFSub: {
1024 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1025 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1026 Dst = LLVMBuildFSub(Builder, LHS, RHS, Name);
1027 break;
1028 }
1029 case LLVMFMul: {
1030 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1031 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1032 Dst = LLVMBuildFMul(Builder, LHS, RHS, Name);
1033 break;
1034 }
1035 case LLVMFDiv: {
1036 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1037 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1038 Dst = LLVMBuildFDiv(Builder, LHS, RHS, Name);
1039 break;
1040 }
1041 case LLVMFRem: {
1042 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1043 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1044 Dst = LLVMBuildFRem(Builder, LHS, RHS, Name);
1045 break;
1046 }
1047 case LLVMFNeg: {
1048 LLVMValueRef Val = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1049 Dst = LLVMBuildFNeg(Builder, V: Val, Name);
1050 break;
1051 }
1052 case LLVMFCmp: {
1053 LLVMRealPredicate Pred = LLVMGetFCmpPredicate(Inst: Src);
1054 LLVMValueRef LHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 0));
1055 LLVMValueRef RHS = CloneValue(Src: LLVMGetOperand(Val: Src, Index: 1));
1056 Dst = LLVMBuildFCmp(Builder, Op: Pred, LHS, RHS, Name);
1057 break;
1058 }
1059 default:
1060 break;
1061 }
1062
1063 if (Dst == nullptr) {
1064 fprintf(stderr, format: "%d is not a supported opcode\n", Op);
1065 exit(status: -1);
1066 }
1067
1068 // Copy fast-math flags on instructions that support them
1069 if (LLVMCanValueUseFastMathFlags(Inst: Src))
1070 LLVMSetFastMathFlags(FPMathInst: Dst, FMF: LLVMGetFastMathFlags(FPMathInst: Src));
1071
1072 size_t NumMetadataEntries;
1073 auto *AllMetadata =
1074 LLVMInstructionGetAllMetadataOtherThanDebugLoc(Instr: Src,
1075 NumEntries: &NumMetadataEntries);
1076 for (unsigned i = 0; i < NumMetadataEntries; ++i) {
1077 unsigned Kind = LLVMValueMetadataEntriesGetKind(Entries: AllMetadata, Index: i);
1078 LLVMMetadataRef MD = LLVMValueMetadataEntriesGetMetadata(Entries: AllMetadata, Index: i);
1079 LLVMSetMetadata(Val: Dst, KindID: Kind, Node: LLVMMetadataAsValue(C: Ctx, MD));
1080 }
1081 LLVMDisposeValueMetadataEntries(Entries: AllMetadata);
1082 LLVMAddMetadataToInst(Builder, Inst: Dst);
1083
1084 check_value_kind(V: Dst, K: LLVMInstructionValueKind);
1085 return VMap[Src] = Dst;
1086 }
1087
1088 LLVMOperandBundleRef CloneOB(LLVMOperandBundleRef Src) {
1089 size_t TagLen;
1090 const char *Tag = LLVMGetOperandBundleTag(Bundle: Src, Len: &TagLen);
1091
1092 SmallVector<LLVMValueRef, 8> Args;
1093 for (unsigned i = 0, n = LLVMGetNumOperandBundleArgs(Bundle: Src); i != n; ++i)
1094 Args.push_back(Elt: CloneValue(Src: LLVMGetOperandBundleArgAtIndex(Bundle: Src, Index: i)));
1095
1096 return LLVMCreateOperandBundle(Tag, TagLen, Args: Args.data(), NumArgs: Args.size());
1097 }
1098
1099 LLVMBasicBlockRef DeclareBB(LLVMBasicBlockRef Src) {
1100 // Check if this is something we already computed.
1101 {
1102 auto i = BBMap.find(Val: Src);
1103 if (i != BBMap.end()) {
1104 return i->second;
1105 }
1106 }
1107
1108 LLVMValueRef V = LLVMBasicBlockAsValue(BB: Src);
1109 if (!LLVMValueIsBasicBlock(Val: V) || LLVMValueAsBasicBlock(Val: V) != Src)
1110 report_fatal_error(reason: "Basic block is not a basic block");
1111
1112 const char *Name = LLVMGetBasicBlockName(BB: Src);
1113 size_t NameLen;
1114 const char *VName = LLVMGetValueName2(Val: V, Length: &NameLen);
1115 if (Name != VName)
1116 report_fatal_error(reason: "Basic block name mismatch");
1117
1118 LLVMBasicBlockRef BB = LLVMAppendBasicBlock(Fn: Fun, Name);
1119 return BBMap[Src] = BB;
1120 }
1121
1122 LLVMBasicBlockRef CloneBB(LLVMBasicBlockRef Src) {
1123 LLVMBasicBlockRef BB = DeclareBB(Src);
1124
1125 // Make sure ordering is correct.
1126 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(BB: Src);
1127 if (Prev)
1128 LLVMMoveBasicBlockAfter(BB, MovePos: DeclareBB(Src: Prev));
1129
1130 LLVMValueRef First = LLVMGetFirstInstruction(BB: Src);
1131 LLVMValueRef Last = LLVMGetLastInstruction(BB: Src);
1132
1133 if (First == nullptr) {
1134 if (Last != nullptr)
1135 report_fatal_error(reason: "Has no first instruction, but last one");
1136 return BB;
1137 }
1138
1139 auto Ctx = LLVMGetModuleContext(M);
1140 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(C: Ctx);
1141 LLVMPositionBuilderAtEnd(Builder, Block: BB);
1142
1143 LLVMValueRef Cur = First;
1144 LLVMValueRef Next = nullptr;
1145 while(true) {
1146 CloneInstruction(Src: Cur, Builder);
1147 Next = LLVMGetNextInstruction(Inst: Cur);
1148 if (Next == nullptr) {
1149 if (Cur != Last)
1150 report_fatal_error(reason: "Final instruction does not match Last");
1151 break;
1152 }
1153
1154 LLVMValueRef Prev = LLVMGetPreviousInstruction(Inst: Next);
1155 if (Prev != Cur)
1156 report_fatal_error(reason: "Next.Previous instruction is not Current");
1157
1158 Cur = Next;
1159 }
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