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