echo.cpp 30 KB

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