jit_dump.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  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", 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. os_printf(" %-15s", #NAME); \
  96. jit_dump_insn_##OPND_KIND(cc, insn, OPND_NUM); \
  97. break;
  98. #include "jit_ir.def"
  99. #undef INSN
  100. }
  101. }
  102. void
  103. jit_dump_basic_block(JitCompContext *cc, JitBasicBlock *block)
  104. {
  105. unsigned i, label_index;
  106. void *begin_addr, *end_addr;
  107. JitBasicBlock *block_next;
  108. JitInsn *insn;
  109. JitRegVec preds = jit_basic_block_preds(block);
  110. JitRegVec succs = jit_basic_block_succs(block);
  111. JitReg label = jit_basic_block_label(block), label_next;
  112. JitReg *reg;
  113. jit_dump_reg(cc, label);
  114. os_printf(":\n ; PREDS(");
  115. JIT_REG_VEC_FOREACH(preds, i, reg)
  116. {
  117. if (i > 0)
  118. os_printf(" ");
  119. jit_dump_reg(cc, *reg);
  120. }
  121. os_printf(")\n ;");
  122. if (jit_annl_is_enabled_begin_bcip(cc))
  123. os_printf(" BEGIN_BCIP=0x%04tx",
  124. *(jit_annl_begin_bcip(cc, label))
  125. - (uint8 *)cc->cur_wasm_module->load_addr);
  126. if (jit_annl_is_enabled_end_bcip(cc))
  127. os_printf(" END_BCIP=0x%04tx",
  128. *(jit_annl_end_bcip(cc, label))
  129. - (uint8 *)cc->cur_wasm_module->load_addr);
  130. os_printf("\n");
  131. if (jit_annl_is_enabled_jitted_addr(cc)) {
  132. begin_addr = *(jit_annl_jitted_addr(cc, label));
  133. if (label == cc->entry_label) {
  134. block_next = cc->_ann._label_basic_block[2];
  135. label_next = jit_basic_block_label(block_next);
  136. end_addr = *(jit_annl_jitted_addr(cc, label_next));
  137. }
  138. else if (label == cc->exit_label) {
  139. end_addr = cc->jitted_addr_end;
  140. }
  141. else {
  142. label_index = jit_reg_no(label);
  143. if (label_index < jit_cc_label_num(cc) - 1)
  144. block_next = cc->_ann._label_basic_block[label_index + 1];
  145. else
  146. block_next = cc->_ann._label_basic_block[1];
  147. label_next = jit_basic_block_label(block_next);
  148. end_addr = *(jit_annl_jitted_addr(cc, label_next));
  149. }
  150. jit_codegen_dump_native(begin_addr, end_addr);
  151. }
  152. else {
  153. /* Dump IR. */
  154. JIT_FOREACH_INSN(block, insn) jit_dump_insn(cc, insn);
  155. }
  156. os_printf(" ; SUCCS(");
  157. JIT_REG_VEC_FOREACH(succs, i, reg)
  158. {
  159. if (i > 0)
  160. os_printf(" ");
  161. jit_dump_reg(cc, *reg);
  162. }
  163. os_printf(")\n\n");
  164. }
  165. static void
  166. dump_func_name(JitCompContext *cc)
  167. {
  168. const char *func_name = NULL;
  169. WASMModule *module = cc->cur_wasm_module;
  170. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  171. func_name = cc->cur_wasm_func->field_name;
  172. #endif
  173. /* if custom name section is not generated,
  174. search symbols from export table */
  175. if (!func_name) {
  176. uint32 i;
  177. for (i = 0; i < module->export_count; i++) {
  178. if (module->exports[i].kind == EXPORT_KIND_FUNC
  179. && module->exports[i].index == cc->cur_wasm_func_idx) {
  180. func_name = module->exports[i].name;
  181. break;
  182. }
  183. }
  184. }
  185. /* function name not exported, print number instead */
  186. if (func_name == NULL) {
  187. os_printf("$f%d", cc->cur_wasm_func_idx);
  188. }
  189. else {
  190. os_printf("%s", func_name);
  191. }
  192. }
  193. static void
  194. dump_cc_ir(JitCompContext *cc)
  195. {
  196. unsigned i, end;
  197. JitBasicBlock *block;
  198. JitReg label;
  199. const char *kind_names[] = { "VOID", "I32", "I64", "F32",
  200. "F64", "V64", "V128", "V256" };
  201. os_printf("; Function: ");
  202. dump_func_name(cc);
  203. os_printf("\n");
  204. os_printf("; Constant table sizes:");
  205. for (i = 0; i < JIT_REG_KIND_L32; i++)
  206. os_printf(" %s=%d", kind_names[i], cc->_const_val._num[i]);
  207. os_printf("\n; Label number: %d", jit_cc_label_num(cc));
  208. os_printf("\n; Instruction number: %d", jit_cc_insn_num(cc));
  209. os_printf("\n; Register numbers:");
  210. for (i = 0; i < JIT_REG_KIND_L32; i++)
  211. os_printf(" %s=%d", kind_names[i], jit_cc_reg_num(cc, i));
  212. os_printf("\n; Label annotations:");
  213. #define ANN_LABEL(TYPE, NAME) \
  214. if (jit_annl_is_enabled_##NAME(cc)) \
  215. os_printf(" %s", #NAME);
  216. #include "jit_ir.def"
  217. #undef ANN_LABEL
  218. os_printf("\n; Instruction annotations:");
  219. #define ANN_INSN(TYPE, NAME) \
  220. if (jit_anni_is_enabled_##NAME(cc)) \
  221. os_printf(" %s", #NAME);
  222. #include "jit_ir.def"
  223. #undef ANN_INSN
  224. os_printf("\n; Register annotations:");
  225. #define ANN_REG(TYPE, NAME) \
  226. if (jit_annr_is_enabled_##NAME(cc)) \
  227. os_printf(" %s", #NAME);
  228. #include "jit_ir.def"
  229. #undef ANN_REG
  230. os_printf("\n\n");
  231. if (jit_annl_is_enabled_next_label(cc)) {
  232. /* Blocks have been reordered, use that order to dump. */
  233. for (label = cc->entry_label; label;
  234. label = *(jit_annl_next_label(cc, label)))
  235. jit_dump_basic_block(cc, *(jit_annl_basic_block(cc, label)));
  236. }
  237. else {
  238. /* Otherwise, use the default order. */
  239. jit_dump_basic_block(cc, jit_cc_entry_basic_block(cc));
  240. JIT_FOREACH_BLOCK(cc, i, end, block) jit_dump_basic_block(cc, block);
  241. jit_dump_basic_block(cc, jit_cc_exit_basic_block(cc));
  242. }
  243. }
  244. void
  245. jit_dump_cc(JitCompContext *cc)
  246. {
  247. if (jit_cc_label_num(cc) <= 2)
  248. return;
  249. dump_cc_ir(cc);
  250. }
  251. bool
  252. jit_pass_dump(JitCompContext *cc)
  253. {
  254. const JitGlobals *jit_globals = jit_compiler_get_jit_globals();
  255. const uint8 *passes = jit_globals->passes;
  256. uint8 pass_no = cc->cur_pass_no;
  257. const char *pass_name =
  258. pass_no > 0 ? jit_compiler_get_pass_name(passes[pass_no - 1]) : "NULL";
  259. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
  260. if (!strcmp(pass_name, "lower_cg"))
  261. /* Ignore lower codegen pass as it does nothing in x86-64 */
  262. return true;
  263. #endif
  264. os_printf("JIT.COMPILER.DUMP: PASS_NO=%d PREV_PASS=%s\n\n", pass_no,
  265. pass_name);
  266. jit_dump_cc(cc);
  267. os_printf("\n");
  268. return true;
  269. }
  270. bool
  271. jit_pass_update_cfg(JitCompContext *cc)
  272. {
  273. return jit_cc_update_cfg(cc);
  274. }