jit_dump.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * Copyright (C) 2021 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "jit_dump.h"
  6. #include "jit_compiler.h"
  7. #include "jit_codegen.h"
  8. void
  9. jit_dump_reg(JitCompContext *cc, JitReg reg)
  10. {
  11. unsigned kind = jit_reg_kind(reg);
  12. unsigned no = jit_reg_no(reg);
  13. switch (kind) {
  14. case JIT_REG_KIND_VOID:
  15. os_printf("VOID");
  16. break;
  17. case JIT_REG_KIND_I32:
  18. if (jit_reg_is_const(reg)) {
  19. unsigned rel = jit_cc_get_const_I32_rel(cc, reg);
  20. os_printf("0x%x", jit_cc_get_const_I32(cc, reg));
  21. if (rel)
  22. os_printf("(rel: 0x%x)", rel);
  23. }
  24. else
  25. os_printf("i%d", no);
  26. break;
  27. case JIT_REG_KIND_I64:
  28. if (jit_reg_is_const(reg))
  29. os_printf("0x%llxL", jit_cc_get_const_I64(cc, reg));
  30. else
  31. os_printf("I%d", no);
  32. break;
  33. case JIT_REG_KIND_F32:
  34. if (jit_reg_is_const(reg))
  35. os_printf("%f", (double)jit_cc_get_const_F32(cc, reg));
  36. else
  37. os_printf("f%d", no);
  38. break;
  39. case JIT_REG_KIND_F64:
  40. if (jit_reg_is_const(reg))
  41. os_printf("%fL", jit_cc_get_const_F64(cc, reg));
  42. else
  43. os_printf("D%d", no);
  44. break;
  45. case JIT_REG_KIND_L32:
  46. os_printf("L%d", no);
  47. break;
  48. default:
  49. bh_assert(!"Unsupported register kind.");
  50. }
  51. }
  52. static void
  53. jit_dump_insn_Reg(JitCompContext *cc, JitInsn *insn, unsigned opnd_num)
  54. {
  55. unsigned i;
  56. for (i = 0; i < opnd_num; i++) {
  57. os_printf(i == 0 ? " " : ", ");
  58. jit_dump_reg(cc, *(jit_insn_opnd(insn, i)));
  59. }
  60. os_printf("\n");
  61. }
  62. static void
  63. jit_dump_insn_VReg(JitCompContext *cc, JitInsn *insn, unsigned opnd_num)
  64. {
  65. unsigned i;
  66. opnd_num = jit_insn_opndv_num(insn);
  67. for (i = 0; i < opnd_num; i++) {
  68. os_printf(i == 0 ? " " : ", ");
  69. jit_dump_reg(cc, *(jit_insn_opndv(insn, i)));
  70. }
  71. os_printf("\n");
  72. }
  73. static void
  74. jit_dump_insn_LookupSwitch(JitCompContext *cc, JitInsn *insn, unsigned opnd_num)
  75. {
  76. unsigned i;
  77. JitOpndLookupSwitch *opnd = jit_insn_opndls(insn);
  78. os_printf(" ");
  79. jit_dump_reg(cc, opnd->value);
  80. os_printf("\n%16s: ", "default");
  81. jit_dump_reg(cc, opnd->default_target);
  82. os_printf("\n");
  83. for (i = 0; i < opnd->match_pairs_num; i++) {
  84. os_printf("%18d: ", opnd->match_pairs[i].value);
  85. jit_dump_reg(cc, opnd->match_pairs[i].target);
  86. os_printf("\n");
  87. }
  88. }
  89. void
  90. jit_dump_insn(JitCompContext *cc, JitInsn *insn)
  91. {
  92. switch (insn->opcode) {
  93. #define INSN(NAME, OPND_KIND, OPND_NUM, FIRST_USE) \
  94. case JIT_OP_##NAME: \
  95. if (insn->flags_u8 & 0x1) \
  96. os_printf(" ATOMIC %-8s", #NAME); \
  97. else \
  98. os_printf(" %-15s", #NAME); \
  99. jit_dump_insn_##OPND_KIND(cc, insn, OPND_NUM); \
  100. break;
  101. #include "jit_ir.def"
  102. #undef INSN
  103. }
  104. }
  105. void
  106. jit_dump_basic_block(JitCompContext *cc, JitBasicBlock *block)
  107. {
  108. unsigned i, label_index;
  109. void *begin_addr, *end_addr;
  110. JitBasicBlock *block_next;
  111. JitInsn *insn;
  112. JitRegVec preds = jit_basic_block_preds(block);
  113. JitRegVec succs = jit_basic_block_succs(block);
  114. JitReg label = jit_basic_block_label(block), label_next;
  115. JitReg *reg;
  116. jit_dump_reg(cc, label);
  117. os_printf(":\n ; PREDS(");
  118. JIT_REG_VEC_FOREACH(preds, i, reg)
  119. {
  120. if (i > 0)
  121. os_printf(" ");
  122. jit_dump_reg(cc, *reg);
  123. }
  124. os_printf(")\n ;");
  125. if (jit_annl_is_enabled_begin_bcip(cc))
  126. os_printf(" BEGIN_BCIP=0x%04tx",
  127. *(jit_annl_begin_bcip(cc, label))
  128. - (uint8 *)cc->cur_wasm_module->load_addr);
  129. if (jit_annl_is_enabled_end_bcip(cc))
  130. os_printf(" END_BCIP=0x%04tx",
  131. *(jit_annl_end_bcip(cc, label))
  132. - (uint8 *)cc->cur_wasm_module->load_addr);
  133. os_printf("\n");
  134. if (jit_annl_is_enabled_jitted_addr(cc)) {
  135. begin_addr = *(jit_annl_jitted_addr(cc, label));
  136. if (label == cc->entry_label) {
  137. block_next = cc->_ann._label_basic_block[2];
  138. label_next = jit_basic_block_label(block_next);
  139. end_addr = *(jit_annl_jitted_addr(cc, label_next));
  140. }
  141. else if (label == cc->exit_label) {
  142. end_addr = cc->jitted_addr_end;
  143. }
  144. else {
  145. label_index = jit_reg_no(label);
  146. if (label_index < jit_cc_label_num(cc) - 1)
  147. block_next = cc->_ann._label_basic_block[label_index + 1];
  148. else
  149. block_next = cc->_ann._label_basic_block[1];
  150. label_next = jit_basic_block_label(block_next);
  151. end_addr = *(jit_annl_jitted_addr(cc, label_next));
  152. }
  153. jit_codegen_dump_native(begin_addr, end_addr);
  154. }
  155. else {
  156. /* Dump IR. */
  157. JIT_FOREACH_INSN(block, insn) jit_dump_insn(cc, insn);
  158. }
  159. os_printf(" ; SUCCS(");
  160. JIT_REG_VEC_FOREACH(succs, i, reg)
  161. {
  162. if (i > 0)
  163. os_printf(" ");
  164. jit_dump_reg(cc, *reg);
  165. }
  166. os_printf(")\n\n");
  167. }
  168. static void
  169. dump_func_name(JitCompContext *cc)
  170. {
  171. const char *func_name = NULL;
  172. WASMModule *module = cc->cur_wasm_module;
  173. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  174. func_name = cc->cur_wasm_func->field_name;
  175. #endif
  176. /* if custom name section is not generated,
  177. search symbols from export table */
  178. if (!func_name) {
  179. uint32 i;
  180. for (i = 0; i < module->export_count; i++) {
  181. if (module->exports[i].kind == EXPORT_KIND_FUNC
  182. && module->exports[i].index == cc->cur_wasm_func_idx) {
  183. func_name = module->exports[i].name;
  184. break;
  185. }
  186. }
  187. }
  188. /* function name not exported, print number instead */
  189. if (func_name == NULL) {
  190. os_printf("$f%d", cc->cur_wasm_func_idx);
  191. }
  192. else {
  193. os_printf("%s", func_name);
  194. }
  195. }
  196. static void
  197. dump_cc_ir(JitCompContext *cc)
  198. {
  199. unsigned i, end;
  200. JitBasicBlock *block;
  201. JitReg label;
  202. const char *kind_names[] = { "VOID", "I32", "I64", "F32",
  203. "F64", "V64", "V128", "V256" };
  204. os_printf("; Function: ");
  205. dump_func_name(cc);
  206. os_printf("\n");
  207. os_printf("; Constant table sizes:");
  208. for (i = 0; i < JIT_REG_KIND_L32; i++)
  209. os_printf(" %s=%d", kind_names[i], cc->_const_val._num[i]);
  210. os_printf("\n; Label number: %d", jit_cc_label_num(cc));
  211. os_printf("\n; Instruction number: %d", jit_cc_insn_num(cc));
  212. os_printf("\n; Register numbers:");
  213. for (i = 0; i < JIT_REG_KIND_L32; i++)
  214. os_printf(" %s=%d", kind_names[i], jit_cc_reg_num(cc, i));
  215. os_printf("\n; Label annotations:");
  216. #define ANN_LABEL(TYPE, NAME) \
  217. if (jit_annl_is_enabled_##NAME(cc)) \
  218. os_printf(" %s", #NAME);
  219. #include "jit_ir.def"
  220. #undef ANN_LABEL
  221. os_printf("\n; Instruction annotations:");
  222. #define ANN_INSN(TYPE, NAME) \
  223. if (jit_anni_is_enabled_##NAME(cc)) \
  224. os_printf(" %s", #NAME);
  225. #include "jit_ir.def"
  226. #undef ANN_INSN
  227. os_printf("\n; Register annotations:");
  228. #define ANN_REG(TYPE, NAME) \
  229. if (jit_annr_is_enabled_##NAME(cc)) \
  230. os_printf(" %s", #NAME);
  231. #include "jit_ir.def"
  232. #undef ANN_REG
  233. os_printf("\n\n");
  234. if (jit_annl_is_enabled_next_label(cc)) {
  235. /* Blocks have been reordered, use that order to dump. */
  236. for (label = cc->entry_label; label;
  237. label = *(jit_annl_next_label(cc, label)))
  238. jit_dump_basic_block(cc, *(jit_annl_basic_block(cc, label)));
  239. }
  240. else {
  241. /* Otherwise, use the default order. */
  242. jit_dump_basic_block(cc, jit_cc_entry_basic_block(cc));
  243. JIT_FOREACH_BLOCK(cc, i, end, block) jit_dump_basic_block(cc, block);
  244. jit_dump_basic_block(cc, jit_cc_exit_basic_block(cc));
  245. }
  246. }
  247. void
  248. jit_dump_cc(JitCompContext *cc)
  249. {
  250. if (jit_cc_label_num(cc) <= 2)
  251. return;
  252. dump_cc_ir(cc);
  253. }
  254. bool
  255. jit_pass_dump(JitCompContext *cc)
  256. {
  257. const JitGlobals *jit_globals = jit_compiler_get_jit_globals();
  258. const uint8 *passes = jit_globals->passes;
  259. uint8 pass_no = cc->cur_pass_no;
  260. const char *pass_name =
  261. pass_no > 0 ? jit_compiler_get_pass_name(passes[pass_no - 1]) : "NULL";
  262. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
  263. if (!strcmp(pass_name, "lower_cg"))
  264. /* Ignore lower codegen pass as it does nothing in x86-64 */
  265. return true;
  266. #endif
  267. os_printf("JIT.COMPILER.DUMP: PASS_NO=%d PREV_PASS=%s\n\n", pass_no,
  268. pass_name);
  269. jit_dump_cc(cc);
  270. os_printf("\n");
  271. return true;
  272. }
  273. bool
  274. jit_pass_update_cfg(JitCompContext *cc)
  275. {
  276. return jit_cc_update_cfg(cc);
  277. }