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