1 //===-- echo.cpp - tool for testing libLLVM and llvm-c API ----------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the --echo commands in llvm-c-test. 11 // 12 // This command uses the C API to read a module and output an exact copy of it 13 // as output. It is used to check that the resulting module matches the input 14 // to validate that the C API can read and write modules properly. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #include "llvm-c-test.h" 19 #include "llvm-c/Target.h" 20 #include "llvm/ADT/DenseMap.h" 21 #include "llvm/Support/ErrorHandling.h" 22 23 #include <stdio.h> 24 #include <stdlib.h> 25 26 using namespace llvm; 27 28 // Provide DenseMapInfo for C API opaque types. 29 template<typename T> 30 struct CAPIDenseMap {}; 31 32 // The default DenseMapInfo require to know about pointer alignement. 33 // Because the C API uses opaques pointer types, their alignement is unknown. 34 // As a result, we need to roll out our own implementation. 35 template<typename T> 36 struct CAPIDenseMap<T*> { 37 struct CAPIDenseMapInfo { 38 static inline T* getEmptyKey() { 39 uintptr_t Val = static_cast<uintptr_t>(-1); 40 return reinterpret_cast<T*>(Val); 41 } 42 static inline T* getTombstoneKey() { 43 uintptr_t Val = static_cast<uintptr_t>(-2); 44 return reinterpret_cast<T*>(Val); 45 } 46 static unsigned getHashValue(const T *PtrVal) { 47 return hash_value(PtrVal); 48 } 49 static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; } 50 }; 51 52 typedef DenseMap<T*, T*, CAPIDenseMapInfo> Map; 53 }; 54 55 typedef CAPIDenseMap<LLVMValueRef>::Map ValueMap; 56 typedef CAPIDenseMap<LLVMBasicBlockRef>::Map BasicBlockMap; 57 58 struct TypeCloner { 59 LLVMModuleRef M; 60 LLVMContextRef Ctx; 61 62 TypeCloner(LLVMModuleRef M): M(M), Ctx(LLVMGetModuleContext(M)) {} 63 64 LLVMTypeRef Clone(LLVMValueRef Src) { 65 return Clone(LLVMTypeOf(Src)); 66 } 67 68 LLVMTypeRef Clone(LLVMTypeRef Src) { 69 LLVMTypeKind Kind = LLVMGetTypeKind(Src); 70 switch (Kind) { 71 case LLVMVoidTypeKind: 72 return LLVMVoidTypeInContext(Ctx); 73 case LLVMHalfTypeKind: 74 return LLVMHalfTypeInContext(Ctx); 75 case LLVMFloatTypeKind: 76 return LLVMFloatTypeInContext(Ctx); 77 case LLVMDoubleTypeKind: 78 return LLVMDoubleTypeInContext(Ctx); 79 case LLVMX86_FP80TypeKind: 80 return LLVMX86FP80TypeInContext(Ctx); 81 case LLVMFP128TypeKind: 82 return LLVMFP128TypeInContext(Ctx); 83 case LLVMPPC_FP128TypeKind: 84 return LLVMPPCFP128TypeInContext(Ctx); 85 case LLVMLabelTypeKind: 86 return LLVMLabelTypeInContext(Ctx); 87 case LLVMIntegerTypeKind: 88 return LLVMIntTypeInContext(Ctx, LLVMGetIntTypeWidth(Src)); 89 case LLVMFunctionTypeKind: { 90 unsigned ParamCount = LLVMCountParamTypes(Src); 91 LLVMTypeRef* Params = nullptr; 92 if (ParamCount > 0) { 93 Params = (LLVMTypeRef*) malloc(ParamCount * sizeof(LLVMTypeRef)); 94 LLVMGetParamTypes(Src, Params); 95 for (unsigned i = 0; i < ParamCount; i++) 96 Params[i] = Clone(Params[i]); 97 } 98 99 LLVMTypeRef FunTy = LLVMFunctionType(Clone(LLVMGetReturnType(Src)), 100 Params, ParamCount, 101 LLVMIsFunctionVarArg(Src)); 102 if (ParamCount > 0) 103 free(Params); 104 return FunTy; 105 } 106 case LLVMStructTypeKind: { 107 LLVMTypeRef S = nullptr; 108 const char *Name = LLVMGetStructName(Src); 109 if (Name) { 110 S = LLVMGetTypeByName(M, Name); 111 if (S) 112 return S; 113 S = LLVMStructCreateNamed(Ctx, Name); 114 if (LLVMIsOpaqueStruct(Src)) 115 return S; 116 } 117 118 unsigned EltCount = LLVMCountStructElementTypes(Src); 119 SmallVector<LLVMTypeRef, 8> Elts; 120 for (unsigned i = 0; i < EltCount; i++) 121 Elts.push_back(Clone(LLVMStructGetTypeAtIndex(Src, i))); 122 if (Name) 123 LLVMStructSetBody(S, Elts.data(), EltCount, LLVMIsPackedStruct(Src)); 124 else 125 S = LLVMStructTypeInContext(Ctx, Elts.data(), EltCount, 126 LLVMIsPackedStruct(Src)); 127 return S; 128 } 129 case LLVMArrayTypeKind: 130 return LLVMArrayType( 131 Clone(LLVMGetElementType(Src)), 132 LLVMGetArrayLength(Src) 133 ); 134 case LLVMPointerTypeKind: 135 return LLVMPointerType( 136 Clone(LLVMGetElementType(Src)), 137 LLVMGetPointerAddressSpace(Src) 138 ); 139 case LLVMVectorTypeKind: 140 return LLVMVectorType( 141 Clone(LLVMGetElementType(Src)), 142 LLVMGetVectorSize(Src) 143 ); 144 case LLVMMetadataTypeKind: 145 break; 146 case LLVMX86_MMXTypeKind: 147 return LLVMX86MMXTypeInContext(Ctx); 148 default: 149 break; 150 } 151 152 fprintf(stderr, "%d is not a supported typekind\n", Kind); 153 exit(-1); 154 } 155 }; 156 157 static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst) { 158 unsigned Count = LLVMCountParams(Src); 159 if (Count != LLVMCountParams(Dst)) 160 report_fatal_error("Parameter count mismatch"); 161 162 ValueMap VMap; 163 if (Count == 0) 164 return VMap; 165 166 LLVMValueRef SrcFirst = LLVMGetFirstParam(Src); 167 LLVMValueRef DstFirst = LLVMGetFirstParam(Dst); 168 LLVMValueRef SrcLast = LLVMGetLastParam(Src); 169 LLVMValueRef DstLast = LLVMGetLastParam(Dst); 170 171 LLVMValueRef SrcCur = SrcFirst; 172 LLVMValueRef DstCur = DstFirst; 173 LLVMValueRef SrcNext = nullptr; 174 LLVMValueRef DstNext = nullptr; 175 while (true) { 176 const char *Name = LLVMGetValueName(SrcCur); 177 LLVMSetValueName(DstCur, Name); 178 179 VMap[SrcCur] = DstCur; 180 181 Count--; 182 SrcNext = LLVMGetNextParam(SrcCur); 183 DstNext = LLVMGetNextParam(DstCur); 184 if (SrcNext == nullptr && DstNext == nullptr) { 185 if (SrcCur != SrcLast) 186 report_fatal_error("SrcLast param does not match End"); 187 if (DstCur != DstLast) 188 report_fatal_error("DstLast param does not match End"); 189 break; 190 } 191 192 if (SrcNext == nullptr) 193 report_fatal_error("SrcNext was unexpectedly null"); 194 if (DstNext == nullptr) 195 report_fatal_error("DstNext was unexpectedly null"); 196 197 LLVMValueRef SrcPrev = LLVMGetPreviousParam(SrcNext); 198 if (SrcPrev != SrcCur) 199 report_fatal_error("SrcNext.Previous param is not Current"); 200 201 LLVMValueRef DstPrev = LLVMGetPreviousParam(DstNext); 202 if (DstPrev != DstCur) 203 report_fatal_error("DstNext.Previous param is not Current"); 204 205 SrcCur = SrcNext; 206 DstCur = DstNext; 207 } 208 209 if (Count != 0) 210 report_fatal_error("Parameter count does not match iteration"); 211 212 return VMap; 213 } 214 215 LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) { 216 if (!LLVMIsAConstant(Cst)) 217 report_fatal_error("Expected a constant"); 218 219 // Maybe it is a symbol 220 if (LLVMIsAGlobalValue(Cst)) { 221 const char *Name = LLVMGetValueName(Cst); 222 223 // Try function 224 if (LLVMIsAFunction(Cst)) { 225 LLVMValueRef Dst = LLVMGetNamedFunction(M, Name); 226 if (Dst) 227 return Dst; 228 report_fatal_error("Could not find function"); 229 } 230 231 // Try global variable 232 if (LLVMIsAGlobalVariable(Cst)) { 233 LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name); 234 if (Dst) 235 return Dst; 236 report_fatal_error("Could not find function"); 237 } 238 239 fprintf(stderr, "Could not find @%s\n", Name); 240 exit(-1); 241 } 242 243 // Try integer literal 244 if (LLVMIsAConstantInt(Cst)) 245 return LLVMConstInt(TypeCloner(M).Clone(Cst), 246 LLVMConstIntGetZExtValue(Cst), false); 247 248 // Try zeroinitializer 249 if (LLVMIsAConstantAggregateZero(Cst)) 250 return LLVMConstNull(TypeCloner(M).Clone(Cst)); 251 252 // Try constant array 253 if (LLVMIsAConstantArray(Cst)) { 254 LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); 255 unsigned EltCount = LLVMGetArrayLength(Ty); 256 SmallVector<LLVMValueRef, 8> Elts; 257 for (unsigned i = 0; i < EltCount; i++) 258 Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M)); 259 return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount); 260 } 261 262 // Try contant data array 263 if (LLVMIsAConstantDataArray(Cst)) { 264 LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); 265 unsigned EltCount = LLVMGetArrayLength(Ty); 266 SmallVector<LLVMValueRef, 8> Elts; 267 for (unsigned i = 0; i < EltCount; i++) 268 Elts.push_back(clone_constant(LLVMGetElementAsConstant(Cst, i), M)); 269 return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount); 270 } 271 272 // Try constant struct 273 if (LLVMIsAConstantStruct(Cst)) { 274 LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); 275 unsigned EltCount = LLVMCountStructElementTypes(Ty); 276 SmallVector<LLVMValueRef, 8> Elts; 277 for (unsigned i = 0; i < EltCount; i++) 278 Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M)); 279 if (LLVMGetStructName(Ty)) 280 return LLVMConstNamedStruct(Ty, Elts.data(), EltCount); 281 return LLVMConstStructInContext(LLVMGetModuleContext(M), Elts.data(), 282 EltCount, LLVMIsPackedStruct(Ty)); 283 } 284 285 // Try undef 286 if (LLVMIsUndef(Cst)) 287 return LLVMGetUndef(TypeCloner(M).Clone(Cst)); 288 289 // Try float literal 290 if (LLVMIsAConstantFP(Cst)) 291 report_fatal_error("ConstantFP is not supported"); 292 293 // This kind of constant is not supported 294 if (!LLVMIsAConstantExpr(Cst)) 295 report_fatal_error("Expected a constant expression"); 296 297 // At this point, it must be a constant expression 298 LLVMOpcode Op = LLVMGetConstOpcode(Cst); 299 switch(Op) { 300 case LLVMBitCast: 301 return LLVMConstBitCast(clone_constant(LLVMGetOperand(Cst, 0), M), 302 TypeCloner(M).Clone(Cst)); 303 default: 304 fprintf(stderr, "%d is not a supported opcode\n", Op); 305 exit(-1); 306 } 307 } 308 309 struct FunCloner { 310 LLVMValueRef Fun; 311 LLVMModuleRef M; 312 313 ValueMap VMap; 314 BasicBlockMap BBMap; 315 316 FunCloner(LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst), 317 M(LLVMGetGlobalParent(Fun)), VMap(clone_params(Src, Dst)) {} 318 319 LLVMTypeRef CloneType(LLVMTypeRef Src) { 320 return TypeCloner(M).Clone(Src); 321 } 322 323 LLVMTypeRef CloneType(LLVMValueRef Src) { 324 return TypeCloner(M).Clone(Src); 325 } 326 327 // Try to clone everything in the llvm::Value hierarchy. 328 LLVMValueRef CloneValue(LLVMValueRef Src) { 329 // First, the value may be constant. 330 if (LLVMIsAConstant(Src)) 331 return clone_constant(Src, M); 332 333 // Function argument should always be in the map already. 334 auto i = VMap.find(Src); 335 if (i != VMap.end()) 336 return i->second; 337 338 if (!LLVMIsAInstruction(Src)) 339 report_fatal_error("Expected an instruction"); 340 341 auto Ctx = LLVMGetModuleContext(M); 342 auto Builder = LLVMCreateBuilderInContext(Ctx); 343 auto BB = DeclareBB(LLVMGetInstructionParent(Src)); 344 LLVMPositionBuilderAtEnd(Builder, BB); 345 auto Dst = CloneInstruction(Src, Builder); 346 LLVMDisposeBuilder(Builder); 347 return Dst; 348 } 349 350 LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) { 351 const char *Name = LLVMGetValueName(Src); 352 if (!LLVMIsAInstruction(Src)) 353 report_fatal_error("Expected an instruction"); 354 355 // Check if this is something we already computed. 356 { 357 auto i = VMap.find(Src); 358 if (i != VMap.end()) { 359 // If we have a hit, it means we already generated the instruction 360 // as a dependancy to somethign else. We need to make sure 361 // it is ordered properly. 362 auto I = i->second; 363 LLVMInstructionRemoveFromParent(I); 364 LLVMInsertIntoBuilderWithName(Builder, I, Name); 365 return I; 366 } 367 } 368 369 // We tried everything, it must be an instruction 370 // that hasn't been generated already. 371 LLVMValueRef Dst = nullptr; 372 373 LLVMOpcode Op = LLVMGetInstructionOpcode(Src); 374 switch(Op) { 375 case LLVMRet: { 376 int OpCount = LLVMGetNumOperands(Src); 377 if (OpCount == 0) 378 Dst = LLVMBuildRetVoid(Builder); 379 else 380 Dst = LLVMBuildRet(Builder, CloneValue(LLVMGetOperand(Src, 0))); 381 break; 382 } 383 case LLVMBr: { 384 if (!LLVMIsConditional(Src)) { 385 LLVMValueRef SrcOp = LLVMGetOperand(Src, 0); 386 LLVMBasicBlockRef SrcBB = LLVMValueAsBasicBlock(SrcOp); 387 Dst = LLVMBuildBr(Builder, DeclareBB(SrcBB)); 388 break; 389 } 390 391 LLVMValueRef Cond = LLVMGetCondition(Src); 392 LLVMValueRef Else = LLVMGetOperand(Src, 1); 393 LLVMBasicBlockRef ElseBB = DeclareBB(LLVMValueAsBasicBlock(Else)); 394 LLVMValueRef Then = LLVMGetOperand(Src, 2); 395 LLVMBasicBlockRef ThenBB = DeclareBB(LLVMValueAsBasicBlock(Then)); 396 Dst = LLVMBuildCondBr(Builder, Cond, ThenBB, ElseBB); 397 break; 398 } 399 case LLVMSwitch: 400 case LLVMIndirectBr: 401 break; 402 case LLVMInvoke: { 403 SmallVector<LLVMValueRef, 8> Args; 404 int ArgCount = LLVMGetNumArgOperands(Src); 405 for (int i = 0; i < ArgCount; i++) 406 Args.push_back(CloneValue(LLVMGetOperand(Src, i))); 407 LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src)); 408 LLVMBasicBlockRef Then = DeclareBB(LLVMGetNormalDest(Src)); 409 LLVMBasicBlockRef Unwind = DeclareBB(LLVMGetUnwindDest(Src)); 410 Dst = LLVMBuildInvoke(Builder, Fn, Args.data(), ArgCount, 411 Then, Unwind, Name); 412 break; 413 } 414 case LLVMUnreachable: 415 Dst = LLVMBuildUnreachable(Builder); 416 break; 417 case LLVMAdd: { 418 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 419 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 420 Dst = LLVMBuildAdd(Builder, LHS, RHS, Name); 421 break; 422 } 423 case LLVMSub: { 424 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 425 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 426 Dst = LLVMBuildSub(Builder, LHS, RHS, Name); 427 break; 428 } 429 case LLVMMul: { 430 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 431 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 432 Dst = LLVMBuildMul(Builder, LHS, RHS, Name); 433 break; 434 } 435 case LLVMUDiv: { 436 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 437 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 438 Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name); 439 break; 440 } 441 case LLVMSDiv: { 442 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 443 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 444 Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name); 445 break; 446 } 447 case LLVMURem: { 448 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 449 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 450 Dst = LLVMBuildURem(Builder, LHS, RHS, Name); 451 break; 452 } 453 case LLVMSRem: { 454 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 455 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 456 Dst = LLVMBuildSRem(Builder, LHS, RHS, Name); 457 break; 458 } 459 case LLVMShl: { 460 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 461 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 462 Dst = LLVMBuildShl(Builder, LHS, RHS, Name); 463 break; 464 } 465 case LLVMLShr: { 466 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 467 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 468 Dst = LLVMBuildLShr(Builder, LHS, RHS, Name); 469 break; 470 } 471 case LLVMAShr: { 472 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 473 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 474 Dst = LLVMBuildAShr(Builder, LHS, RHS, Name); 475 break; 476 } 477 case LLVMAnd: { 478 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 479 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 480 Dst = LLVMBuildAnd(Builder, LHS, RHS, Name); 481 break; 482 } 483 case LLVMOr: { 484 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 485 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 486 Dst = LLVMBuildOr(Builder, LHS, RHS, Name); 487 break; 488 } 489 case LLVMXor: { 490 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 491 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 492 Dst = LLVMBuildXor(Builder, LHS, RHS, Name); 493 break; 494 } 495 case LLVMAlloca: { 496 LLVMTypeRef Ty = CloneType(LLVMGetAllocatedType(Src)); 497 Dst = LLVMBuildAlloca(Builder, Ty, Name); 498 break; 499 } 500 case LLVMLoad: { 501 LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0)); 502 Dst = LLVMBuildLoad(Builder, Ptr, Name); 503 LLVMSetAlignment(Dst, LLVMGetAlignment(Src)); 504 break; 505 } 506 case LLVMStore: { 507 LLVMValueRef Val = CloneValue(LLVMGetOperand(Src, 0)); 508 LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 1)); 509 Dst = LLVMBuildStore(Builder, Val, Ptr); 510 LLVMSetAlignment(Dst, LLVMGetAlignment(Src)); 511 break; 512 } 513 case LLVMGetElementPtr: { 514 LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0)); 515 SmallVector<LLVMValueRef, 8> Idx; 516 int NumIdx = LLVMGetNumIndices(Src); 517 for (int i = 1; i <= NumIdx; i++) 518 Idx.push_back(CloneValue(LLVMGetOperand(Src, i))); 519 if (LLVMIsInBounds(Src)) 520 Dst = LLVMBuildInBoundsGEP(Builder, Ptr, Idx.data(), NumIdx, Name); 521 else 522 Dst = LLVMBuildGEP(Builder, Ptr, Idx.data(), NumIdx, Name); 523 break; 524 } 525 case LLVMAtomicCmpXchg: { 526 LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0)); 527 LLVMValueRef Cmp = CloneValue(LLVMGetOperand(Src, 1)); 528 LLVMValueRef New = CloneValue(LLVMGetOperand(Src, 2)); 529 LLVMAtomicOrdering Succ = LLVMGetCmpXchgSuccessOrdering(Src); 530 LLVMAtomicOrdering Fail = LLVMGetCmpXchgFailureOrdering(Src); 531 LLVMBool SingleThread = LLVMIsAtomicSingleThread(Src); 532 533 Dst = LLVMBuildAtomicCmpXchg(Builder, Ptr, Cmp, New, Succ, Fail, 534 SingleThread); 535 } break; 536 case LLVMBitCast: { 537 LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 0)); 538 Dst = LLVMBuildBitCast(Builder, V, CloneType(Src), Name); 539 break; 540 } 541 case LLVMICmp: { 542 LLVMIntPredicate Pred = LLVMGetICmpPredicate(Src); 543 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 544 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 545 Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name); 546 break; 547 } 548 case LLVMPHI: { 549 // We need to agressively set things here because of loops. 550 VMap[Src] = Dst = LLVMBuildPhi(Builder, CloneType(Src), Name); 551 552 SmallVector<LLVMValueRef, 8> Values; 553 SmallVector<LLVMBasicBlockRef, 8> Blocks; 554 555 unsigned IncomingCount = LLVMCountIncoming(Src); 556 for (unsigned i = 0; i < IncomingCount; ++i) { 557 Blocks.push_back(DeclareBB(LLVMGetIncomingBlock(Src, i))); 558 Values.push_back(CloneValue(LLVMGetIncomingValue(Src, i))); 559 } 560 561 LLVMAddIncoming(Dst, Values.data(), Blocks.data(), IncomingCount); 562 return Dst; 563 } 564 case LLVMCall: { 565 SmallVector<LLVMValueRef, 8> Args; 566 int ArgCount = LLVMGetNumArgOperands(Src); 567 for (int i = 0; i < ArgCount; i++) 568 Args.push_back(CloneValue(LLVMGetOperand(Src, i))); 569 LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src)); 570 Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name); 571 LLVMSetTailCall(Dst, LLVMIsTailCall(Src)); 572 break; 573 } 574 case LLVMResume: { 575 Dst = LLVMBuildResume(Builder, CloneValue(LLVMGetOperand(Src, 0))); 576 break; 577 } 578 case LLVMLandingPad: { 579 // The landing pad API is a bit screwed up for historical reasons. 580 Dst = LLVMBuildLandingPad(Builder, CloneType(Src), nullptr, 0, Name); 581 unsigned NumClauses = LLVMGetNumClauses(Src); 582 for (unsigned i = 0; i < NumClauses; ++i) 583 LLVMAddClause(Dst, CloneValue(LLVMGetClause(Src, i))); 584 LLVMSetCleanup(Dst, LLVMIsCleanup(Src)); 585 break; 586 } 587 case LLVMExtractValue: { 588 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0)); 589 if (LLVMGetNumIndices(Src) != 1) 590 report_fatal_error("Expected only one indice"); 591 auto I = LLVMGetIndices(Src)[0]; 592 Dst = LLVMBuildExtractValue(Builder, Agg, I, Name); 593 break; 594 } 595 case LLVMInsertValue: { 596 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0)); 597 LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1)); 598 if (LLVMGetNumIndices(Src) != 1) 599 report_fatal_error("Expected only one indice"); 600 auto I = LLVMGetIndices(Src)[0]; 601 Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name); 602 break; 603 } 604 default: 605 break; 606 } 607 608 if (Dst == nullptr) { 609 fprintf(stderr, "%d is not a supported opcode\n", Op); 610 exit(-1); 611 } 612 613 return VMap[Src] = Dst; 614 } 615 616 LLVMBasicBlockRef DeclareBB(LLVMBasicBlockRef Src) { 617 // Check if this is something we already computed. 618 { 619 auto i = BBMap.find(Src); 620 if (i != BBMap.end()) { 621 return i->second; 622 } 623 } 624 625 LLVMValueRef V = LLVMBasicBlockAsValue(Src); 626 if (!LLVMValueIsBasicBlock(V) || LLVMValueAsBasicBlock(V) != Src) 627 report_fatal_error("Basic block is not a basic block"); 628 629 const char *Name = LLVMGetBasicBlockName(Src); 630 const char *VName = LLVMGetValueName(V); 631 if (Name != VName) 632 report_fatal_error("Basic block name mismatch"); 633 634 LLVMBasicBlockRef BB = LLVMAppendBasicBlock(Fun, Name); 635 return BBMap[Src] = BB; 636 } 637 638 LLVMBasicBlockRef CloneBB(LLVMBasicBlockRef Src) { 639 LLVMBasicBlockRef BB = DeclareBB(Src); 640 641 // Make sure ordering is correct. 642 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Src); 643 if (Prev) 644 LLVMMoveBasicBlockAfter(BB, DeclareBB(Prev)); 645 646 LLVMValueRef First = LLVMGetFirstInstruction(Src); 647 LLVMValueRef Last = LLVMGetLastInstruction(Src); 648 649 if (First == nullptr) { 650 if (Last != nullptr) 651 report_fatal_error("Has no first instruction, but last one"); 652 return BB; 653 } 654 655 auto Ctx = LLVMGetModuleContext(M); 656 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx); 657 LLVMPositionBuilderAtEnd(Builder, BB); 658 659 LLVMValueRef Cur = First; 660 LLVMValueRef Next = nullptr; 661 while(true) { 662 CloneInstruction(Cur, Builder); 663 Next = LLVMGetNextInstruction(Cur); 664 if (Next == nullptr) { 665 if (Cur != Last) 666 report_fatal_error("Final instruction does not match Last"); 667 break; 668 } 669 670 LLVMValueRef Prev = LLVMGetPreviousInstruction(Next); 671 if (Prev != Cur) 672 report_fatal_error("Next.Previous instruction is not Current"); 673 674 Cur = Next; 675 } 676 677 LLVMDisposeBuilder(Builder); 678 return BB; 679 } 680 681 void CloneBBs(LLVMValueRef Src) { 682 unsigned Count = LLVMCountBasicBlocks(Src); 683 if (Count == 0) 684 return; 685 686 LLVMBasicBlockRef First = LLVMGetFirstBasicBlock(Src); 687 LLVMBasicBlockRef Last = LLVMGetLastBasicBlock(Src); 688 689 LLVMBasicBlockRef Cur = First; 690 LLVMBasicBlockRef Next = nullptr; 691 while(true) { 692 CloneBB(Cur); 693 Count--; 694 Next = LLVMGetNextBasicBlock(Cur); 695 if (Next == nullptr) { 696 if (Cur != Last) 697 report_fatal_error("Final basic block does not match Last"); 698 break; 699 } 700 701 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Next); 702 if (Prev != Cur) 703 report_fatal_error("Next.Previous basic bloc is not Current"); 704 705 Cur = Next; 706 } 707 708 if (Count != 0) 709 report_fatal_error("Basic block count does not match iterration"); 710 } 711 }; 712 713 static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) { 714 LLVMValueRef Begin = LLVMGetFirstGlobal(Src); 715 LLVMValueRef End = LLVMGetLastGlobal(Src); 716 717 LLVMValueRef Cur = Begin; 718 LLVMValueRef Next = nullptr; 719 if (!Begin) { 720 if (End != nullptr) 721 report_fatal_error("Range has an end but no begining"); 722 goto FunDecl; 723 } 724 725 while (true) { 726 const char *Name = LLVMGetValueName(Cur); 727 if (LLVMGetNamedGlobal(M, Name)) 728 report_fatal_error("GlobalVariable already cloned"); 729 LLVMAddGlobal(M, LLVMGetElementType(TypeCloner(M).Clone(Cur)), Name); 730 731 Next = LLVMGetNextGlobal(Cur); 732 if (Next == nullptr) { 733 if (Cur != End) 734 report_fatal_error(""); 735 break; 736 } 737 738 LLVMValueRef Prev = LLVMGetPreviousGlobal(Next); 739 if (Prev != Cur) 740 report_fatal_error("Next.Previous global is not Current"); 741 742 Cur = Next; 743 } 744 745 FunDecl: 746 Begin = LLVMGetFirstFunction(Src); 747 End = LLVMGetLastFunction(Src); 748 if (!Begin) { 749 if (End != nullptr) 750 report_fatal_error("Range has an end but no begining"); 751 return; 752 } 753 754 Cur = Begin; 755 Next = nullptr; 756 while (true) { 757 const char *Name = LLVMGetValueName(Cur); 758 if (LLVMGetNamedFunction(M, Name)) 759 report_fatal_error("Function already cloned"); 760 LLVMAddFunction(M, Name, LLVMGetElementType(TypeCloner(M).Clone(Cur))); 761 762 Next = LLVMGetNextFunction(Cur); 763 if (Next == nullptr) { 764 if (Cur != End) 765 report_fatal_error("Last function does not match End"); 766 break; 767 } 768 769 LLVMValueRef Prev = LLVMGetPreviousFunction(Next); 770 if (Prev != Cur) 771 report_fatal_error("Next.Previous function is not Current"); 772 773 Cur = Next; 774 } 775 } 776 777 static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) { 778 LLVMValueRef Begin = LLVMGetFirstGlobal(Src); 779 LLVMValueRef End = LLVMGetLastGlobal(Src); 780 781 LLVMValueRef Cur = Begin; 782 LLVMValueRef Next = nullptr; 783 if (!Begin) { 784 if (End != nullptr) 785 report_fatal_error("Range has an end but no begining"); 786 goto FunClone; 787 } 788 789 while (true) { 790 const char *Name = LLVMGetValueName(Cur); 791 LLVMValueRef G = LLVMGetNamedGlobal(M, Name); 792 if (!G) 793 report_fatal_error("GlobalVariable must have been declared already"); 794 795 if (auto I = LLVMGetInitializer(Cur)) 796 LLVMSetInitializer(G, clone_constant(I, M)); 797 798 LLVMSetGlobalConstant(G, LLVMIsGlobalConstant(Cur)); 799 LLVMSetThreadLocal(G, LLVMIsThreadLocal(Cur)); 800 LLVMSetExternallyInitialized(G, LLVMIsExternallyInitialized(Cur)); 801 LLVMSetLinkage(G, LLVMGetLinkage(Cur)); 802 LLVMSetSection(G, LLVMGetSection(Cur)); 803 LLVMSetVisibility(G, LLVMGetVisibility(Cur)); 804 LLVMSetUnnamedAddr(G, LLVMHasUnnamedAddr(Cur)); 805 LLVMSetAlignment(G, LLVMGetAlignment(Cur)); 806 807 Next = LLVMGetNextGlobal(Cur); 808 if (Next == nullptr) { 809 if (Cur != End) 810 report_fatal_error(""); 811 break; 812 } 813 814 LLVMValueRef Prev = LLVMGetPreviousGlobal(Next); 815 if (Prev != Cur) 816 report_fatal_error("Next.Previous global is not Current"); 817 818 Cur = Next; 819 } 820 821 FunClone: 822 Begin = LLVMGetFirstFunction(Src); 823 End = LLVMGetLastFunction(Src); 824 if (!Begin) { 825 if (End != nullptr) 826 report_fatal_error("Range has an end but no begining"); 827 return; 828 } 829 830 Cur = Begin; 831 Next = nullptr; 832 while (true) { 833 const char *Name = LLVMGetValueName(Cur); 834 LLVMValueRef Fun = LLVMGetNamedFunction(M, Name); 835 if (!Fun) 836 report_fatal_error("Function must have been declared already"); 837 838 if (LLVMHasPersonalityFn(Cur)) { 839 const char *FName = LLVMGetValueName(LLVMGetPersonalityFn(Cur)); 840 LLVMValueRef P = LLVMGetNamedFunction(M, FName); 841 if (!P) 842 report_fatal_error("Could not find personality function"); 843 LLVMSetPersonalityFn(Fun, P); 844 } 845 846 FunCloner FC(Cur, Fun); 847 FC.CloneBBs(Cur); 848 849 Next = LLVMGetNextFunction(Cur); 850 if (Next == nullptr) { 851 if (Cur != End) 852 report_fatal_error("Last function does not match End"); 853 break; 854 } 855 856 LLVMValueRef Prev = LLVMGetPreviousFunction(Next); 857 if (Prev != Cur) 858 report_fatal_error("Next.Previous function is not Current"); 859 860 Cur = Next; 861 } 862 } 863 864 int llvm_echo(void) { 865 LLVMEnablePrettyStackTrace(); 866 867 LLVMModuleRef Src = llvm_load_module(false, true); 868 869 LLVMContextRef Ctx = LLVMContextCreate(); 870 LLVMModuleRef M = LLVMModuleCreateWithNameInContext("<stdin>", Ctx); 871 872 LLVMSetTarget(M, LLVMGetTarget(Src)); 873 LLVMSetModuleDataLayout(M, LLVMGetModuleDataLayout(Src)); 874 if (strcmp(LLVMGetDataLayoutStr(M), LLVMGetDataLayoutStr(Src))) 875 report_fatal_error("Inconsistent DataLayout string representation"); 876 877 declare_symbols(Src, M); 878 clone_symbols(Src, M); 879 char *Str = LLVMPrintModuleToString(M); 880 fputs(Str, stdout); 881 882 LLVMDisposeMessage(Str); 883 LLVMDisposeModule(M); 884 LLVMContextDispose(Ctx); 885 886 return 0; 887 } 888