Implement call Fast JIT function from LLVM JIT jitted code (#1714)

Basically implement the Multi-tier JIT engine.
And update document and wamr-test-suites script.
This commit is contained in:
Wenyong Huang
2022-11-21 10:42:18 +08:00
committed by GitHub
parent 3daa512925
commit cf7b01ad82
20 changed files with 1775 additions and 221 deletions

View File

@ -3886,28 +3886,48 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if WASM_ENABLE_FAST_JIT != 0
static void
fast_jit_call_func_bytecode(WASMExecEnv *exec_env,
fast_jit_call_func_bytecode(WASMModuleInstance *module_inst,
WASMExecEnv *exec_env,
WASMFunctionInstance *function,
WASMInterpFrame *frame)
{
JitGlobals *jit_globals = jit_compiler_get_jit_globals();
JitInterpSwitchInfo info;
WASMModule *module = module_inst->module;
WASMType *func_type = function->u.func->func_type;
uint8 type = func_type->result_count
? func_type->types[func_type->param_count]
: VALUE_TYPE_VOID;
uint32 func_idx = (uint32)(function - module_inst->e->functions);
uint32 func_idx_non_import = func_idx - module->import_function_count;
int32 action;
#if WASM_ENABLE_REF_TYPES != 0
if (type == VALUE_TYPE_EXTERNREF || type == VALUE_TYPE_FUNCREF)
type = VALUE_TYPE_I32;
#endif
#if WASM_ENABLE_LAZY_JIT != 0
if (!jit_compiler_compile(module, func_idx)) {
wasm_set_exception(module_inst, "failed to compile fast jit function");
return;
}
#endif
bh_assert(jit_compiler_is_compiled(module, func_idx));
/* Switch to jitted code to call the jit function */
info.out.ret.last_return_type = type;
info.frame = frame;
frame->jitted_return_addr =
(uint8 *)jit_globals->return_to_interp_from_jitted;
jit_interp_switch_to_jitted(exec_env, &info,
function->u.func->fast_jit_jitted_code);
action = jit_interp_switch_to_jitted(
exec_env, &info, func_idx,
module_inst->fast_jit_func_ptrs[func_idx_non_import]);
bh_assert(action == JIT_INTERP_ACTION_NORMAL
|| (action == JIT_INTERP_ACTION_THROWN
&& wasm_runtime_get_exception(exec_env->module_inst)));
/* Get the return values form info.out.ret */
if (func_type->result_count) {
switch (type) {
case VALUE_TYPE_I32:
@ -3931,8 +3951,10 @@ fast_jit_call_func_bytecode(WASMExecEnv *exec_env,
break;
}
}
(void)action;
(void)func_idx;
}
#endif
#endif /* end of WASM_ENABLE_FAST_JIT != 0 */
#if WASM_ENABLE_JIT != 0
static bool
@ -3962,11 +3984,14 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
WASMType *func_type = function->u.func->func_type;
uint32 result_count = func_type->result_count;
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
uint32 func_idx = (uint32)(function - module_inst->e->functions);
bool ret;
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
if (!llvm_jit_alloc_frame(exec_env, function - module_inst->e->functions)) {
wasm_set_exception(module_inst, "wasm operand stack overflow");
/* wasm operand stack overflow has been thrown,
no need to throw again */
return false;
}
#endif
@ -4007,8 +4032,8 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
}
ret = wasm_runtime_invoke_native(
exec_env, function->u.func->llvm_jit_func_ptr, func_type, NULL,
NULL, argv1, argc, argv);
exec_env, module_inst->func_ptrs[func_idx], func_type, NULL, NULL,
argv1, argc, argv);
if (!ret || wasm_get_exception(module_inst)) {
if (clear_wasi_proc_exit_exception(module_inst))
@ -4058,8 +4083,8 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
}
else {
ret = wasm_runtime_invoke_native(
exec_env, function->u.func->llvm_jit_func_ptr, func_type, NULL,
NULL, argv, argc, argv);
exec_env, module_inst->func_ptrs[func_idx], func_type, NULL, NULL,
argv, argc, argv);
if (clear_wasi_proc_exit_exception(module_inst))
ret = true;
@ -4067,7 +4092,7 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
return ret && !wasm_get_exception(module_inst) ? true : false;
}
}
#endif
#endif /* end of WASM_ENABLE_JIT != 0 */
void
wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
@ -4134,18 +4159,63 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
}
}
else {
#if WASM_ENABLE_JIT != 0
#if WASM_ENABLE_LAZY_JIT != 0
/* Fast JIT to LLVM JIT tier-up is enabled */
#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0
/* Fast JIT and LLVM JIT are both enabled, call llvm jit function
if it is compiled, else call fast jit function */
uint32 func_idx = (uint32)(function - module_inst->e->functions);
if (module_inst->module->func_ptrs_compiled
[func_idx - module_inst->module->import_function_count]) {
llvm_jit_call_func_bytecode(module_inst, exec_env, function, argc,
argv);
/* For llvm jit, the results have been stored in argv,
no need to copy them from stack frame again */
copy_argv_from_frame = false;
}
else {
fast_jit_call_func_bytecode(module_inst, exec_env, function, frame);
}
#elif WASM_ENABLE_JIT != 0
/* Only LLVM JIT is enabled */
llvm_jit_call_func_bytecode(module_inst, exec_env, function, argc,
argv);
/* For llvm jit, the results have been stored in argv,
no need to copy them from stack frame again */
copy_argv_from_frame = false;
#elif WASM_ENABLE_FAST_JIT != 0
fast_jit_call_func_bytecode(exec_env, function, frame);
/* Only Fast JIT is enabled */
fast_jit_call_func_bytecode(module_inst, exec_env, function, frame);
#else
/* Both Fast JIT and LLVM JIT are disabled */
wasm_interp_call_func_bytecode(module_inst, exec_env, function, frame);
#endif
#else /* else of WASM_ENABLE_LAZY_JIT != 0 */
/* Fast JIT to LLVM JIT tier-up is enabled */
#if WASM_ENABLE_JIT != 0
/* LLVM JIT is enabled */
llvm_jit_call_func_bytecode(module_inst, exec_env, function, argc,
argv);
/* For llvm jit, the results have been stored in argv,
no need to copy them from stack frame again */
copy_argv_from_frame = false;
#elif WASM_ENABLE_FAST_JIT != 0
/* Fast JIT is enabled */
fast_jit_call_func_bytecode(module_inst, exec_env, function, frame);
#else
/* Both Fast JIT and LLVM JIT are disabled */
wasm_interp_call_func_bytecode(module_inst, exec_env, function, frame);
#endif
#endif /* end of WASM_ENABLE_LAZY_JIT != 0 */
(void)wasm_interp_call_func_bytecode;
#if WASM_ENABLE_FAST_JIT != 0
(void)fast_jit_call_func_bytecode;
#endif
}
/* Output the return value to the caller */