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

source code of llvm/tools/llvm-c-test/echo.cpp