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