jit_compiler.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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. #if WASM_ENABLE_LAZY_JIT != 0
  49. .compile_fast_jit_and_then_call = NULL,
  50. #endif
  51. };
  52. /* clang-format on */
  53. static bool
  54. apply_compiler_passes(JitCompContext *cc)
  55. {
  56. const uint8 *p = jit_globals.passes;
  57. for (; *p; p++) {
  58. /* Set the pass NO */
  59. cc->cur_pass_no = p - jit_globals.passes;
  60. bh_assert(*p < COMPILER_PASS_NUM);
  61. if (!compiler_passes[*p].run(cc) || jit_get_last_error(cc)) {
  62. LOG_VERBOSE("JIT: compilation failed at pass[%td] = %s\n",
  63. p - jit_globals.passes, compiler_passes[*p].name);
  64. return false;
  65. }
  66. }
  67. return true;
  68. }
  69. bool
  70. jit_compiler_init(const JitCompOptions *options)
  71. {
  72. uint32 code_cache_size = options->code_cache_size > 0
  73. ? options->code_cache_size
  74. : FAST_JIT_DEFAULT_CODE_CACHE_SIZE;
  75. LOG_VERBOSE("JIT: compiler init with code cache size: %u\n",
  76. code_cache_size);
  77. if (!jit_code_cache_init(code_cache_size))
  78. return false;
  79. if (!jit_codegen_init())
  80. goto fail1;
  81. return true;
  82. fail1:
  83. jit_code_cache_destroy();
  84. return false;
  85. }
  86. void
  87. jit_compiler_destroy()
  88. {
  89. jit_codegen_destroy();
  90. jit_code_cache_destroy();
  91. }
  92. JitGlobals *
  93. jit_compiler_get_jit_globals()
  94. {
  95. return &jit_globals;
  96. }
  97. const char *
  98. jit_compiler_get_pass_name(unsigned i)
  99. {
  100. return i < COMPILER_PASS_NUM ? compiler_passes[i].name : NULL;
  101. }
  102. bool
  103. jit_compiler_compile(WASMModule *module, uint32 func_idx)
  104. {
  105. JitCompContext *cc = NULL;
  106. char *last_error;
  107. bool ret = false;
  108. uint32 i = func_idx - module->import_function_count;
  109. uint32 j = i % WASM_ORC_JIT_BACKEND_THREAD_NUM;
  110. /* Lock to avoid duplicated compilation by other threads */
  111. os_mutex_lock(&module->fast_jit_thread_locks[j]);
  112. if (jit_compiler_is_compiled(module, func_idx)) {
  113. /* Function has been compiled */
  114. os_mutex_unlock(&module->fast_jit_thread_locks[j]);
  115. return true;
  116. }
  117. /* Initialize the compilation context */
  118. if (!(cc = jit_calloc(sizeof(*cc)))) {
  119. goto fail;
  120. }
  121. if (!jit_cc_init(cc, 64)) {
  122. goto fail;
  123. }
  124. cc->cur_wasm_module = module;
  125. cc->cur_wasm_func = module->functions[i];
  126. cc->cur_wasm_func_idx = func_idx;
  127. cc->mem_space_unchanged = (!cc->cur_wasm_func->has_op_memory_grow
  128. && !cc->cur_wasm_func->has_op_func_call)
  129. || (!module->possible_memory_grow);
  130. /* Apply compiler passes */
  131. if (!apply_compiler_passes(cc) || jit_get_last_error(cc)) {
  132. last_error = jit_get_last_error(cc);
  133. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  134. char *function_name = cc->cur_wasm_func->field_name;
  135. LOG_ERROR("fast jit compilation failed: %s (function_name=%s)\n",
  136. last_error ? last_error : "unknown error", function_name);
  137. #else
  138. LOG_ERROR("fast jit compilation failed: %s\n",
  139. last_error ? last_error : "unknown error");
  140. #endif
  141. goto fail;
  142. }
  143. ret = true;
  144. fail:
  145. /* Destroy the compilation context */
  146. if (cc)
  147. jit_cc_delete(cc);
  148. os_mutex_unlock(&module->fast_jit_thread_locks[j]);
  149. return ret;
  150. }
  151. bool
  152. jit_compiler_compile_all(WASMModule *module)
  153. {
  154. uint32 i;
  155. for (i = 0; i < module->function_count; i++) {
  156. if (!jit_compiler_compile(module, module->import_function_count + i)) {
  157. return false;
  158. }
  159. }
  160. return true;
  161. }
  162. bool
  163. jit_compiler_is_compiled(const WASMModule *module, uint32 func_idx)
  164. {
  165. uint32 i = func_idx - module->import_function_count;
  166. bh_assert(func_idx >= module->import_function_count
  167. && func_idx
  168. < module->import_function_count + module->function_count);
  169. #if WASM_ENABLE_LAZY_JIT == 0
  170. return module->fast_jit_func_ptrs[i] ? true : false;
  171. #else
  172. return module->fast_jit_func_ptrs[i]
  173. != jit_globals.compile_fast_jit_and_then_call
  174. ? true
  175. : false;
  176. #endif
  177. }
  178. #if WASM_ENABLE_LAZY_JIT != 0 && WASM_ENABLE_JIT != 0
  179. bool
  180. jit_compiler_set_call_to_llvm_jit(WASMModule *module, uint32 func_idx)
  181. {
  182. uint32 i = func_idx - module->import_function_count;
  183. uint32 j = i % WASM_ORC_JIT_BACKEND_THREAD_NUM;
  184. WASMType *func_type = module->functions[i]->func_type;
  185. uint32 k =
  186. ((uint32)(uintptr_t)func_type >> 3) % WASM_ORC_JIT_BACKEND_THREAD_NUM;
  187. void *func_ptr = NULL;
  188. /* Compile code block of call_to_llvm_jit_from_fast_jit of
  189. this kind of function type if it hasn't been compiled */
  190. if (!(func_ptr = func_type->call_to_llvm_jit_from_fast_jit)) {
  191. os_mutex_lock(&module->fast_jit_thread_locks[k]);
  192. if (!(func_ptr = func_type->call_to_llvm_jit_from_fast_jit)) {
  193. if (!(func_ptr = func_type->call_to_llvm_jit_from_fast_jit =
  194. jit_codegen_compile_call_to_llvm_jit(func_type))) {
  195. os_mutex_unlock(&module->fast_jit_thread_locks[k]);
  196. return false;
  197. }
  198. }
  199. os_mutex_unlock(&module->fast_jit_thread_locks[k]);
  200. }
  201. /* Switch current fast jit func ptr to the code block */
  202. os_mutex_lock(&module->fast_jit_thread_locks[j]);
  203. module->fast_jit_func_ptrs[i] = func_ptr;
  204. os_mutex_unlock(&module->fast_jit_thread_locks[j]);
  205. return true;
  206. }
  207. bool
  208. jit_compiler_set_call_to_fast_jit(WASMModule *module, uint32 func_idx)
  209. {
  210. void *func_ptr = NULL;
  211. func_ptr = jit_codegen_compile_call_to_fast_jit(module, func_idx);
  212. if (func_ptr) {
  213. uint32 i = func_idx - module->import_function_count;
  214. module->functions[i]->call_to_fast_jit_from_llvm_jit = func_ptr;
  215. jit_compiler_set_llvm_jit_func_ptr(module, func_idx, func_ptr);
  216. }
  217. return func_ptr ? true : false;
  218. }
  219. void
  220. jit_compiler_set_llvm_jit_func_ptr(WASMModule *module, uint32 func_idx,
  221. void *func_ptr)
  222. {
  223. WASMModuleInstance *instance;
  224. uint32 i = func_idx - module->import_function_count;
  225. os_mutex_lock(&module->instance_list_lock);
  226. module->func_ptrs[i] = func_ptr;
  227. instance = module->instance_list;
  228. while (instance) {
  229. if (instance->e->running_mode == Mode_Multi_Tier_JIT)
  230. instance->func_ptrs[func_idx] = func_ptr;
  231. instance = instance->e->next;
  232. }
  233. os_mutex_unlock(&module->instance_list_lock);
  234. }
  235. #endif /* end of WASM_ENABLE_LAZY_JIT != 0 && WASM_ENABLE_JIT != 0 */
  236. int
  237. jit_interp_switch_to_jitted(void *exec_env, JitInterpSwitchInfo *info,
  238. uint32 func_idx, void *pc)
  239. {
  240. return jit_codegen_interp_jitted_glue(exec_env, info, func_idx, pc);
  241. }