jit_compiler.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Copyright (C) 2021 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "jit_compiler.h"
  6. #include "jit_ir.h"
  7. #include "jit_codegen.h"
  8. #include "jit_codecache.h"
  9. #include "../interpreter/wasm.h"
  10. typedef struct JitCompilerPass {
  11. /* Name of the pass. */
  12. const char *name;
  13. /* The entry of the compiler pass. */
  14. bool (*run)(JitCompContext *cc);
  15. } JitCompilerPass;
  16. /* clang-format off */
  17. static JitCompilerPass compiler_passes[] = {
  18. { NULL, NULL },
  19. #define REG_PASS(name) { #name, jit_pass_##name }
  20. REG_PASS(dump),
  21. REG_PASS(update_cfg),
  22. REG_PASS(frontend),
  23. REG_PASS(lower_cg),
  24. REG_PASS(regalloc),
  25. REG_PASS(codegen),
  26. REG_PASS(register_jitted_code)
  27. #undef REG_PASS
  28. };
  29. /* Number of compiler passes. */
  30. #define COMPILER_PASS_NUM (sizeof(compiler_passes) / sizeof(compiler_passes[0]))
  31. #if WASM_ENABLE_FAST_JIT_DUMP == 0
  32. static const uint8 compiler_passes_without_dump[] = {
  33. 3, 4, 5, 6, 7, 0
  34. };
  35. #else
  36. static const uint8 compiler_passes_with_dump[] = {
  37. 3, 2, 1, 4, 1, 5, 1, 6, 1, 7, 0
  38. };
  39. #endif
  40. /* The exported global data of JIT compiler. */
  41. static JitGlobals jit_globals = {
  42. #if WASM_ENABLE_FAST_JIT_DUMP == 0
  43. .passes = compiler_passes_without_dump,
  44. #else
  45. .passes = compiler_passes_with_dump,
  46. #endif
  47. .return_to_interp_from_jitted = NULL
  48. };
  49. /* clang-format on */
  50. static bool
  51. apply_compiler_passes(JitCompContext *cc)
  52. {
  53. const uint8 *p = jit_globals.passes;
  54. for (; *p; p++) {
  55. /* Set the pass NO. */
  56. cc->cur_pass_no = p - jit_globals.passes;
  57. bh_assert(*p < COMPILER_PASS_NUM);
  58. if (!compiler_passes[*p].run(cc)) {
  59. LOG_VERBOSE("JIT: compilation failed at pass[%td] = %s\n",
  60. p - jit_globals.passes, compiler_passes[*p].name);
  61. return false;
  62. }
  63. }
  64. return true;
  65. }
  66. bool
  67. jit_compiler_init(const JitCompOptions *options)
  68. {
  69. uint32 code_cache_size = options->code_cache_size > 0
  70. ? options->code_cache_size
  71. : FAST_JIT_DEFAULT_CODE_CACHE_SIZE;
  72. LOG_VERBOSE("JIT: compiler init with code cache size: %u\n",
  73. code_cache_size);
  74. if (!jit_code_cache_init(code_cache_size))
  75. return false;
  76. if (!jit_codegen_init())
  77. goto fail1;
  78. return true;
  79. fail1:
  80. jit_code_cache_destroy();
  81. return false;
  82. }
  83. void
  84. jit_compiler_destroy()
  85. {
  86. jit_codegen_destroy();
  87. jit_code_cache_destroy();
  88. }
  89. JitGlobals *
  90. jit_compiler_get_jit_globals()
  91. {
  92. return &jit_globals;
  93. }
  94. const char *
  95. jit_compiler_get_pass_name(unsigned i)
  96. {
  97. return i < COMPILER_PASS_NUM ? compiler_passes[i].name : NULL;
  98. }
  99. bool
  100. jit_compiler_compile(WASMModule *module, uint32 func_idx)
  101. {
  102. JitCompContext *cc;
  103. char *last_error;
  104. bool ret = true;
  105. /* Initialize compilation context. */
  106. if (!(cc = jit_calloc(sizeof(*cc))))
  107. return false;
  108. if (!jit_cc_init(cc, 64)) {
  109. jit_free(cc);
  110. return false;
  111. }
  112. cc->cur_wasm_module = module;
  113. cc->cur_wasm_func =
  114. module->functions[func_idx - module->import_function_count];
  115. cc->cur_wasm_func_idx = func_idx;
  116. cc->mem_space_unchanged = (!cc->cur_wasm_func->has_op_memory_grow
  117. && !cc->cur_wasm_func->has_op_func_call)
  118. || (!module->possible_memory_grow);
  119. /* Apply compiler passes. */
  120. if (!apply_compiler_passes(cc) || jit_get_last_error(cc)) {
  121. last_error = jit_get_last_error(cc);
  122. os_printf("fast jit compilation failed: %s\n",
  123. last_error ? last_error : "unknown error");
  124. ret = false;
  125. }
  126. /* Delete the compilation context. */
  127. jit_cc_delete(cc);
  128. return ret;
  129. }
  130. bool
  131. jit_compiler_compile_all(WASMModule *module)
  132. {
  133. uint32 i;
  134. for (i = 0; i < module->function_count; i++) {
  135. if (!jit_compiler_compile(module, module->import_function_count + i)) {
  136. return false;
  137. }
  138. }
  139. return true;
  140. }
  141. int
  142. jit_interp_switch_to_jitted(void *exec_env, JitInterpSwitchInfo *info, void *pc)
  143. {
  144. return jit_codegen_interp_jitted_glue(exec_env, info, pc);
  145. }