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 constant struct 263 if (LLVMIsAConstantStruct(Cst)) { 264 LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); 265 unsigned EltCount = LLVMCountStructElementTypes(Ty); 266 SmallVector<LLVMValueRef, 8> Elts; 267 for (unsigned i = 0; i < EltCount; i++) 268 Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M)); 269 if (LLVMGetStructName(Ty)) 270 return LLVMConstNamedStruct(Ty, Elts.data(), EltCount); 271 return LLVMConstStructInContext(LLVMGetModuleContext(M), Elts.data(), 272 EltCount, LLVMIsPackedStruct(Ty)); 273 } 274 275 // Try undef 276 if (LLVMIsUndef(Cst)) 277 return LLVMGetUndef(TypeCloner(M).Clone(Cst)); 278 279 // Try float literal 280 if (LLVMIsAConstantFP(Cst)) 281 report_fatal_error("ConstantFP is not supported"); 282 283 // This kind of constant is not supported 284 if (!LLVMIsAConstantExpr(Cst)) 285 report_fatal_error("Expected a constant expression"); 286 287 // At this point, it must be a constant expression 288 LLVMOpcode Op = LLVMGetConstOpcode(Cst); 289 switch(Op) { 290 case LLVMBitCast: 291 return LLVMConstBitCast(clone_constant(LLVMGetOperand(Cst, 0), M), 292 TypeCloner(M).Clone(Cst)); 293 default: 294 fprintf(stderr, "%d is not a supported opcode\n", Op); 295 exit(-1); 296 } 297 } 298 299 struct FunCloner { 300 LLVMValueRef Fun; 301 LLVMModuleRef M; 302 303 ValueMap VMap; 304 BasicBlockMap BBMap; 305 306 FunCloner(LLVMValueRef Src, LLVMValueRef Dst): Fun(Dst), 307 M(LLVMGetGlobalParent(Fun)), VMap(clone_params(Src, Dst)) {} 308 309 LLVMTypeRef CloneType(LLVMTypeRef Src) { 310 return TypeCloner(M).Clone(Src); 311 } 312 313 LLVMTypeRef CloneType(LLVMValueRef Src) { 314 return TypeCloner(M).Clone(Src); 315 } 316 317 // Try to clone everything in the llvm::Value hierarchy. 318 LLVMValueRef CloneValue(LLVMValueRef Src) { 319 // First, the value may be constant. 320 if (LLVMIsAConstant(Src)) 321 return clone_constant(Src, M); 322 323 // Function argument should always be in the map already. 324 auto i = VMap.find(Src); 325 if (i != VMap.end()) 326 return i->second; 327 328 if (!LLVMIsAInstruction(Src)) 329 report_fatal_error("Expected an instruction"); 330 331 auto Ctx = LLVMGetModuleContext(M); 332 auto Builder = LLVMCreateBuilderInContext(Ctx); 333 auto BB = DeclareBB(LLVMGetInstructionParent(Src)); 334 LLVMPositionBuilderAtEnd(Builder, BB); 335 auto Dst = CloneInstruction(Src, Builder); 336 LLVMDisposeBuilder(Builder); 337 return Dst; 338 } 339 340 LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) { 341 const char *Name = LLVMGetValueName(Src); 342 if (!LLVMIsAInstruction(Src)) 343 report_fatal_error("Expected an instruction"); 344 345 // Check if this is something we already computed. 346 { 347 auto i = VMap.find(Src); 348 if (i != VMap.end()) { 349 // If we have a hit, it means we already generated the instruction 350 // as a dependancy to somethign else. We need to make sure 351 // it is ordered properly. 352 auto I = i->second; 353 LLVMInstructionRemoveFromParent(I); 354 LLVMInsertIntoBuilderWithName(Builder, I, Name); 355 return I; 356 } 357 } 358 359 // We tried everything, it must be an instruction 360 // that hasn't been generated already. 361 LLVMValueRef Dst = nullptr; 362 363 LLVMOpcode Op = LLVMGetInstructionOpcode(Src); 364 switch(Op) { 365 case LLVMRet: { 366 int OpCount = LLVMGetNumOperands(Src); 367 if (OpCount == 0) 368 Dst = LLVMBuildRetVoid(Builder); 369 else 370 Dst = LLVMBuildRet(Builder, CloneValue(LLVMGetOperand(Src, 0))); 371 break; 372 } 373 case LLVMBr: { 374 if (!LLVMIsConditional(Src)) { 375 LLVMValueRef SrcOp = LLVMGetOperand(Src, 0); 376 LLVMBasicBlockRef SrcBB = LLVMValueAsBasicBlock(SrcOp); 377 Dst = LLVMBuildBr(Builder, DeclareBB(SrcBB)); 378 break; 379 } 380 381 LLVMValueRef Cond = LLVMGetCondition(Src); 382 LLVMValueRef Else = LLVMGetOperand(Src, 1); 383 LLVMBasicBlockRef ElseBB = DeclareBB(LLVMValueAsBasicBlock(Else)); 384 LLVMValueRef Then = LLVMGetOperand(Src, 2); 385 LLVMBasicBlockRef ThenBB = DeclareBB(LLVMValueAsBasicBlock(Then)); 386 Dst = LLVMBuildCondBr(Builder, Cond, ThenBB, ElseBB); 387 break; 388 } 389 case LLVMSwitch: 390 case LLVMIndirectBr: 391 break; 392 case LLVMInvoke: { 393 SmallVector<LLVMValueRef, 8> Args; 394 int ArgCount = LLVMGetNumArgOperands(Src); 395 for (int i = 0; i < ArgCount; i++) 396 Args.push_back(CloneValue(LLVMGetOperand(Src, i))); 397 LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src)); 398 LLVMBasicBlockRef Then = DeclareBB(LLVMGetNormalDest(Src)); 399 LLVMBasicBlockRef Unwind = DeclareBB(LLVMGetUnwindDest(Src)); 400 Dst = LLVMBuildInvoke(Builder, Fn, Args.data(), ArgCount, 401 Then, Unwind, Name); 402 break; 403 } 404 case LLVMUnreachable: 405 Dst = LLVMBuildUnreachable(Builder); 406 break; 407 case LLVMAdd: { 408 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 409 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 410 Dst = LLVMBuildAdd(Builder, LHS, RHS, Name); 411 break; 412 } 413 case LLVMSub: { 414 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 415 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 416 Dst = LLVMBuildSub(Builder, LHS, RHS, Name); 417 break; 418 } 419 case LLVMMul: { 420 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 421 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 422 Dst = LLVMBuildMul(Builder, LHS, RHS, Name); 423 break; 424 } 425 case LLVMUDiv: { 426 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 427 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 428 Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name); 429 break; 430 } 431 case LLVMSDiv: { 432 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 433 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 434 Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name); 435 break; 436 } 437 case LLVMURem: { 438 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 439 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 440 Dst = LLVMBuildURem(Builder, LHS, RHS, Name); 441 break; 442 } 443 case LLVMSRem: { 444 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 445 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 446 Dst = LLVMBuildSRem(Builder, LHS, RHS, Name); 447 break; 448 } 449 case LLVMShl: { 450 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 451 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 452 Dst = LLVMBuildShl(Builder, LHS, RHS, Name); 453 break; 454 } 455 case LLVMLShr: { 456 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 457 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 458 Dst = LLVMBuildLShr(Builder, LHS, RHS, Name); 459 break; 460 } 461 case LLVMAShr: { 462 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 463 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 464 Dst = LLVMBuildAShr(Builder, LHS, RHS, Name); 465 break; 466 } 467 case LLVMAnd: { 468 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 469 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 470 Dst = LLVMBuildAnd(Builder, LHS, RHS, Name); 471 break; 472 } 473 case LLVMOr: { 474 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 475 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 476 Dst = LLVMBuildOr(Builder, LHS, RHS, Name); 477 break; 478 } 479 case LLVMXor: { 480 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 481 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 482 Dst = LLVMBuildXor(Builder, LHS, RHS, Name); 483 break; 484 } 485 case LLVMAlloca: { 486 LLVMTypeRef Ty = CloneType(LLVMGetAllocatedType(Src)); 487 Dst = LLVMBuildAlloca(Builder, Ty, Name); 488 break; 489 } 490 case LLVMLoad: { 491 LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0)); 492 Dst = LLVMBuildLoad(Builder, Ptr, Name); 493 LLVMSetAlignment(Dst, LLVMGetAlignment(Src)); 494 break; 495 } 496 case LLVMStore: { 497 LLVMValueRef Val = CloneValue(LLVMGetOperand(Src, 0)); 498 LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 1)); 499 Dst = LLVMBuildStore(Builder, Val, Ptr); 500 LLVMSetAlignment(Dst, LLVMGetAlignment(Src)); 501 break; 502 } 503 case LLVMGetElementPtr: { 504 LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0)); 505 SmallVector<LLVMValueRef, 8> Idx; 506 int NumIdx = LLVMGetNumIndices(Src); 507 for (int i = 1; i <= NumIdx; i++) 508 Idx.push_back(CloneValue(LLVMGetOperand(Src, i))); 509 if (LLVMIsInBounds(Src)) 510 Dst = LLVMBuildInBoundsGEP(Builder, Ptr, Idx.data(), NumIdx, Name); 511 else 512 Dst = LLVMBuildGEP(Builder, Ptr, Idx.data(), NumIdx, Name); 513 break; 514 } 515 case LLVMBitCast: { 516 LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 0)); 517 Dst = LLVMBuildBitCast(Builder, V, CloneType(Src), Name); 518 break; 519 } 520 case LLVMICmp: { 521 LLVMIntPredicate Pred = LLVMGetICmpPredicate(Src); 522 LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0)); 523 LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1)); 524 Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name); 525 break; 526 } 527 case LLVMPHI: { 528 // We need to agressively set things here because of loops. 529 VMap[Src] = Dst = LLVMBuildPhi(Builder, CloneType(Src), Name); 530 531 SmallVector<LLVMValueRef, 8> Values; 532 SmallVector<LLVMBasicBlockRef, 8> Blocks; 533 534 unsigned IncomingCount = LLVMCountIncoming(Src); 535 for (unsigned i = 0; i < IncomingCount; ++i) { 536 Blocks.push_back(DeclareBB(LLVMGetIncomingBlock(Src, i))); 537 Values.push_back(CloneValue(LLVMGetIncomingValue(Src, i))); 538 } 539 540 LLVMAddIncoming(Dst, Values.data(), Blocks.data(), IncomingCount); 541 return Dst; 542 } 543 case LLVMCall: { 544 SmallVector<LLVMValueRef, 8> Args; 545 int ArgCount = LLVMGetNumArgOperands(Src); 546 for (int i = 0; i < ArgCount; i++) 547 Args.push_back(CloneValue(LLVMGetOperand(Src, i))); 548 LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src)); 549 Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name); 550 LLVMSetTailCall(Dst, LLVMIsTailCall(Src)); 551 break; 552 } 553 case LLVMResume: { 554 Dst = LLVMBuildResume(Builder, CloneValue(LLVMGetOperand(Src, 0))); 555 break; 556 } 557 case LLVMLandingPad: { 558 // The landing pad API is a bit screwed up for historical reasons. 559 Dst = LLVMBuildLandingPad(Builder, CloneType(Src), nullptr, 0, Name); 560 unsigned NumClauses = LLVMGetNumClauses(Src); 561 for (unsigned i = 0; i < NumClauses; ++i) 562 LLVMAddClause(Dst, CloneValue(LLVMGetClause(Src, i))); 563 LLVMSetCleanup(Dst, LLVMIsCleanup(Src)); 564 break; 565 } 566 case LLVMExtractValue: { 567 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0)); 568 if (LLVMGetNumIndices(Src) != 1) 569 report_fatal_error("Expected only one indice"); 570 auto I = LLVMGetIndices(Src)[0]; 571 Dst = LLVMBuildExtractValue(Builder, Agg, I, Name); 572 break; 573 } 574 case LLVMInsertValue: { 575 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0)); 576 LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1)); 577 if (LLVMGetNumIndices(Src) != 1) 578 report_fatal_error("Expected only one indice"); 579 auto I = LLVMGetIndices(Src)[0]; 580 Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name); 581 break; 582 } 583 default: 584 break; 585 } 586 587 if (Dst == nullptr) { 588 fprintf(stderr, "%d is not a supported opcode\n", Op); 589 exit(-1); 590 } 591 592 return VMap[Src] = Dst; 593 } 594 595 LLVMBasicBlockRef DeclareBB(LLVMBasicBlockRef Src) { 596 // Check if this is something we already computed. 597 { 598 auto i = BBMap.find(Src); 599 if (i != BBMap.end()) { 600 return i->second; 601 } 602 } 603 604 LLVMValueRef V = LLVMBasicBlockAsValue(Src); 605 if (!LLVMValueIsBasicBlock(V) || LLVMValueAsBasicBlock(V) != Src) 606 report_fatal_error("Basic block is not a basic block"); 607 608 const char *Name = LLVMGetBasicBlockName(Src); 609 const char *VName = LLVMGetValueName(V); 610 if (Name != VName) 611 report_fatal_error("Basic block name mismatch"); 612 613 LLVMBasicBlockRef BB = LLVMAppendBasicBlock(Fun, Name); 614 return BBMap[Src] = BB; 615 } 616 617 LLVMBasicBlockRef CloneBB(LLVMBasicBlockRef Src) { 618 LLVMBasicBlockRef BB = DeclareBB(Src); 619 620 // Make sure ordering is correct. 621 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Src); 622 if (Prev) 623 LLVMMoveBasicBlockAfter(BB, DeclareBB(Prev)); 624 625 LLVMValueRef First = LLVMGetFirstInstruction(Src); 626 LLVMValueRef Last = LLVMGetLastInstruction(Src); 627 628 if (First == nullptr) { 629 if (Last != nullptr) 630 report_fatal_error("Has no first instruction, but last one"); 631 return BB; 632 } 633 634 auto Ctx = LLVMGetModuleContext(M); 635 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx); 636 LLVMPositionBuilderAtEnd(Builder, BB); 637 638 LLVMValueRef Cur = First; 639 LLVMValueRef Next = nullptr; 640 while(true) { 641 CloneInstruction(Cur, Builder); 642 Next = LLVMGetNextInstruction(Cur); 643 if (Next == nullptr) { 644 if (Cur != Last) 645 report_fatal_error("Final instruction does not match Last"); 646 break; 647 } 648 649 LLVMValueRef Prev = LLVMGetPreviousInstruction(Next); 650 if (Prev != Cur) 651 report_fatal_error("Next.Previous instruction is not Current"); 652 653 Cur = Next; 654 } 655 656 LLVMDisposeBuilder(Builder); 657 return BB; 658 } 659 660 void CloneBBs(LLVMValueRef Src) { 661 unsigned Count = LLVMCountBasicBlocks(Src); 662 if (Count == 0) 663 return; 664 665 LLVMBasicBlockRef First = LLVMGetFirstBasicBlock(Src); 666 LLVMBasicBlockRef Last = LLVMGetLastBasicBlock(Src); 667 668 LLVMBasicBlockRef Cur = First; 669 LLVMBasicBlockRef Next = nullptr; 670 while(true) { 671 CloneBB(Cur); 672 Count--; 673 Next = LLVMGetNextBasicBlock(Cur); 674 if (Next == nullptr) { 675 if (Cur != Last) 676 report_fatal_error("Final basic block does not match Last"); 677 break; 678 } 679 680 LLVMBasicBlockRef Prev = LLVMGetPreviousBasicBlock(Next); 681 if (Prev != Cur) 682 report_fatal_error("Next.Previous basic bloc is not Current"); 683 684 Cur = Next; 685 } 686 687 if (Count != 0) 688 report_fatal_error("Basic block count does not match iterration"); 689 } 690 }; 691 692 static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) { 693 LLVMValueRef Begin = LLVMGetFirstGlobal(Src); 694 LLVMValueRef End = LLVMGetLastGlobal(Src); 695 696 LLVMValueRef Cur = Begin; 697 LLVMValueRef Next = nullptr; 698 if (!Begin) { 699 if (End != nullptr) 700 report_fatal_error("Range has an end but no begining"); 701 goto FunDecl; 702 } 703 704 while (true) { 705 const char *Name = LLVMGetValueName(Cur); 706 if (LLVMGetNamedGlobal(M, Name)) 707 report_fatal_error("GlobalVariable already cloned"); 708 LLVMAddGlobal(M, LLVMGetElementType(TypeCloner(M).Clone(Cur)), Name); 709 710 Next = LLVMGetNextGlobal(Cur); 711 if (Next == nullptr) { 712 if (Cur != End) 713 report_fatal_error(""); 714 break; 715 } 716 717 LLVMValueRef Prev = LLVMGetPreviousGlobal(Next); 718 if (Prev != Cur) 719 report_fatal_error("Next.Previous global is not Current"); 720 721 Cur = Next; 722 } 723 724 FunDecl: 725 Begin = LLVMGetFirstFunction(Src); 726 End = LLVMGetLastFunction(Src); 727 if (!Begin) { 728 if (End != nullptr) 729 report_fatal_error("Range has an end but no begining"); 730 return; 731 } 732 733 Cur = Begin; 734 Next = nullptr; 735 while (true) { 736 const char *Name = LLVMGetValueName(Cur); 737 if (LLVMGetNamedFunction(M, Name)) 738 report_fatal_error("Function already cloned"); 739 LLVMAddFunction(M, Name, LLVMGetElementType(TypeCloner(M).Clone(Cur))); 740 741 Next = LLVMGetNextFunction(Cur); 742 if (Next == nullptr) { 743 if (Cur != End) 744 report_fatal_error("Last function does not match End"); 745 break; 746 } 747 748 LLVMValueRef Prev = LLVMGetPreviousFunction(Next); 749 if (Prev != Cur) 750 report_fatal_error("Next.Previous function is not Current"); 751 752 Cur = Next; 753 } 754 } 755 756 static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) { 757 LLVMValueRef Begin = LLVMGetFirstGlobal(Src); 758 LLVMValueRef End = LLVMGetLastGlobal(Src); 759 760 LLVMValueRef Cur = Begin; 761 LLVMValueRef Next = nullptr; 762 if (!Begin) { 763 if (End != nullptr) 764 report_fatal_error("Range has an end but no begining"); 765 goto FunClone; 766 } 767 768 while (true) { 769 const char *Name = LLVMGetValueName(Cur); 770 LLVMValueRef G = LLVMGetNamedGlobal(M, Name); 771 if (!G) 772 report_fatal_error("GlobalVariable must have been declared already"); 773 774 if (auto I = LLVMGetInitializer(Cur)) 775 LLVMSetInitializer(G, clone_constant(I, M)); 776 777 LLVMSetGlobalConstant(G, LLVMIsGlobalConstant(Cur)); 778 LLVMSetThreadLocal(G, LLVMIsThreadLocal(Cur)); 779 LLVMSetExternallyInitialized(G, LLVMIsExternallyInitialized(Cur)); 780 LLVMSetLinkage(G, LLVMGetLinkage(Cur)); 781 LLVMSetSection(G, LLVMGetSection(Cur)); 782 LLVMSetVisibility(G, LLVMGetVisibility(Cur)); 783 LLVMSetUnnamedAddr(G, LLVMHasUnnamedAddr(Cur)); 784 LLVMSetAlignment(G, LLVMGetAlignment(Cur)); 785 786 Next = LLVMGetNextGlobal(Cur); 787 if (Next == nullptr) { 788 if (Cur != End) 789 report_fatal_error(""); 790 break; 791 } 792 793 LLVMValueRef Prev = LLVMGetPreviousGlobal(Next); 794 if (Prev != Cur) 795 report_fatal_error("Next.Previous global is not Current"); 796 797 Cur = Next; 798 } 799 800 FunClone: 801 Begin = LLVMGetFirstFunction(Src); 802 End = LLVMGetLastFunction(Src); 803 if (!Begin) { 804 if (End != nullptr) 805 report_fatal_error("Range has an end but no begining"); 806 return; 807 } 808 809 Cur = Begin; 810 Next = nullptr; 811 while (true) { 812 const char *Name = LLVMGetValueName(Cur); 813 LLVMValueRef Fun = LLVMGetNamedFunction(M, Name); 814 if (!Fun) 815 report_fatal_error("Function must have been declared already"); 816 817 if (LLVMHasPersonalityFn(Cur)) { 818 const char *FName = LLVMGetValueName(LLVMGetPersonalityFn(Cur)); 819 LLVMValueRef P = LLVMGetNamedFunction(M, FName); 820 if (!P) 821 report_fatal_error("Could not find personality function"); 822 LLVMSetPersonalityFn(Fun, P); 823 } 824 825 FunCloner FC(Cur, Fun); 826 FC.CloneBBs(Cur); 827 828 Next = LLVMGetNextFunction(Cur); 829 if (Next == nullptr) { 830 if (Cur != End) 831 report_fatal_error("Last function does not match End"); 832 break; 833 } 834 835 LLVMValueRef Prev = LLVMGetPreviousFunction(Next); 836 if (Prev != Cur) 837 report_fatal_error("Next.Previous function is not Current"); 838 839 Cur = Next; 840 } 841 } 842 843 int llvm_echo(void) { 844 LLVMEnablePrettyStackTrace(); 845 846 LLVMModuleRef Src = llvm_load_module(false, true); 847 848 LLVMContextRef Ctx = LLVMContextCreate(); 849 LLVMModuleRef M = LLVMModuleCreateWithNameInContext("<stdin>", Ctx); 850 851 LLVMSetTarget(M, LLVMGetTarget(Src)); 852 LLVMSetModuleDataLayout(M, LLVMGetModuleDataLayout(Src)); 853 if (strcmp(LLVMGetDataLayoutStr(M), LLVMGetDataLayoutStr(Src))) 854 report_fatal_error("Inconsistent DataLayout string representation"); 855 856 declare_symbols(Src, M); 857 clone_symbols(Src, M); 858 char *Str = LLVMPrintModuleToString(M); 859 fputs(Str, stdout); 860 861 LLVMDisposeMessage(Str); 862 LLVMDisposeModule(M); 863 LLVMContextDispose(Ctx); 864 865 return 0; 866 } 867