From 471cac47194e3145c33229c9682d9812f3b0d194 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Sat, 25 Jun 2022 21:38:43 +0800 Subject: [PATCH 1/6] Enable dump call stack to a buffer (#1244) Enable dump call stack to a buffer, use API `wasm_runtime_get_call_stack_buf_size` to get the required buffer size and use API `wasm_runtime_dump_call_stack_to_buf` to dump call stack to a buffer --- core/iwasm/aot/aot_runtime.c | 101 +++++++++++++++---- core/iwasm/aot/aot_runtime.h | 20 +++- core/iwasm/common/wasm_runtime_common.c | 69 ++++++++++++- core/iwasm/common/wasm_runtime_common.h | 23 +++++ core/iwasm/include/wasm_export.h | 37 ++++++- core/iwasm/interpreter/wasm_interp_classic.c | 4 +- core/iwasm/interpreter/wasm_interp_fast.c | 4 +- core/iwasm/interpreter/wasm_runtime.c | 94 ++++++++++++++--- core/iwasm/interpreter/wasm_runtime.h | 21 +++- 9 files changed, 327 insertions(+), 46 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 606ffa05c..64024ce07 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1511,7 +1511,9 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, #if WASM_ENABLE_DUMP_CALL_STACK != 0 if (!ret) { - aot_dump_call_stack(exec_env); + if (aot_create_call_stack(exec_env)) { + aot_dump_call_stack(exec_env, true, NULL, 0); + } } #endif @@ -1568,7 +1570,9 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, #if WASM_ENABLE_DUMP_CALL_STACK != 0 if (aot_get_exception(module_inst)) { - aot_dump_call_stack(exec_env); + if (aot_create_call_stack(exec_env)) { + aot_dump_call_stack(exec_env, true, NULL, 0); + } } #endif @@ -3018,38 +3022,24 @@ aot_free_frame(WASMExecEnv *exec_env) || (WASM_ENABLE_PERF_PROFILING != 0) */ #if WASM_ENABLE_DUMP_CALL_STACK != 0 -void -aot_dump_call_stack(WASMExecEnv *exec_env) +bool +aot_create_call_stack(struct WASMExecEnv *exec_env) { AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame, *first_frame = cur_frame; AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst; - const char *func_name; uint32 n = 0; - os_printf("\n"); while (cur_frame) { - func_name = - get_func_name_from_index(module_inst, cur_frame->func_index); - - /* function name not exported, print number instead */ - if (func_name == NULL) { - os_printf("#%02d $f%d \n", n, cur_frame->func_index); - } - else { - os_printf("#%02d %s \n", n, func_name); - } - cur_frame = cur_frame->prev_frame; n++; } - os_printf("\n"); /* release previous stack frames and create new ones */ if (!bh_vector_destroy(module_inst->frames.ptr) || !bh_vector_init(module_inst->frames.ptr, n, sizeof(WASMCApiFrame), false)) { - return; + return false; } cur_frame = first_frame; @@ -3059,14 +3049,85 @@ aot_dump_call_stack(WASMExecEnv *exec_env) frame.module_offset = 0; frame.func_index = cur_frame->func_index; frame.func_offset = 0; + frame.func_name_wp = + get_func_name_from_index(module_inst, cur_frame->func_index); if (!bh_vector_append(module_inst->frames.ptr, &frame)) { bh_vector_destroy(module_inst->frames.ptr); - return; + return false; } cur_frame = cur_frame->prev_frame; } + + return true; +} + +#define PRINT_OR_DUMP() \ + do { \ + total_len += \ + wasm_runtime_dump_line_buf_impl(line_buf, print, &buf, &len); \ + if ((!print) && buf && (len == 0)) { \ + return total_len; \ + } \ + } while (0) + +uint32 +aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len) +{ + AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst; + uint32 n = 0, total_len = 0, total_frames; + /* reserve 256 bytes for line buffer, any line longer than 256 bytes + * will be truncated */ + char line_buf[256]; + + if (!module_inst->frames.ptr) { + return 0; + } + + total_frames = bh_vector_size(module_inst->frames.ptr); + if (total_frames == 0) { + return 0; + } + + snprintf(line_buf, sizeof(line_buf), "\n"); + PRINT_OR_DUMP(); + + while (n < total_frames) { + WASMCApiFrame frame = { 0 }; + uint32 line_length, i; + + if (!bh_vector_get(module_inst->frames.ptr, n, &frame)) { + return 0; + } + + /* function name not exported, print number instead */ + if (frame.func_name_wp == NULL) { + line_length = snprintf(line_buf, sizeof(line_buf), "#%02d $f%d\n", + n, frame.func_index); + } + else { + line_length = snprintf(line_buf, sizeof(line_buf), "#%02d %s\n", n, + frame.func_name_wp); + } + + if (line_length >= sizeof(line_buf)) { + uint32 line_buffer_len = sizeof(line_buf); + /* If line too long, ensure the last character is '\n' */ + for (i = line_buffer_len - 5; i < line_buffer_len - 2; i++) { + line_buf[i] = '.'; + } + line_buf[line_buffer_len - 2] = '\n'; + } + + PRINT_OR_DUMP(); + + n++; + } + snprintf(line_buf, sizeof(line_buf), "\n"); + PRINT_OR_DUMP(); + + return total_len + 1; } #endif /* end of WASM_ENABLE_DUMP_CALL_STACK */ diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 0aa4edeae..c3838b585 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -731,8 +731,24 @@ aot_alloc_frame(WASMExecEnv *exec_env, uint32 func_index); void aot_free_frame(WASMExecEnv *exec_env); -void -aot_dump_call_stack(WASMExecEnv *exec_env); +bool +aot_create_call_stack(struct WASMExecEnv *exec_env); + +/** + * @brief Dump wasm call stack or get the size + * + * @param exec_env the execution environment + * @param print whether to print to stdout or not + * @param buf buffer to store the dumped content + * @param len length of the buffer + * + * @return when print is true, return the bytes printed out to stdout; when + * print is false and buf is NULL, return the size required to store the + * callstack content; when print is false and buf is not NULL, return the size + * dumped to the buffer, 0 means error and data in buf may be invalid + */ +uint32 +aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len); void aot_dump_perf_profiling(const AOTModuleInstance *module_inst); diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index ca8d02d25..cd1d56d04 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -4527,6 +4527,30 @@ wasm_externref_retain(uint32 externref_idx) #endif /* end of WASM_ENABLE_REF_TYPES */ #if WASM_ENABLE_DUMP_CALL_STACK != 0 +uint32 +wasm_runtime_dump_line_buf_impl(const char *line_buf, bool dump_or_print, + char **buf, uint32 *len) +{ + if (dump_or_print) { + return (uint32)os_printf("%s", line_buf); + } + else if (*buf) { + uint32 dump_len; + + dump_len = snprintf(*buf, *len, "%s", line_buf); + if (dump_len >= *len) { + dump_len = *len; + } + + *len = *len - dump_len; + *buf = *buf + dump_len; + return dump_len; + } + else { + return strlen(line_buf); + } +} + void wasm_runtime_dump_call_stack(WASMExecEnv *exec_env) { @@ -4534,15 +4558,56 @@ wasm_runtime_dump_call_stack(WASMExecEnv *exec_env) wasm_exec_env_get_module_inst(exec_env); #if WASM_ENABLE_INTERP != 0 if (module_inst->module_type == Wasm_Module_Bytecode) { - wasm_interp_dump_call_stack(exec_env); + wasm_interp_dump_call_stack(exec_env, true, NULL, 0); } #endif #if WASM_ENABLE_AOT != 0 if (module_inst->module_type == Wasm_Module_AoT) { - aot_dump_call_stack(exec_env); + aot_dump_call_stack(exec_env, true, NULL, 0); } #endif } + +uint32 +wasm_runtime_get_call_stack_buf_size(wasm_exec_env_t exec_env) +{ + WASMModuleInstanceCommon *module_inst = + wasm_exec_env_get_module_inst(exec_env); + +#if WASM_ENABLE_INTERP != 0 + if (module_inst->module_type == Wasm_Module_Bytecode) { + return wasm_interp_dump_call_stack(exec_env, false, NULL, 0); + } +#endif +#if WASM_ENABLE_AOT != 0 + if (module_inst->module_type == Wasm_Module_AoT) { + return aot_dump_call_stack(exec_env, false, NULL, 0); + } +#endif + + return 0; +} + +uint32 +wasm_runtime_dump_call_stack_to_buf(wasm_exec_env_t exec_env, char *buf, + uint32 len) +{ + WASMModuleInstanceCommon *module_inst = + wasm_exec_env_get_module_inst(exec_env); + +#if WASM_ENABLE_INTERP != 0 + if (module_inst->module_type == Wasm_Module_Bytecode) { + return wasm_interp_dump_call_stack(exec_env, false, buf, len); + } +#endif +#if WASM_ENABLE_AOT != 0 + if (module_inst->module_type == Wasm_Module_AoT) { + return aot_dump_call_stack(exec_env, false, buf, len); + } +#endif + + return 0; +} #endif /* end of WASM_ENABLE_DUMP_CALL_STACK */ bool diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 7ef8f69c1..87a2e4aaf 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -404,6 +404,7 @@ typedef struct wasm_frame_t { uint32 module_offset; uint32 func_index; uint32 func_offset; + const char *func_name_wp; } WASMCApiFrame; /* See wasm_export.h for description */ @@ -803,6 +804,28 @@ void wasm_externref_cleanup(WASMModuleInstanceCommon *module_inst); #endif /* end of WASM_ENABLE_REF_TYPES */ +#if WASM_ENABLE_DUMP_CALL_STACK != 0 +/** + * @brief Internal implementation for dumping or printing callstack line + * + * @note if dump_or_print is true, then print to stdout directly; + * if dump_or_print is false, but *buf is NULL, then return the length of the + * line; + * if dump_or_print is false, and *buf is not NULL, then dump content to + * the memory pointed by *buf, and adjust *buf and *len according to actual + * bytes dumped, and return the actual dumped length + * + * @param line_buf current line to dump or print + * @param dump_or_print whether to print to stdout or dump to buf + * @param buf [INOUT] pointer to the buffer + * @param len [INOUT] pointer to remaining length + * @return bytes printed to stdout or dumped to buf + */ +uint32 +wasm_runtime_dump_line_buf_impl(const char *line_buf, bool dump_or_print, + char **buf, uint32 *len); +#endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 */ + /* Get module of the current exec_env */ WASMModuleCommon * wasm_exec_env_get_module(WASMExecEnv *exec_env); diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 9b1481d72..ed7a865b8 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -919,6 +919,7 @@ wasm_runtime_get_function_attachment(wasm_exec_env_t exec_env); */ WASM_RUNTIME_API_EXTERN void wasm_runtime_set_user_data(wasm_exec_env_t exec_env, void *user_data); + /** * Get the user data within execution environment. * @@ -963,7 +964,7 @@ WASM_RUNTIME_API_EXTERN void wasm_runtime_set_max_thread_num(uint32_t num); /** - * spawn a new exec_env, the spawned exec_env + * Spawn a new exec_env, the spawned exec_env * can be used in other threads * * @param num the original exec_env @@ -982,7 +983,7 @@ WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_spawned_exec_env(wasm_exec_env_t exec_env); /** - * spawn a thread from the given exec_env + * Spawn a thread from the given exec_env * * @param exec_env the original exec_env * @param tid thread id to be returned to the caller @@ -996,7 +997,7 @@ wasm_runtime_spawn_thread(wasm_exec_env_t exec_env, wasm_thread_t *tid, wasm_thread_callback_t callback, void *arg); /** - * waits a spawned thread to terminate + * Waits a spawned thread to terminate * * @param tid thread id * @param retval if not NULL, output the return value of the thread @@ -1046,13 +1047,41 @@ WASM_RUNTIME_API_EXTERN bool wasm_externref_retain(uint32_t externref_idx); /** - * dump the call stack + * Dump the call stack to stdout * * @param exec_env the execution environment */ WASM_RUNTIME_API_EXTERN void wasm_runtime_dump_call_stack(wasm_exec_env_t exec_env); +/** + * Get the size required to store the call stack contents, including + * the space for terminating null byte ('\0') + * + * @param exec_env the execution environment + * + * @return size required to store the contents, 0 means error + */ +WASM_RUNTIME_API_EXTERN uint32_t +wasm_runtime_get_call_stack_buf_size(wasm_exec_env_t exec_env); + +/** + * Dump the call stack to buffer. + * + * @note this function is not thread-safe, please only use this API + * when the exec_env is not executing + * + * @param exec_env the execution environment + * @param buf buffer to store the dumped content + * @param len length of the buffer + * + * @return bytes dumped to the buffer, including the terminating null + * byte ('\0'), 0 means error and data in buf may be invalid + */ +WASM_RUNTIME_API_EXTERN uint32_t +wasm_runtime_dump_call_stack_to_buf(wasm_exec_env_t exec_env, char *buf, + uint32_t len); + /** * Get a custom section by name * diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 0c97df44d..7510698eb 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -3834,7 +3834,9 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, } else { #if WASM_ENABLE_DUMP_CALL_STACK != 0 - wasm_interp_dump_call_stack(exec_env); + if (wasm_interp_create_call_stack(exec_env)) { + wasm_interp_dump_call_stack(exec_env, true, NULL, 0); + } #endif LOG_DEBUG("meet an exception %s", wasm_get_exception(module_inst)); } diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index b64609d7a..45e8401bc 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -3847,7 +3847,9 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, } else { #if WASM_ENABLE_DUMP_CALL_STACK != 0 - wasm_interp_dump_call_stack(exec_env); + if (wasm_interp_create_call_stack(exec_env)) { + wasm_interp_dump_call_stack(exec_env, true, NULL, 0); + } #endif } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index c6b77f0a7..deba92dca 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -2485,8 +2485,8 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst, || (WASM_ENABLE_MEMORY_TRACING != 0) */ #if WASM_ENABLE_DUMP_CALL_STACK != 0 -void -wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) +bool +wasm_interp_create_call_stack(struct WASMExecEnv *exec_env) { WASMModuleInstance *module_inst = (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); @@ -2507,12 +2507,12 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) if (!bh_vector_destroy(module_inst->frames) || !bh_vector_init(module_inst->frames, n, sizeof(WASMCApiFrame), false)) { - return; + return false; } cur_frame = first_frame; n = 0; - os_printf("\n"); + while (cur_frame) { WASMCApiFrame frame = { 0 }; WASMFunctionInstance *func_inst = cur_frame->function; @@ -2560,20 +2560,86 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) } } - /* function name not exported, print number instead */ - if (func_name == NULL) { - os_printf("#%02d $f%d \n", n, func_inst - module_inst->functions); - } - else { - os_printf("#%02d %s \n", n, func_name); - } + frame.func_name_wp = func_name; - /* keep print */ - bh_vector_append(module_inst->frames, &frame); + if (!bh_vector_append(module_inst->frames, &frame)) { + bh_vector_destroy(module_inst->frames); + return false; + } cur_frame = cur_frame->prev_frame; n++; } - os_printf("\n"); + + return true; +} + +#define PRINT_OR_DUMP() \ + do { \ + total_len += \ + wasm_runtime_dump_line_buf_impl(line_buf, print, &buf, &len); \ + if ((!print) && buf && (len == 0)) { \ + return total_len; \ + } \ + } while (0) + +uint32 +wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf, + uint32 len) +{ + WASMModuleInstance *module_inst = + (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); + uint32 n = 0, total_len = 0, total_frames; + /* reserve 256 bytes for line buffer, any line longer than 256 bytes + * will be truncated */ + char line_buf[256]; + + if (!module_inst->frames) { + return 0; + } + + total_frames = bh_vector_size(module_inst->frames); + if (total_frames == 0) { + return 0; + } + + snprintf(line_buf, sizeof(line_buf), "\n"); + PRINT_OR_DUMP(); + + while (n < total_frames) { + WASMCApiFrame frame = { 0 }; + uint32 line_length, i; + + if (!bh_vector_get(module_inst->frames, n, &frame)) { + return 0; + } + + /* function name not exported, print number instead */ + if (frame.func_name_wp == NULL) { + line_length = snprintf(line_buf, sizeof(line_buf), "#%02d $f%d\n", + n, frame.func_index); + } + else { + line_length = snprintf(line_buf, sizeof(line_buf), "#%02d %s\n", n, + frame.func_name_wp); + } + + if (line_length >= sizeof(line_buf)) { + uint32 line_buffer_len = sizeof(line_buf); + /* If line too long, ensure the last character is '\n' */ + for (i = line_buffer_len - 5; i < line_buffer_len - 2; i++) { + line_buf[i] = '.'; + } + line_buf[line_buffer_len - 2] = '\n'; + } + + PRINT_OR_DUMP(); + + n++; + } + snprintf(line_buf, sizeof(line_buf), "\n"); + PRINT_OR_DUMP(); + + return total_len + 1; } #endif /* end of WASM_ENABLE_DUMP_CALL_STACK */ diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index ccdf538aa..c780e6a11 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -432,8 +432,25 @@ wasm_get_table_inst(const WASMModuleInstance *module_inst, const uint32 tbl_idx) } #if WASM_ENABLE_DUMP_CALL_STACK != 0 -void -wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env); +bool +wasm_interp_create_call_stack(struct WASMExecEnv *exec_env); + +/** + * @brief Dump wasm call stack or get the size + * + * @param exec_env the execution environment + * @param print whether to print to stdout or not + * @param buf buffer to store the dumped content + * @param len length of the buffer + * + * @return when print is true, return the bytes printed out to stdout; when + * print is false and buf is NULL, return the size required to store the + * callstack content; when print is false and buf is not NULL, return the size + * dumped to the buffer, 0 means error and data in buf may be invalid + */ +uint32 +wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf, + uint32 len); #endif const uint8 * From 114bf9408bbfbf623cd6d7185393a49663e75213 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Sun, 26 Jun 2022 09:33:54 +0800 Subject: [PATCH 2/6] Fix get invokeNative float ret value issue with clang compiler (#1248) When using clang compiler, the f32/f64 return value might be invalid when calling invokeNative asm code. Declare the return type of invokeNative as void, and set volatile for the converted function pointers to resolve the issue. --- core/iwasm/common/wasm_runtime_common.c | 54 ++++++++++++------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index cd1d56d04..fea9987a3 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -3049,7 +3049,7 @@ fail: || defined(BUILD_TARGET_RISCV32_ILP32D) \ || defined(BUILD_TARGET_RISCV32_ILP32) || defined(BUILD_TARGET_ARC) typedef void (*GenericFunctionPointer)(); -int64 +void invokeNative(GenericFunctionPointer f, uint32 *args, uint32 n_stacks); typedef float64 (*Float64FuncPtr)(GenericFunctionPointer, uint32 *, uint32); @@ -3058,13 +3058,16 @@ typedef int64 (*Int64FuncPtr)(GenericFunctionPointer, uint32 *, uint32); typedef int32 (*Int32FuncPtr)(GenericFunctionPointer, uint32 *, uint32); typedef void (*VoidFuncPtr)(GenericFunctionPointer, uint32 *, uint32); -static Float64FuncPtr invokeNative_Float64 = +static volatile Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)(uintptr_t)invokeNative; -static Float32FuncPtr invokeNative_Float32 = +static volatile Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)(uintptr_t)invokeNative; -static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)(uintptr_t)invokeNative; -static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)(uintptr_t)invokeNative; -static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)(uintptr_t)invokeNative; +static volatile Int64FuncPtr invokeNative_Int64 = + (Int64FuncPtr)(uintptr_t)invokeNative; +static volatile Int32FuncPtr invokeNative_Int32 = + (Int32FuncPtr)(uintptr_t)invokeNative; +static volatile VoidFuncPtr invokeNative_Void = + (VoidFuncPtr)(uintptr_t)invokeNative; #if defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP) #define MAX_REG_INTS 4 @@ -3520,7 +3523,7 @@ fail: || defined(BUILD_TARGET_THUMB) || defined(BUILD_TARGET_MIPS) \ || defined(BUILD_TARGET_XTENSA) typedef void (*GenericFunctionPointer)(); -int64 +void invokeNative(GenericFunctionPointer f, uint32 *args, uint32 sz); typedef float64 (*Float64FuncPtr)(GenericFunctionPointer f, uint32 *, uint32); @@ -3529,13 +3532,16 @@ typedef int64 (*Int64FuncPtr)(GenericFunctionPointer f, uint32 *, uint32); typedef int32 (*Int32FuncPtr)(GenericFunctionPointer f, uint32 *, uint32); typedef void (*VoidFuncPtr)(GenericFunctionPointer f, uint32 *, uint32); -static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative; -static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)(uintptr_t)invokeNative; -static Float64FuncPtr invokeNative_Float64 = +static volatile Int64FuncPtr invokeNative_Int64 = + (Int64FuncPtr)(uintptr_t)invokeNative; +static volatile Int32FuncPtr invokeNative_Int32 = + (Int32FuncPtr)(uintptr_t)invokeNative; +static volatile Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)(uintptr_t)invokeNative; -static Float32FuncPtr invokeNative_Float32 = +static volatile Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)(uintptr_t)invokeNative; -static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)(uintptr_t)invokeNative; +static volatile VoidFuncPtr invokeNative_Void = + (VoidFuncPtr)(uintptr_t)invokeNative; static inline void word_copy(uint32 *dest, uint32 *src, unsigned num) @@ -3762,19 +3768,8 @@ typedef uint32x4_t __m128i; #endif /* end of WASM_ENABLE_SIMD != 0 */ typedef void (*GenericFunctionPointer)(); -#if defined(__APPLE__) || defined(__MACH__) -/** - * Define the return type as 'void' in MacOS, since after converting - * 'int64 invokeNative' into 'float64 invokeNative_Float64', the - * return value passing might be invalid, the caller reads the return - * value from register rax but not xmm0. - */ void invokeNative(GenericFunctionPointer f, uint64 *args, uint64 n_stacks); -#else -int64 -invokeNative(GenericFunctionPointer f, uint64 *args, uint64 n_stacks); -#endif typedef float64 (*Float64FuncPtr)(GenericFunctionPointer, uint64 *, uint64); typedef float32 (*Float32FuncPtr)(GenericFunctionPointer, uint64 *, uint64); @@ -3782,13 +3777,16 @@ typedef int64 (*Int64FuncPtr)(GenericFunctionPointer, uint64 *, uint64); typedef int32 (*Int32FuncPtr)(GenericFunctionPointer, uint64 *, uint64); typedef void (*VoidFuncPtr)(GenericFunctionPointer, uint64 *, uint64); -static Float64FuncPtr invokeNative_Float64 = +static volatile Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)(uintptr_t)invokeNative; -static Float32FuncPtr invokeNative_Float32 = +static volatile Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)(uintptr_t)invokeNative; -static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)(uintptr_t)invokeNative; -static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)(uintptr_t)invokeNative; -static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)(uintptr_t)invokeNative; +static volatile Int64FuncPtr invokeNative_Int64 = + (Int64FuncPtr)(uintptr_t)invokeNative; +static volatile Int32FuncPtr invokeNative_Int32 = + (Int32FuncPtr)(uintptr_t)invokeNative; +static volatile VoidFuncPtr invokeNative_Void = + (VoidFuncPtr)(uintptr_t)invokeNative; #if WASM_ENABLE_SIMD != 0 typedef v128 (*V128FuncPtr)(GenericFunctionPointer, uint64 *, uint64); From eb3cdaaf3206cbe7c0173b87c6a1bd553d8b5fa4 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Sun, 26 Jun 2022 11:06:34 +0900 Subject: [PATCH 3/6] Fix macro redifinition warning for NuttX (#1250) Fix the following warning introduced by the recent change. ``` In file included from wamr/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/locking.h:17, from wamr/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.h:18, from wamr/core/iwasm/aot/../common/wasm_runtime_common.h:18, from wamr/core/iwasm/aot/aot_runtime.h:10, from wamr/core/iwasm/aot/aot_loader.c:6: wamr/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h:55: error: "CONFIG_HAS_ISATTY" redefined [-Werror] #define CONFIG_HAS_ISATTY 1 In file included from wamr/core/shared/utils/../platform/include/platform_common.h:13, from wamr/core/shared/utils/bh_platform.h:9, from wamr/core/iwasm/aot/aot_runtime.h:9, from wamr/core/iwasm/aot/aot_loader.c:6: wamr/core/shared/platform/nuttx/platform_internal.h:75: note: this is the location of the previous definition #define CONFIG_HAS_ISATTY 0 ``` --- .../libc-wasi/sandboxed-system-primitives/src/ssp_config.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h index 5ffcb6b37..47b65ca82 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h @@ -51,11 +51,17 @@ #define CONFIG_HAS_FDATASYNC 0 #endif +/* + * For NuttX, CONFIG_HAS_ISATTY is provided by its platform header. + * (platform_internal.h) + */ +#ifndef __NuttX__ #ifndef __CloudABI__ #define CONFIG_HAS_ISATTY 1 #else #define CONFIG_HAS_ISATTY 0 #endif +#endif #ifndef __APPLE__ #define CONFIG_HAS_POSIX_FALLOCATE 1 From 2746d297513a02b144ed2ca9558f746934269eac Mon Sep 17 00:00:00 2001 From: Cengizhan Pasaoglu Date: Mon, 27 Jun 2022 14:30:31 +0200 Subject: [PATCH 4/6] Make robust on choosing target assumption for X86_32 support (#1241) When WAMR_BUILD_TARGET isn't set, choosing right target is decided by checking `CMAKE_SIZEOF_VOID_P` variable. However, choosing `X86_32` target is not doing specifically checking size of void pointer. It is kind a fallback target for others. This patch explicitly checks the size of void pointer before setting the target to `X86_32` to fix the issue. --- CMakeLists.txt | 4 +++- build-scripts/runtime_lib.cmake | 4 +++- product-mini/platforms/android/CMakeLists.txt | 4 +++- product-mini/platforms/darwin/CMakeLists.txt | 4 +++- product-mini/platforms/linux-sgx/CMakeLists.txt | 4 +++- product-mini/platforms/linux-sgx/CMakeLists_minimal.txt | 4 +++- product-mini/platforms/linux/CMakeLists.txt | 4 +++- product-mini/platforms/vxworks/CMakeLists.txt | 4 +++- product-mini/platforms/windows/CMakeLists.txt | 4 +++- samples/basic/CMakeLists.txt | 4 +++- samples/multi-module/CMakeLists.txt | 4 +++- samples/multi-thread/CMakeLists.txt | 4 +++- samples/native-lib/CMakeLists.txt | 4 +++- samples/ref-types/CMakeLists.txt | 4 +++- samples/socket-api/CMakeLists.txt | 4 +++- samples/spawn-thread/CMakeLists.txt | 4 +++- samples/wasm-c-api/CMakeLists.txt | 4 +++- 17 files changed, 51 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2582b4926..a2abac7ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,9 +25,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/build-scripts/runtime_lib.cmake b/build-scripts/runtime_lib.cmake index e7f7860cf..ff714b132 100644 --- a/build-scripts/runtime_lib.cmake +++ b/build-scripts/runtime_lib.cmake @@ -41,9 +41,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/product-mini/platforms/android/CMakeLists.txt b/product-mini/platforms/android/CMakeLists.txt index c59f98c0d..b20011023 100644 --- a/product-mini/platforms/android/CMakeLists.txt +++ b/product-mini/platforms/android/CMakeLists.txt @@ -35,9 +35,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) if (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/product-mini/platforms/darwin/CMakeLists.txt b/product-mini/platforms/darwin/CMakeLists.txt index 6485b5903..588b5d166 100644 --- a/product-mini/platforms/darwin/CMakeLists.txt +++ b/product-mini/platforms/darwin/CMakeLists.txt @@ -22,9 +22,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/product-mini/platforms/linux-sgx/CMakeLists.txt b/product-mini/platforms/linux-sgx/CMakeLists.txt index 286d90596..6a06c061e 100644 --- a/product-mini/platforms/linux-sgx/CMakeLists.txt +++ b/product-mini/platforms/linux-sgx/CMakeLists.txt @@ -16,9 +16,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) if (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/product-mini/platforms/linux-sgx/CMakeLists_minimal.txt b/product-mini/platforms/linux-sgx/CMakeLists_minimal.txt index 336757401..9a33f8b47 100644 --- a/product-mini/platforms/linux-sgx/CMakeLists_minimal.txt +++ b/product-mini/platforms/linux-sgx/CMakeLists_minimal.txt @@ -16,9 +16,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) if (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/product-mini/platforms/linux/CMakeLists.txt b/product-mini/platforms/linux/CMakeLists.txt index c0b6f6a8c..542d27716 100644 --- a/product-mini/platforms/linux/CMakeLists.txt +++ b/product-mini/platforms/linux/CMakeLists.txt @@ -25,9 +25,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/product-mini/platforms/vxworks/CMakeLists.txt b/product-mini/platforms/vxworks/CMakeLists.txt index d681e9213..f15eb0594 100644 --- a/product-mini/platforms/vxworks/CMakeLists.txt +++ b/product-mini/platforms/vxworks/CMakeLists.txt @@ -24,9 +24,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) if (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/product-mini/platforms/windows/CMakeLists.txt b/product-mini/platforms/windows/CMakeLists.txt index bc82c8221..34f280fa5 100644 --- a/product-mini/platforms/windows/CMakeLists.txt +++ b/product-mini/platforms/windows/CMakeLists.txt @@ -23,9 +23,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) if (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(FATAL_ERROR "Unsupported build target platform!") endif () endif () diff --git a/samples/basic/CMakeLists.txt b/samples/basic/CMakeLists.txt index 7e10d4609..d408774da 100644 --- a/samples/basic/CMakeLists.txt +++ b/samples/basic/CMakeLists.txt @@ -33,9 +33,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/samples/multi-module/CMakeLists.txt b/samples/multi-module/CMakeLists.txt index e3edd0476..26c99d828 100644 --- a/samples/multi-module/CMakeLists.txt +++ b/samples/multi-module/CMakeLists.txt @@ -27,9 +27,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/samples/multi-thread/CMakeLists.txt b/samples/multi-thread/CMakeLists.txt index 89c983862..63c14eebd 100644 --- a/samples/multi-thread/CMakeLists.txt +++ b/samples/multi-thread/CMakeLists.txt @@ -27,9 +27,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/samples/native-lib/CMakeLists.txt b/samples/native-lib/CMakeLists.txt index 3968393c6..00eb40d94 100644 --- a/samples/native-lib/CMakeLists.txt +++ b/samples/native-lib/CMakeLists.txt @@ -27,9 +27,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/samples/ref-types/CMakeLists.txt b/samples/ref-types/CMakeLists.txt index 229afd3c4..3aac01d42 100644 --- a/samples/ref-types/CMakeLists.txt +++ b/samples/ref-types/CMakeLists.txt @@ -33,9 +33,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/samples/socket-api/CMakeLists.txt b/samples/socket-api/CMakeLists.txt index 936287c7d..5ce2543b9 100644 --- a/samples/socket-api/CMakeLists.txt +++ b/samples/socket-api/CMakeLists.txt @@ -125,9 +125,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/samples/spawn-thread/CMakeLists.txt b/samples/spawn-thread/CMakeLists.txt index 794ec2aa2..16618e303 100644 --- a/samples/spawn-thread/CMakeLists.txt +++ b/samples/spawn-thread/CMakeLists.txt @@ -27,9 +27,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () diff --git a/samples/wasm-c-api/CMakeLists.txt b/samples/wasm-c-api/CMakeLists.txt index c395b627a..38838e698 100644 --- a/samples/wasm-c-api/CMakeLists.txt +++ b/samples/wasm-c-api/CMakeLists.txt @@ -39,9 +39,11 @@ if (NOT DEFINED WAMR_BUILD_TARGET) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") - else () + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) # Build as X86_32 by default in 32-bit platform set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") endif () endif () From 5e238322c2c110f31df3102056d1c307de14db3c Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 28 Jun 2022 14:53:01 +0800 Subject: [PATCH 5/6] Enable aot compiler with llvm-14/15 (#1252) Enable aot compiler and jit based on llvm-14.0 and llvm-15.0git, replace LLVMBuildLoad/LLVMBuildInBoundsGEP/LLVMBuildCall with LLVMBuildLoad2/LLVMBuildInBoundsGEP2/LLVMBuildCall2, and pass them with related types, so as to meet the requirements of opaque pointers. And fix several compilation errors for llvm-14.0/15.0git. Most spec cases and standalone cases are tested. --- core/iwasm/compilation/aot_compiler.c | 7 + core/iwasm/compilation/aot_emit_const.c | 6 +- core/iwasm/compilation/aot_emit_control.c | 11 +- core/iwasm/compilation/aot_emit_exception.c | 3 +- core/iwasm/compilation/aot_emit_function.c | 171 ++++++----- core/iwasm/compilation/aot_emit_memory.c | 130 +++++---- core/iwasm/compilation/aot_emit_table.c | 74 +++-- core/iwasm/compilation/aot_emit_variable.c | 18 +- core/iwasm/compilation/aot_llvm.c | 267 ++++++++++-------- core/iwasm/compilation/aot_llvm.h | 14 + core/iwasm/compilation/aot_llvm_extra.cpp | 4 + core/iwasm/compilation/simd/simd_load_store.c | 27 +- 12 files changed, 431 insertions(+), 301 deletions(-) diff --git a/core/iwasm/compilation/aot_compiler.c b/core/iwasm/compilation/aot_compiler.c index 09c3be273..7491023cd 100644 --- a/core/iwasm/compilation/aot_compiler.c +++ b/core/iwasm/compilation/aot_compiler.c @@ -2641,7 +2641,12 @@ apply_func_passes(AOTCompContext *comp_ctx) LLVMAddLoopVectorizePass(pass_mgr); LLVMAddSLPVectorizePass(pass_mgr); LLVMAddLoopRotatePass(pass_mgr); +#if LLVM_VERSION_MAJOR < 15 LLVMAddLoopUnswitchPass(pass_mgr); + /* Binding disabled in LLVM 15, don't add the pass util we can either + add a binding to SimpleLoopUnswitchPass, or add it to + aot_llvm_extra.cpp */ +#endif LLVMAddInstructionCombiningPass(pass_mgr); LLVMAddCFGSimplificationPass(pass_mgr); if (!comp_ctx->enable_thread_mgr) { @@ -2694,8 +2699,10 @@ apply_lto_passes(AOTCompContext *comp_ctx) LLVMPassManagerBuilderSetOptLevel(pass_mgr_builder, comp_ctx->opt_level); LLVMPassManagerBuilderPopulateModulePassManager(pass_mgr_builder, common_pass_mgr); +#if LLVM_VERSION_MAJOR < 15 LLVMPassManagerBuilderPopulateLTOPassManager(pass_mgr_builder, common_pass_mgr, true, true); +#endif #if WASM_ENABLE_LAZY_JIT == 0 LLVMRunPassManager(common_pass_mgr, comp_ctx->module); diff --git a/core/iwasm/compilation/aot_emit_const.c b/core/iwasm/compilation/aot_emit_const.c index 5b6bab46e..949b275ad 100644 --- a/core/iwasm/compilation/aot_emit_const.c +++ b/core/iwasm/compilation/aot_emit_const.c @@ -72,7 +72,8 @@ aot_compile_op_f32_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_set_last_error("llvm build bitcast failed."); return false; } - if (!(value = LLVMBuildLoad(comp_ctx->builder, alloca, ""))) { + if (!(value = + LLVMBuildLoad2(comp_ctx->builder, F32_TYPE, alloca, ""))) { aot_set_last_error("llvm build load failed."); return false; } @@ -127,7 +128,8 @@ aot_compile_op_f64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_set_last_error("llvm build bitcast failed."); return false; } - if (!(value = LLVMBuildLoad(comp_ctx->builder, alloca, ""))) { + if (!(value = + LLVMBuildLoad2(comp_ctx->builder, F64_TYPE, alloca, ""))) { aot_set_last_error("llvm build load failed."); return false; } diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index 9c90cd006..6d452b04f 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -677,9 +677,9 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) /* Offset of suspend_flags */ offset = I32_FIVE; - if (!(terminate_addr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env, - &offset, 1, "terminate_addr"))) { + if (!(terminate_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->exec_env, &offset, 1, + "terminate_addr"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } @@ -690,8 +690,9 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) return false; } - if (!(terminate_flags = LLVMBuildLoad(comp_ctx->builder, terminate_addr, - "terminate_flags"))) { + if (!(terminate_flags = + LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, terminate_addr, + "terminate_flags"))) { aot_set_last_error("llvm build bit cast failed"); return false; } diff --git a/core/iwasm/compilation/aot_emit_exception.c b/core/iwasm/compilation/aot_emit_exception.c index 1ec606b47..3a16f7f88 100644 --- a/core/iwasm/compilation/aot_emit_exception.c +++ b/core/iwasm/compilation/aot_emit_exception.c @@ -96,7 +96,8 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, /* Call the aot_set_exception_with_id() function */ param_values[0] = func_ctx->aot_inst; param_values[1] = func_ctx->exception_id_phi; - if (!LLVMBuildCall(comp_ctx->builder, func, param_values, 2, "")) { + if (!LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, 2, + "")) { aot_set_last_error("llvm build call failed."); return false; } diff --git a/core/iwasm/compilation/aot_emit_function.c b/core/iwasm/compilation/aot_emit_function.c index 0510172ff..1065b4c77 100644 --- a/core/iwasm/compilation/aot_emit_function.c +++ b/core/iwasm/compilation/aot_emit_function.c @@ -57,8 +57,8 @@ check_exception_thrown(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) /* Load the first byte of aot_module_inst->cur_exception, and check whether it is '\0'. If yes, no exception was thrown. */ - if (!(value = LLVMBuildLoad(comp_ctx->builder, func_ctx->cur_exception, - "exce_value")) + if (!(value = LLVMBuildLoad2(comp_ctx->builder, INT8_TYPE, + func_ctx->cur_exception, "exce_value")) || !(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntEQ, value, I8_ZERO, "cmp"))) { aot_set_last_error("llvm build icmp failed."); @@ -207,8 +207,9 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } snprintf(buf, sizeof(buf), "%s%d", "elem", i); - if (!(elem_ptr = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->argv_buf, &elem_idx, 1, buf)) + if (!(elem_ptr = + LLVMBuildInBoundsGEP2(comp_ctx->builder, I32_TYPE, + func_ctx->argv_buf, &elem_idx, 1, buf)) || !(elem_ptr = LLVMBuildBitCast(comp_ctx->builder, elem_ptr, elem_ptr_type, buf))) { aot_set_last_error("llvm build bit cast failed."); @@ -236,8 +237,8 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* call aot_invoke_native() function */ - if (!(res = LLVMBuildCall(comp_ctx->builder, func, func_param_values, 4, - "res"))) { + if (!(res = LLVMBuildCall2(comp_ctx->builder, func_type, func, + func_param_values, 4, "res"))) { aot_set_last_error("llvm build call failed."); return false; } @@ -255,8 +256,8 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_set_last_error("llvm build bit cast failed."); return false; } - if (!(*p_value_ret = - LLVMBuildLoad(comp_ctx->builder, value_ret, "value_ret"))) { + if (!(*p_value_ret = LLVMBuildLoad2(comp_ctx->builder, ret_type, + value_ret, "value_ret"))) { aot_set_last_error("llvm build load failed."); return false; } @@ -299,14 +300,15 @@ lookup_orcjit_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMPositionBuilderAtEnd(comp_ctx->builder, block_curr); /* Load function pointer */ - if (!(func_ptr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->func_ptrs, - &func_idx, 1, "func_ptr_tmp"))) { + if (!(func_ptr = LLVMBuildInBoundsGEP2(comp_ctx->builder, OPQ_PTR_TYPE, + func_ctx->func_ptrs, &func_idx, 1, + "func_ptr_tmp"))) { aot_set_last_error("llvm build inbounds gep failed."); return false; } - if (!(func = LLVMBuildLoad(comp_ctx->builder, func_ptr, "func_ptr"))) { + if (!(func = LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, func_ptr, + "func_ptr"))) { aot_set_last_error("llvm build load failed."); return false; } @@ -364,8 +366,8 @@ lookup_orcjit_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* Call the function */ - if (!(func = LLVMBuildCall(comp_ctx->builder, func, param_values, 3, - "call_orcjit_lookup"))) { + if (!(func = LLVMBuildCall2(comp_ctx->builder, func_type, func, + param_values, 3, "call_orcjit_lookup"))) { aot_set_last_error("LLVM build call failed."); return false; } @@ -410,8 +412,9 @@ call_aot_alloc_frame_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, param_values[0] = func_ctx->exec_env; param_values[1] = func_idx; - if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 2, - "call_aot_alloc_frame"))) { + if (!(ret_value = + LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, + 2, "call_aot_alloc_frame"))) { aot_set_last_error("llvm build call failed."); return false; } @@ -462,8 +465,8 @@ call_aot_free_frame_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) param_values[0] = func_ctx->exec_env; - if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 1, - "call_aot_free_frame"))) { + if (!(ret_value = LLVMBuildCall2(comp_ctx->builder, func_type, func, + param_values, 1, "call_aot_free_frame"))) { aot_set_last_error("llvm build call failed."); return false; } @@ -488,8 +491,8 @@ check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } - if (!(stack_bound = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->native_stack_bound, + if (!(stack_bound = LLVMBuildInBoundsGEP2( + comp_ctx->builder, INT8_TYPE, func_ctx->native_stack_bound, &callee_local_size, 1, "stack_bound"))) { aot_set_last_error("llvm build inbound gep failed."); return false; @@ -603,8 +606,8 @@ check_app_addr_and_convert(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* call aot_check_app_addr_and_convert() function */ - if (!(res = LLVMBuildCall(comp_ctx->builder, func, func_param_values, 5, - "res"))) { + if (!(res = LLVMBuildCall2(comp_ctx->builder, func_type, func, + func_param_values, 5, "res"))) { aot_set_last_error("llvm build call failed."); return false; } @@ -614,8 +617,9 @@ check_app_addr_and_convert(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } - if (!(*p_native_addr_converted = LLVMBuildLoad( - comp_ctx->builder, native_addr_ptr, "native_addr"))) { + if (!(*p_native_addr_converted = + LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, native_addr_ptr, + "native_addr"))) { aot_set_last_error("llvm build load failed."); return false; } @@ -734,9 +738,9 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } snprintf(buf, sizeof(buf), "ext_ret%d_ptr", i); - if (!(ext_ret_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, - func_ctx->argv_buf, - &ext_ret_idx, 1, buf))) { + if (!(ext_ret_ptr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, I32_TYPE, func_ctx->argv_buf, + &ext_ret_idx, 1, buf))) { aot_set_last_error("llvm build GEP failed."); goto fail; } @@ -841,15 +845,15 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* Load function pointer */ - if (!(func_ptr = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->func_ptrs, &import_func_idx, - 1, "native_func_ptr_tmp"))) { + if (!(func_ptr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->func_ptrs, + &import_func_idx, 1, "native_func_ptr_tmp"))) { aot_set_last_error("llvm build inbounds gep failed."); goto fail; } - if (!(func_ptr = LLVMBuildLoad(comp_ctx->builder, func_ptr, - "native_func_ptr"))) { + if (!(func_ptr = LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, + func_ptr, "native_func_ptr"))) { aot_set_last_error("llvm build load failed."); goto fail; } @@ -861,8 +865,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* Call the function */ - if (!(value_ret = LLVMBuildCall( - comp_ctx->builder, func, param_values, + if (!(value_ret = LLVMBuildCall2( + comp_ctx->builder, native_func_type, func, param_values, (uint32)param_count + 1 + ext_ret_count, (func_type->result_count > 0 ? "call" : "")))) { aot_set_last_error("LLVM build call failed."); @@ -877,6 +881,9 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } } else { +#if LLVM_VERSION_MAJOR >= 14 + LLVMTypeRef llvm_func_type; +#endif bool recursive_call = (func_ctx == func_ctxes[func_idx - import_func_count]) ? true : false; @@ -943,11 +950,15 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, && !check_stack_boundary(comp_ctx, func_ctx, callee_cell_num)) goto fail; +#if LLVM_VERSION_MAJOR >= 14 + llvm_func_type = func_ctxes[func_idx - import_func_count]->func_type; +#endif + /* Call the function */ - if (!(value_ret = - LLVMBuildCall(comp_ctx->builder, func, param_values, - (uint32)param_count + 1 + ext_ret_count, - (func_type->result_count > 0 ? "call" : "")))) { + if (!(value_ret = LLVMBuildCall2( + comp_ctx->builder, llvm_func_type, func, param_values, + (uint32)param_count + 1 + ext_ret_count, + (func_type->result_count > 0 ? "call" : "")))) { aot_set_last_error("LLVM build call failed."); goto fail; } @@ -972,9 +983,9 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, /* Load extra result from its address and push to stack */ for (i = 0; i < ext_ret_count; i++) { snprintf(buf, sizeof(buf), "func%d_ext_ret%d", func_idx, i); - if (!(ext_ret = - LLVMBuildLoad(comp_ctx->builder, - param_values[1 + param_count + i], buf))) { + if (!(ext_ret = LLVMBuildLoad2( + comp_ctx->builder, TO_LLVM_TYPE(ext_ret_types[i]), + param_values[1 + param_count + i], buf))) { aot_set_last_error("llvm build load failed."); goto fail; } @@ -1084,8 +1095,9 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } snprintf(buf, sizeof(buf), "%s%d", "elem", i); - if (!(elem_ptr = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->argv_buf, &elem_idx, 1, buf)) + if (!(elem_ptr = + LLVMBuildInBoundsGEP2(comp_ctx->builder, I32_TYPE, + func_ctx->argv_buf, &elem_idx, 1, buf)) || !(elem_ptr = LLVMBuildBitCast(comp_ctx->builder, elem_ptr, elem_ptr_type, buf))) { aot_set_last_error("llvm build bit cast failed."); @@ -1114,8 +1126,8 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* call aot_call_indirect() function */ - if (!(res = LLVMBuildCall(comp_ctx->builder, func, func_param_values, 5, - "res"))) { + if (!(res = LLVMBuildCall2(comp_ctx->builder, func_type, func, + func_param_values, 5, "res"))) { aot_set_last_error("llvm build call failed."); return false; } @@ -1131,8 +1143,9 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } snprintf(buf, sizeof(buf), "argv_ret%d", i); - if (!(ret_ptr = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->argv_buf, &ret_idx, 1, buf)) + if (!(ret_ptr = + LLVMBuildInBoundsGEP2(comp_ctx->builder, I32_TYPE, + func_ctx->argv_buf, &ret_idx, 1, buf)) || !(ret_ptr = LLVMBuildBitCast(comp_ctx->builder, ret_ptr, ret_ptr_type, buf))) { aot_set_last_error("llvm build GEP or bit cast failed."); @@ -1140,7 +1153,8 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } snprintf(buf, sizeof(buf), "ret%d", i); - if (!(value_rets[i] = LLVMBuildLoad(comp_ctx->builder, ret_ptr, buf))) { + if (!(value_rets[i] = + LLVMBuildLoad2(comp_ctx->builder, ret_type, ret_ptr, buf))) { aot_set_last_error("llvm build load failed."); return false; } @@ -1208,8 +1222,9 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - if (!(table_size_const = LLVMBuildGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "cur_size_i8p"))) { + if (!(table_size_const = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->aot_inst, &offset, + 1, "cur_size_i8p"))) { HANDLE_FAILURE("LLVMBuildGEP"); goto fail; } @@ -1221,8 +1236,8 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - if (!(table_size_const = - LLVMBuildLoad(comp_ctx->builder, table_size_const, "cur_size"))) { + if (!(table_size_const = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, + table_size_const, "cur_size"))) { HANDLE_FAILURE("LLVMBuildLoad"); goto fail; } @@ -1255,8 +1270,9 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "table_elem_i8p"))) { + if (!(table_elem = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->aot_inst, &offset, 1, + "table_elem_i8p"))) { aot_set_last_error("llvm build add failed."); goto fail; } @@ -1268,14 +1284,15 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* Load function index */ - if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, 1, - "table_elem"))) { + if (!(table_elem = + LLVMBuildInBoundsGEP2(comp_ctx->builder, I32_TYPE, table_elem, + &elem_idx, 1, "table_elem"))) { HANDLE_FAILURE("LLVMBuildNUWAdd"); goto fail; } - if (!(func_idx = - LLVMBuildLoad(comp_ctx->builder, table_elem, "func_idx"))) { + if (!(func_idx = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, table_elem, + "func_idx"))) { aot_set_last_error("llvm build load failed."); goto fail; } @@ -1302,15 +1319,15 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; /* Load function type index */ - if (!(ftype_idx_ptr = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->func_type_indexes, &func_idx, 1, - "ftype_idx_ptr"))) { + if (!(ftype_idx_ptr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, I32_TYPE, func_ctx->func_type_indexes, + &func_idx, 1, "ftype_idx_ptr"))) { aot_set_last_error("llvm build inbounds gep failed."); goto fail; } - if (!(ftype_idx = - LLVMBuildLoad(comp_ctx->builder, ftype_idx_ptr, "ftype_idx"))) { + if (!(ftype_idx = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, ftype_idx_ptr, + "ftype_idx"))) { aot_set_last_error("llvm build load failed."); goto fail; } @@ -1399,9 +1416,9 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, CHECK_LLVM_CONST(ext_ret_offset); snprintf(buf, sizeof(buf), "ext_ret%d_ptr", i - 1); - if (!(ext_ret_ptr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->argv_buf, - &ext_ret_offset, 1, buf))) { + if (!(ext_ret_ptr = LLVMBuildInBoundsGEP2(comp_ctx->builder, I32_TYPE, + func_ctx->argv_buf, + &ext_ret_offset, 1, buf))) { aot_set_last_error("llvm build GEP failed."); goto fail; } @@ -1553,14 +1570,15 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, #if WASM_ENABLE_LAZY_JIT == 0 /* Load function pointer */ - if (!(func_ptr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->func_ptrs, - &func_idx, 1, "func_ptr_tmp"))) { + if (!(func_ptr = LLVMBuildInBoundsGEP2(comp_ctx->builder, OPQ_PTR_TYPE, + func_ctx->func_ptrs, &func_idx, 1, + "func_ptr_tmp"))) { aot_set_last_error("llvm build inbounds gep failed."); goto fail; } - if (!(func_ptr = LLVMBuildLoad(comp_ctx->builder, func_ptr, "func_ptr"))) { + if (!(func_ptr = LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, func_ptr, + "func_ptr"))) { aot_set_last_error("llvm build load failed."); goto fail; } @@ -1584,9 +1602,9 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - if (!(value_ret = LLVMBuildCall(comp_ctx->builder, func, param_values, - total_param_count, - func_result_count > 0 ? "ret" : ""))) { + if (!(value_ret = LLVMBuildCall2(comp_ctx->builder, llvm_func_type, func, + param_values, total_param_count, + func_result_count > 0 ? "ret" : ""))) { aot_set_last_error("llvm build call failed."); goto fail; } @@ -1603,10 +1621,11 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, /* Load extra result from its address and push to stack */ for (i = 1; i < func_result_count; i++) { + ret_type = TO_LLVM_TYPE(func_type->types[func_param_count + i]); snprintf(buf, sizeof(buf), "ext_ret%d", i - 1); - if (!(ext_ret = - LLVMBuildLoad(comp_ctx->builder, - param_values[func_param_count + i], buf))) { + if (!(ext_ret = LLVMBuildLoad2(comp_ctx->builder, ret_type, + param_values[func_param_count + i], + buf))) { aot_set_last_error("llvm build load failed."); goto fail; } diff --git a/core/iwasm/compilation/aot_emit_memory.c b/core/iwasm/compilation/aot_emit_memory.c index 7bba057d3..aacc16406 100644 --- a/core/iwasm/compilation/aot_emit_memory.c +++ b/core/iwasm/compilation/aot_emit_memory.c @@ -65,8 +65,10 @@ get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (func_ctx->mem_space_unchanged) return mem_check_bound; - if (!(mem_check_bound = LLVMBuildLoad(comp_ctx->builder, mem_check_bound, - "mem_check_bound"))) { + if (!(mem_check_bound = LLVMBuildLoad2( + comp_ctx->builder, + (comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE : I32_TYPE, + mem_check_bound, "mem_check_bound"))) { aot_set_last_error("llvm build load failed."); return NULL; } @@ -106,9 +108,9 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, mem_base_addr = func_ctx->mem_info[0].mem_base_addr; } else { - if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_info[0].mem_base_addr, - "mem_base"))) { + if (!(mem_base_addr = LLVMBuildLoad2( + comp_ctx->builder, OPQ_PTR_TYPE, + func_ctx->mem_info[0].mem_base_addr, "mem_base"))) { aot_set_last_error("llvm build load failed."); goto fail; } @@ -147,8 +149,9 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, /* inside memory space */ offset1 = I32_CONST((uint32)mem_offset); CHECK_LLVM_CONST(offset1); - if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr, - &offset1, 1, "maddr"))) { + if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + mem_base_addr, &offset1, 1, + "maddr"))) { aot_set_last_error("llvm build add failed."); goto fail; } @@ -229,8 +232,8 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* maddr = mem_base_addr + offset1 */ - if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr, - &offset1, 1, "maddr"))) { + if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + mem_base_addr, &offset1, 1, "maddr"))) { aot_set_last_error("llvm build add failed."); goto fail; } @@ -248,9 +251,10 @@ fail: } \ } while (0) -#define BUILD_LOAD() \ +#define BUILD_LOAD(data_type) \ do { \ - if (!(value = LLVMBuildLoad(comp_ctx->builder, maddr, "data"))) { \ + if (!(value = LLVMBuildLoad2(comp_ctx->builder, data_type, maddr, \ + "data"))) { \ aot_set_last_error("llvm build load failed."); \ goto fail; \ } \ @@ -333,12 +337,13 @@ fail: return false; } -#define BUILD_ATOMIC_LOAD(align) \ +#define BUILD_ATOMIC_LOAD(align, data_type) \ do { \ if (!(check_memory_alignment(comp_ctx, func_ctx, maddr, align))) { \ goto fail; \ } \ - if (!(value = LLVMBuildLoad(comp_ctx->builder, maddr, "data"))) { \ + if (!(value = LLVMBuildLoad2(comp_ctx->builder, data_type, maddr, \ + "data"))) { \ aot_set_last_error("llvm build load failed."); \ goto fail; \ } \ @@ -369,6 +374,7 @@ aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, bool atomic) { LLVMValueRef maddr, value = NULL; + LLVMTypeRef data_type; if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes))) return false; @@ -378,26 +384,31 @@ aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, BUILD_PTR_CAST(INT32_PTR_TYPE); #if WASM_ENABLE_SHARED_MEMORY != 0 if (atomic) - BUILD_ATOMIC_LOAD(align); + BUILD_ATOMIC_LOAD(align, I32_TYPE); else #endif - BUILD_LOAD(); + BUILD_LOAD(I32_TYPE); break; case 2: case 1: - if (bytes == 2) + if (bytes == 2) { BUILD_PTR_CAST(INT16_PTR_TYPE); - else + data_type = INT16_TYPE; + } + else { BUILD_PTR_CAST(INT8_PTR_TYPE); + data_type = INT8_TYPE; + } + #if WASM_ENABLE_SHARED_MEMORY != 0 if (atomic) { - BUILD_ATOMIC_LOAD(align); + BUILD_ATOMIC_LOAD(align, data_type); BUILD_ZERO_EXT(I32_TYPE); } else #endif { - BUILD_LOAD(); + BUILD_LOAD(data_type); if (sign) BUILD_SIGN_EXT(I32_TYPE); else @@ -410,6 +421,7 @@ aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } PUSH_I32(value); + (void)data_type; return true; fail: return false; @@ -421,6 +433,7 @@ aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, bool atomic) { LLVMValueRef maddr, value = NULL; + LLVMTypeRef data_type; if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes))) return false; @@ -430,29 +443,36 @@ aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, BUILD_PTR_CAST(INT64_PTR_TYPE); #if WASM_ENABLE_SHARED_MEMORY != 0 if (atomic) - BUILD_ATOMIC_LOAD(align); + BUILD_ATOMIC_LOAD(align, I64_TYPE); else #endif - BUILD_LOAD(); + BUILD_LOAD(I64_TYPE); break; case 4: case 2: case 1: - if (bytes == 4) + if (bytes == 4) { BUILD_PTR_CAST(INT32_PTR_TYPE); - else if (bytes == 2) + data_type = I32_TYPE; + } + else if (bytes == 2) { BUILD_PTR_CAST(INT16_PTR_TYPE); - else + data_type = INT16_TYPE; + } + else { BUILD_PTR_CAST(INT8_PTR_TYPE); + data_type = INT8_TYPE; + } + #if WASM_ENABLE_SHARED_MEMORY != 0 if (atomic) { - BUILD_ATOMIC_LOAD(align); + BUILD_ATOMIC_LOAD(align, data_type); BUILD_ZERO_EXT(I64_TYPE); } else #endif { - BUILD_LOAD(); + BUILD_LOAD(data_type); if (sign) BUILD_SIGN_EXT(I64_TYPE); else @@ -465,6 +485,7 @@ aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } PUSH_I64(value); + (void)data_type; return true; fail: return false; @@ -480,7 +501,7 @@ aot_compile_op_f32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; BUILD_PTR_CAST(F32_PTR_TYPE); - BUILD_LOAD(); + BUILD_LOAD(F32_TYPE); PUSH_F32(value); return true; fail: @@ -497,7 +518,7 @@ aot_compile_op_f64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; BUILD_PTR_CAST(F64_PTR_TYPE); - BUILD_LOAD(); + BUILD_LOAD(F64_TYPE); PUSH_F64(value); return true; fail: @@ -631,8 +652,8 @@ get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) mem_size = func_ctx->mem_info[0].mem_cur_page_count_addr; } else { - if (!(mem_size = LLVMBuildLoad( - comp_ctx->builder, + if (!(mem_size = LLVMBuildLoad2( + comp_ctx->builder, I32_TYPE, func_ctx->mem_info[0].mem_cur_page_count_addr, "mem_size"))) { aot_set_last_error("llvm build load failed."); goto fail; @@ -720,8 +741,8 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) /* Call function aot_enlarge_memory() */ param_values[0] = func_ctx->aot_inst; param_values[1] = delta; - if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 2, - "call"))) { + if (!(ret_value = LLVMBuildCall2(comp_ctx->builder, func_type, func, + param_values, 2, "call"))) { aot_set_last_error("llvm build call failed."); return false; } @@ -765,9 +786,9 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, mem_base_addr = func_ctx->mem_info[0].mem_base_addr; } else { - if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_info[0].mem_base_addr, - "mem_base"))) { + if (!(mem_base_addr = LLVMBuildLoad2( + comp_ctx->builder, OPQ_PTR_TYPE, + func_ctx->mem_info[0].mem_base_addr, "mem_base"))) { aot_set_last_error("llvm build load failed."); goto fail; } @@ -793,8 +814,9 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (mem_data_size > 0 && mem_offset + mem_len <= mem_data_size) { /* inside memory space */ /* maddr = mem_base_addr + moffset */ - if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr, - &offset, 1, "maddr"))) { + if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + mem_base_addr, &offset, 1, + "maddr"))) { aot_set_last_error("llvm build add failed."); goto fail; } @@ -806,9 +828,9 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, mem_size = func_ctx->mem_info[0].mem_data_size_addr; } else { - if (!(mem_size = LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_info[0].mem_data_size_addr, - "mem_size"))) { + if (!(mem_size = LLVMBuildLoad2( + comp_ctx->builder, I32_TYPE, + func_ctx->mem_info[0].mem_data_size_addr, "mem_size"))) { aot_set_last_error("llvm build load failed."); goto fail; } @@ -832,8 +854,8 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* maddr = mem_base_addr + offset */ - if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr, - &offset, 1, "maddr"))) { + if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + mem_base_addr, &offset, 1, "maddr"))) { aot_set_last_error("llvm build add failed."); goto fail; } @@ -873,8 +895,8 @@ aot_compile_op_memory_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, param_values[2] = offset; param_values[3] = len; param_values[4] = dst; - if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 5, - "call"))) { + if (!(ret_value = LLVMBuildCall2(comp_ctx->builder, func_type, func, + param_values, 5, "call"))) { aot_set_last_error("llvm build call failed."); return false; } @@ -926,8 +948,8 @@ aot_compile_op_data_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, /* Call function aot_data_drop() */ param_values[0] = func_ctx->aot_inst; param_values[1] = seg; - if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 2, - "call"))) { + if (!(ret_value = LLVMBuildCall2(comp_ctx->builder, func_type, func, + param_values, 2, "call"))) { aot_set_last_error("llvm build call failed."); return false; } @@ -1001,8 +1023,8 @@ aot_compile_op_memory_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) params[0] = dst_addr; params[1] = src_addr; params[2] = len; - if (!(res = LLVMBuildCall(comp_ctx->builder, func, params, 3, - "call_memmove"))) { + if (!(res = LLVMBuildCall2(comp_ctx->builder, func_type, func, params, + 3, "call_memmove"))) { aot_set_last_error("llvm build memmove failed."); return false; } @@ -1079,8 +1101,8 @@ aot_compile_op_memory_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) params[0] = dst_addr; params[1] = val; params[2] = len; - if (!(res = LLVMBuildCall(comp_ctx->builder, func, params, 3, - "call_memset"))) { + if (!(res = LLVMBuildCall2(comp_ctx->builder, func_type, func, params, 3, + "call_memset"))) { aot_set_last_error("llvm build memset failed."); return false; } @@ -1297,8 +1319,8 @@ aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, param_values[2] = expect; param_values[3] = timeout; param_values[4] = is_wait64; - if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 5, - "call"))) { + if (!(ret_value = LLVMBuildCall2(comp_ctx->builder, func_type, func, + param_values, 5, "call"))) { aot_set_last_error("llvm build call failed."); return false; } @@ -1360,8 +1382,8 @@ aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx, param_values[0] = func_ctx->aot_inst; param_values[1] = maddr; param_values[2] = count; - if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 3, - "call"))) { + if (!(ret_value = LLVMBuildCall2(comp_ctx->builder, func_type, func, + param_values, 3, "call"))) { aot_set_last_error("llvm build call failed."); return false; } diff --git a/core/iwasm/compilation/aot_emit_table.c b/core/iwasm/compilation/aot_emit_table.c index d3598c928..984ce8a04 100644 --- a/core/iwasm/compilation/aot_emit_table.c +++ b/core/iwasm/compilation/aot_emit_table.c @@ -58,9 +58,10 @@ aot_compile_get_tbl_inst(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - if (!(tbl_inst = LLVMBuildGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "tbl_inst"))) { - HANDLE_FAILURE("LLVMBuildGEP"); + if (!(tbl_inst = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->aot_inst, &offset, 1, + "tbl_inst"))) { + HANDLE_FAILURE("LLVMBuildInBoundsGEP"); goto fail; } @@ -90,8 +91,8 @@ aot_compile_op_elem_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* "" means return void */ - if (!(ret_value = - LLVMBuildCall(comp_ctx->builder, func, param_values, 2, ""))) { + if (!(ret_value = LLVMBuildCall2(comp_ctx->builder, func_type, func, + param_values, 2, ""))) { HANDLE_FAILURE("LLVMBuildCall"); goto fail; } @@ -115,9 +116,10 @@ aot_check_table_access(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - if (!(tbl_sz = LLVMBuildGEP(comp_ctx->builder, func_ctx->aot_inst, &offset, - 1, "cur_size_i8p"))) { - HANDLE_FAILURE("LLVMBuildGEP"); + if (!(tbl_sz = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->aot_inst, &offset, 1, + "cur_size_i8p"))) { + HANDLE_FAILURE("LLVMBuildInBoundsGEP"); goto fail; } @@ -127,7 +129,8 @@ aot_check_table_access(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - if (!(tbl_sz = LLVMBuildLoad(comp_ctx->builder, tbl_sz, "cur_size"))) { + if (!(tbl_sz = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, tbl_sz, + "cur_size"))) { HANDLE_FAILURE("LLVMBuildLoad"); goto fail; } @@ -178,8 +181,9 @@ aot_compile_op_table_get(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "table_elem_i8p"))) { + if (!(table_elem = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->aot_inst, &offset, 1, + "table_elem_i8p"))) { aot_set_last_error("llvm build add failed."); goto fail; } @@ -191,14 +195,15 @@ aot_compile_op_table_get(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* Load function index */ - if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, 1, - "table_elem"))) { + if (!(table_elem = + LLVMBuildInBoundsGEP2(comp_ctx->builder, I32_TYPE, table_elem, + &elem_idx, 1, "table_elem"))) { HANDLE_FAILURE("LLVMBuildNUWAdd"); goto fail; } - if (!(func_idx = - LLVMBuildLoad(comp_ctx->builder, table_elem, "func_idx"))) { + if (!(func_idx = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, table_elem, + "func_idx"))) { HANDLE_FAILURE("LLVMBuildLoad"); goto fail; } @@ -230,9 +235,10 @@ aot_compile_op_table_set(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "table_elem_i8p"))) { - HANDLE_FAILURE("LLVMBuildGEP"); + if (!(table_elem = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->aot_inst, &offset, 1, + "table_elem_i8p"))) { + HANDLE_FAILURE("LLVMBuildInBoundsGEP"); goto fail; } @@ -243,9 +249,10 @@ aot_compile_op_table_set(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* Load function index */ - if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, 1, - "table_elem"))) { - HANDLE_FAILURE("LLVMBuildGEP"); + if (!(table_elem = + LLVMBuildInBoundsGEP2(comp_ctx->builder, I32_TYPE, table_elem, + &elem_idx, 1, "table_elem"))) { + HANDLE_FAILURE("LLVMBuildInBoundsGEP"); goto fail; } @@ -297,7 +304,8 @@ aot_compile_op_table_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, POP_I32(param_values[5]); /* "" means return void */ - if (!(LLVMBuildCall(comp_ctx->builder, func, param_values, 6, ""))) { + if (!(LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, 6, + ""))) { HANDLE_FAILURE("LLVMBuildCall"); goto fail; } @@ -344,7 +352,8 @@ aot_compile_op_table_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, POP_I32(param_values[5]); /* "" means return void */ - if (!(LLVMBuildCall(comp_ctx->builder, func, param_values, 6, ""))) { + if (!(LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, 6, + ""))) { HANDLE_FAILURE("LLVMBuildCall"); goto fail; } @@ -366,9 +375,10 @@ aot_compile_op_table_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - if (!(tbl_sz = LLVMBuildGEP(comp_ctx->builder, func_ctx->aot_inst, &offset, - 1, "tbl_sz_ptr_i8"))) { - HANDLE_FAILURE("LLVMBuildGEP"); + if (!(tbl_sz = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->aot_inst, &offset, 1, + "tbl_sz_ptr_i8"))) { + HANDLE_FAILURE("LLVMBuildInBoundsGEP"); goto fail; } @@ -378,7 +388,8 @@ aot_compile_op_table_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - if (!(tbl_sz = LLVMBuildLoad(comp_ctx->builder, tbl_sz, "tbl_sz"))) { + if (!(tbl_sz = + LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, tbl_sz, "tbl_sz"))) { HANDLE_FAILURE("LLVMBuildLoad"); goto fail; } @@ -417,8 +428,8 @@ aot_compile_op_table_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, /* v */ POP_I32(param_values[3]); - if (!(ret = LLVMBuildCall(comp_ctx->builder, func, param_values, 4, - "table_grow"))) { + if (!(ret = LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, + 4, "table_grow"))) { HANDLE_FAILURE("LLVMBuildCall"); goto fail; } @@ -461,7 +472,8 @@ aot_compile_op_table_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, POP_I32(param_values[4]); /* "" means return void */ - if (!(LLVMBuildCall(comp_ctx->builder, func, param_values, 5, ""))) { + if (!(LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, 5, + ""))) { HANDLE_FAILURE("LLVMBuildCall"); goto fail; } @@ -471,4 +483,4 @@ fail: return false; } -#endif /* WASM_ENABLE_REF_TYPES != 0 */ \ No newline at end of file +#endif /* WASM_ENABLE_REF_TYPES != 0 */ diff --git a/core/iwasm/compilation/aot_emit_variable.c b/core/iwasm/compilation/aot_emit_variable.c index 7ac6645d3..4510a4c34 100644 --- a/core/iwasm/compilation/aot_emit_variable.c +++ b/core/iwasm/compilation/aot_emit_variable.c @@ -33,17 +33,20 @@ aot_compile_op_get_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, char name[32]; LLVMValueRef value; AOTValue *aot_value_top; + uint8 local_type; CHECK_LOCAL(local_idx); + local_type = get_local_type(func_ctx, local_idx); + snprintf(name, sizeof(name), "%s%d%s", "local", local_idx, "#"); - if (!(value = LLVMBuildLoad(comp_ctx->builder, func_ctx->locals[local_idx], - name))) { + if (!(value = LLVMBuildLoad2(comp_ctx->builder, TO_LLVM_TYPE(local_type), + func_ctx->locals[local_idx], name))) { aot_set_last_error("llvm build load fail"); return false; } - PUSH(value, get_local_type(func_ctx, local_idx)); + PUSH(value, local_type); aot_value_top = func_ctx->block_stack.block_list_end->value_stack.value_list_end; @@ -134,9 +137,9 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } offset = I32_CONST(global_offset); - if (!(global_ptr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "global_ptr_tmp"))) { + if (!(global_ptr = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->aot_inst, &offset, 1, + "global_ptr_tmp"))) { aot_set_last_error("llvm build in bounds gep failed."); return false; } @@ -172,7 +175,8 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (!is_set) { if (!(global = - LLVMBuildLoad(comp_ctx->builder, global_ptr, "global"))) { + LLVMBuildLoad2(comp_ctx->builder, TO_LLVM_TYPE(global_type), + global_ptr, "global"))) { aot_set_last_error("llvm build load failed."); return false; } diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index f4449afd3..12b34d583 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -232,9 +232,9 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* aot_inst->memories */ - if (!(shared_mem_addr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "shared_mem_addr_offset"))) { + if (!(shared_mem_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1, + "shared_mem_addr_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } @@ -245,8 +245,9 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } /* aot_inst->memories[0] */ - if (!(shared_mem_addr = LLVMBuildLoad( - comp_ctx->builder, shared_mem_addr, "shared_mem_addr"))) { + if (!(shared_mem_addr = + LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, + shared_mem_addr, "shared_mem_addr"))) { aot_set_last_error("llvm build load failed"); return false; } @@ -256,29 +257,34 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_set_last_error("llvm build bit cast failed"); return false; } - if (!(shared_mem_addr = LLVMBuildLoad( - comp_ctx->builder, shared_mem_addr, "shared_mem_addr"))) { + if (!(shared_mem_addr = + LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, + shared_mem_addr, "shared_mem_addr"))) { aot_set_last_error("llvm build load failed"); return false; } + /* memories[0]->memory_data */ offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data.ptr)); - if (!(func_ctx->mem_info[0].mem_base_addr = - LLVMBuildInBoundsGEP(comp_ctx->builder, shared_mem_addr, - &offset, 1, "mem_base_addr_offset"))) { + if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1, + "mem_base_addr_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } + /* memories[0]->cur_page_count */ offset = I32_CONST(offsetof(AOTMemoryInstance, cur_page_count)); if (!(func_ctx->mem_info[0].mem_cur_page_count_addr = - LLVMBuildInBoundsGEP(comp_ctx->builder, shared_mem_addr, - &offset, 1, "mem_cur_page_offset"))) { + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + shared_mem_addr, &offset, 1, + "mem_cur_page_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } + /* memories[0]->memory_data_size */ offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data_size)); - if (!(func_ctx->mem_info[0].mem_data_size_addr = - LLVMBuildInBoundsGEP(comp_ctx->builder, shared_mem_addr, - &offset, 1, "mem_data_size_offset"))) { + if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1, + "mem_data_size_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } @@ -288,25 +294,26 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, { offset = I32_CONST(offsetof(AOTModuleInstance, global_table_data) + offsetof(AOTMemoryInstance, memory_data.ptr)); - if (!(func_ctx->mem_info[0].mem_base_addr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "mem_base_addr_offset"))) { + if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1, + "mem_base_addr_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } offset = I32_CONST(offsetof(AOTModuleInstance, global_table_data) + offsetof(AOTMemoryInstance, cur_page_count)); if (!(func_ctx->mem_info[0].mem_cur_page_count_addr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "mem_cur_page_offset"))) { + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, + func_ctx->aot_inst, &offset, 1, + "mem_cur_page_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } offset = I32_CONST(offsetof(AOTModuleInstance, global_table_data) + offsetof(AOTMemoryInstance, memory_data_size)); - if (!(func_ctx->mem_info[0].mem_data_size_addr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "mem_data_size_offset"))) { + if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1, + "mem_data_size_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } @@ -333,22 +340,22 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } if (mem_space_unchanged) { - if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildLoad( - comp_ctx->builder, func_ctx->mem_info[0].mem_base_addr, - "mem_base_addr"))) { + if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildLoad2( + comp_ctx->builder, OPQ_PTR_TYPE, + func_ctx->mem_info[0].mem_base_addr, "mem_base_addr"))) { aot_set_last_error("llvm build load failed"); return false; } if (!(func_ctx->mem_info[0].mem_cur_page_count_addr = - LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_info[0].mem_cur_page_count_addr, - "mem_cur_page_count"))) { + LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, + func_ctx->mem_info[0].mem_cur_page_count_addr, + "mem_cur_page_count"))) { aot_set_last_error("llvm build load failed"); return false; } - if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildLoad( - comp_ctx->builder, func_ctx->mem_info[0].mem_data_size_addr, - "mem_data_size"))) { + if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildLoad2( + comp_ctx->builder, I32_TYPE, + func_ctx->mem_info[0].mem_data_size_addr, "mem_data_size"))) { aot_set_last_error("llvm build load failed"); return false; } @@ -357,9 +364,9 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, else if (is_shared_memory) { /* The base address for shared memory will never changed, we can load the value here */ - if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildLoad( - comp_ctx->builder, func_ctx->mem_info[0].mem_base_addr, - "mem_base_addr"))) { + if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildLoad2( + comp_ctx->builder, OPQ_PTR_TYPE, + func_ctx->mem_info[0].mem_base_addr, "mem_base_addr"))) { aot_set_last_error("llvm build load failed"); return false; } @@ -374,8 +381,8 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_1byte) - offsetof(AOTMemoryInstance, memory_data.ptr)); if (!(func_ctx->mem_info[0].mem_bound_check_1byte = - LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base, &offset, 1, - "bound_check_1byte_offset"))) { + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base, + &offset, 1, "bound_check_1byte_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } @@ -386,10 +393,12 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } if (mem_space_unchanged) { - if (!(func_ctx->mem_info[0].mem_bound_check_1byte = - LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_info[0].mem_bound_check_1byte, - "bound_check_1byte"))) { + if (!(func_ctx->mem_info[0].mem_bound_check_1byte = LLVMBuildLoad2( + comp_ctx->builder, + (comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE + : I32_TYPE, + func_ctx->mem_info[0].mem_bound_check_1byte, + "bound_check_1byte"))) { aot_set_last_error("llvm build load failed"); return false; } @@ -398,8 +407,8 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_2bytes) - offsetof(AOTMemoryInstance, memory_data.ptr)); if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = - LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base, &offset, 1, - "bound_check_2bytes_offset"))) { + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base, + &offset, 1, "bound_check_2bytes_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } @@ -410,10 +419,12 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } if (mem_space_unchanged) { - if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = - LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_info[0].mem_bound_check_2bytes, - "bound_check_2bytes"))) { + if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = LLVMBuildLoad2( + comp_ctx->builder, + (comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE + : I32_TYPE, + func_ctx->mem_info[0].mem_bound_check_2bytes, + "bound_check_2bytes"))) { aot_set_last_error("llvm build load failed"); return false; } @@ -422,8 +433,8 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_4bytes) - offsetof(AOTMemoryInstance, memory_data.ptr)); if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = - LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base, &offset, 1, - "bound_check_4bytes_offset"))) { + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base, + &offset, 1, "bound_check_4bytes_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } @@ -434,10 +445,12 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } if (mem_space_unchanged) { - if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = - LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_info[0].mem_bound_check_4bytes, - "bound_check_4bytes"))) { + if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = LLVMBuildLoad2( + comp_ctx->builder, + (comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE + : I32_TYPE, + func_ctx->mem_info[0].mem_bound_check_4bytes, + "bound_check_4bytes"))) { aot_set_last_error("llvm build load failed"); return false; } @@ -446,8 +459,8 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_8bytes) - offsetof(AOTMemoryInstance, memory_data.ptr)); if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = - LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base, &offset, 1, - "bound_check_8bytes_offset"))) { + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base, + &offset, 1, "bound_check_8bytes_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } @@ -458,10 +471,12 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } if (mem_space_unchanged) { - if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = - LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_info[0].mem_bound_check_8bytes, - "bound_check_8bytes"))) { + if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = LLVMBuildLoad2( + comp_ctx->builder, + (comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE + : I32_TYPE, + func_ctx->mem_info[0].mem_bound_check_8bytes, + "bound_check_8bytes"))) { aot_set_last_error("llvm build load failed"); return false; } @@ -469,9 +484,9 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_16bytes) - offsetof(AOTMemoryInstance, memory_data.ptr)); - if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = - LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base, &offset, 1, - "bound_check_16bytes_offset"))) { + if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = LLVMBuildInBoundsGEP2( + comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1, + "bound_check_16bytes_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } @@ -482,10 +497,12 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } if (mem_space_unchanged) { - if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = - LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_info[0].mem_bound_check_16bytes, - "bound_check_16bytes"))) { + if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = LLVMBuildLoad2( + comp_ctx->builder, + (comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE + : I32_TYPE, + func_ctx->mem_info[0].mem_bound_check_16bytes, + "bound_check_16bytes"))) { aot_set_last_error("llvm build load failed"); return false; } @@ -500,8 +517,9 @@ create_cur_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) LLVMValueRef offset; offset = I32_CONST(offsetof(AOTModuleInstance, cur_exception)); - func_ctx->cur_exception = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->aot_inst, &offset, 1, "cur_exception"); + func_ctx->cur_exception = + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, + &offset, 1, "cur_exception"); if (!func_ctx->cur_exception) { aot_set_last_error("llvm build in bounds gep failed."); return false; @@ -517,8 +535,8 @@ create_func_type_indexes(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) offset = I32_CONST(offsetof(AOTModuleInstance, func_type_indexes.ptr)); func_type_indexes_ptr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, &offset, 1, - "func_type_indexes_ptr"); + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, + &offset, 1, "func_type_indexes_ptr"); if (!func_type_indexes_ptr) { aot_set_last_error("llvm build add failed."); return false; @@ -537,8 +555,9 @@ create_func_type_indexes(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) return false; } - func_ctx->func_type_indexes = LLVMBuildLoad( - comp_ctx->builder, func_ctx->func_type_indexes, "func_type_indexes"); + func_ctx->func_type_indexes = + LLVMBuildLoad2(comp_ctx->builder, INT32_PTR_TYPE, + func_ctx->func_type_indexes, "func_type_indexes"); if (!func_ctx->func_type_indexes) { aot_set_last_error("llvm build load failed."); return false; @@ -552,8 +571,9 @@ create_func_ptrs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) LLVMValueRef offset; offset = I32_CONST(offsetof(AOTModuleInstance, func_ptrs)); - func_ctx->func_ptrs = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->aot_inst, &offset, 1, "func_ptrs_offset"); + func_ctx->func_ptrs = + LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, + &offset, 1, "func_ptrs_offset"); if (!func_ctx->func_ptrs) { aot_set_last_error("llvm build in bounds gep failed."); return false; @@ -566,8 +586,8 @@ create_func_ptrs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) return false; } - func_ctx->func_ptrs = - LLVMBuildLoad(comp_ctx->builder, func_ctx->func_ptrs, "func_ptrs_ptr"); + func_ctx->func_ptrs = LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, + func_ctx->func_ptrs, "func_ptrs_ptr"); if (!func_ctx->func_ptrs) { aot_set_last_error("llvm build load failed."); return false; @@ -648,24 +668,24 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx, /* Get aot inst address, the layout of exec_env is: exec_env->next, exec_env->prev, exec_env->module_inst, and argv_buf */ - if (!(aot_inst_addr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env, - &aot_inst_offset, 1, "aot_inst_addr"))) { + if (!(aot_inst_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->exec_env, + &aot_inst_offset, 1, "aot_inst_addr"))) { aot_set_last_error("llvm build in bounds gep failed"); goto fail; } /* Load aot inst */ - if (!(func_ctx->aot_inst = - LLVMBuildLoad(comp_ctx->builder, aot_inst_addr, "aot_inst"))) { + if (!(func_ctx->aot_inst = LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, + aot_inst_addr, "aot_inst"))) { aot_set_last_error("llvm build load failed"); goto fail; } /* Get argv buffer address */ - if (!(argv_buf_addr = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env, - &argv_buf_offset, 1, "argv_buf_addr"))) { + if (!(argv_buf_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->exec_env, + &argv_buf_offset, 1, "argv_buf_addr"))) { aot_set_last_error("llvm build in bounds gep failed"); goto fail; } @@ -682,30 +702,31 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx, goto fail; } - if (!(func_ctx->argv_buf = - LLVMBuildLoad(comp_ctx->builder, argv_buf_addr, "argv_buf"))) { + if (!(func_ctx->argv_buf = LLVMBuildLoad2(comp_ctx->builder, INT32_PTR_TYPE, + argv_buf_addr, "argv_buf"))) { aot_set_last_error("llvm build load failed"); goto fail; } /* Get native stack boundary address */ - if (!(stack_bound_addr = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->exec_env, &stack_bound_offset, 1, - "stack_bound_addr"))) { + if (!(stack_bound_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->exec_env, + &stack_bound_offset, 1, "stack_bound_addr"))) { aot_set_last_error("llvm build in bounds gep failed"); goto fail; } - if (!(func_ctx->native_stack_bound = LLVMBuildLoad( - comp_ctx->builder, stack_bound_addr, "native_stack_bound"))) { + if (!(func_ctx->native_stack_bound = + LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, stack_bound_addr, + "native_stack_bound"))) { aot_set_last_error("llvm build load failed"); goto fail; } /* Get aux stack boundary address */ - if (!(aux_stack_bound_addr = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->exec_env, &aux_stack_bound_offset, 1, - "aux_stack_bound_addr"))) { + if (!(aux_stack_bound_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->exec_env, + &aux_stack_bound_offset, 1, "aux_stack_bound_addr"))) { aot_set_last_error("llvm build in bounds gep failed"); goto fail; } @@ -717,16 +738,17 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx, goto fail; } - if (!(func_ctx->aux_stack_bound = LLVMBuildLoad( - comp_ctx->builder, aux_stack_bound_addr, "aux_stack_bound"))) { + if (!(func_ctx->aux_stack_bound = + LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, aux_stack_bound_addr, + "aux_stack_bound"))) { aot_set_last_error("llvm build load failed"); goto fail; } /* Get aux stack bottom address */ - if (!(aux_stack_bottom_addr = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->exec_env, &aux_stack_bottom_offset, - 1, "aux_stack_bottom_addr"))) { + if (!(aux_stack_bottom_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->exec_env, + &aux_stack_bottom_offset, 1, "aux_stack_bottom_addr"))) { aot_set_last_error("llvm build in bounds gep failed"); goto fail; } @@ -737,21 +759,23 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx, aot_set_last_error("llvm build bit cast failed"); goto fail; } - if (!(func_ctx->aux_stack_bottom = LLVMBuildLoad( - comp_ctx->builder, aux_stack_bottom_addr, "aux_stack_bottom"))) { + if (!(func_ctx->aux_stack_bottom = + LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, aux_stack_bottom_addr, + "aux_stack_bottom"))) { aot_set_last_error("llvm build load failed"); goto fail; } - if (!(native_symbol_addr = LLVMBuildInBoundsGEP( - comp_ctx->builder, func_ctx->exec_env, &native_symbol_offset, 1, - "native_symbol_addr"))) { + if (!(native_symbol_addr = LLVMBuildInBoundsGEP2( + comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->exec_env, + &native_symbol_offset, 1, "native_symbol_addr"))) { aot_set_last_error("llvm build in bounds gep failed"); goto fail; } - if (!(func_ctx->native_symbol = LLVMBuildLoad( - comp_ctx->builder, native_symbol_addr, "native_symbol_tmp"))) { + if (!(func_ctx->native_symbol = + LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, + native_symbol_addr, "native_symbol_tmp"))) { aot_set_last_error("llvm build bit cast failed"); goto fail; } @@ -2581,9 +2605,14 @@ __call_llvm_intrinsic(const AOTCompContext *comp_ctx, } } +#if LLVM_VERSION_MAJOR >= 14 + func_type = + LLVMFunctionType(ret_type, param_types, (uint32)param_count, false); +#endif + /* Call the LLVM intrinsic function */ - if (!(ret = LLVMBuildCall(comp_ctx->builder, func, param_values, - (uint32)param_count, "call"))) { + if (!(ret = LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, + (uint32)param_count, "call"))) { aot_set_last_error("llvm build intrinsic call failed."); return NULL; } @@ -2666,13 +2695,15 @@ aot_get_func_from_table(const AOTCompContext *comp_ctx, LLVMValueRef base, goto fail; } - if (!(func_addr = LLVMBuildInBoundsGEP(comp_ctx->builder, base, &func_addr, - 1, "func_addr"))) { + if (!(func_addr = + LLVMBuildInBoundsGEP2(comp_ctx->builder, OPQ_PTR_TYPE, base, + &func_addr, 1, "func_addr"))) { aot_set_last_error("get function addr by index failed."); goto fail; } - func = LLVMBuildLoad(comp_ctx->builder, func_addr, "func_tmp"); + func = + LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, func_addr, "func_tmp"); if (func == NULL) { aot_set_last_error("get function pointer failed."); @@ -2695,7 +2726,7 @@ aot_load_const_from_table(AOTCompContext *comp_ctx, LLVMValueRef base, const WASMValue *value, uint8 value_type) { LLVMValueRef const_index, const_addr, const_value; - LLVMTypeRef const_ptr_type; + LLVMTypeRef const_ptr_type, const_type; char buf[128] = { 0 }; int32 index; @@ -2704,11 +2735,13 @@ aot_load_const_from_table(AOTCompContext *comp_ctx, LLVMValueRef base, /* Store the raw int bits of f32 const as a hex string */ snprintf(buf, sizeof(buf), "f32#%08" PRIX32, value->i32); const_ptr_type = F32_PTR_TYPE; + const_type = F32_TYPE; break; case VALUE_TYPE_F64: /* Store the raw int bits of f64 const as a hex string */ snprintf(buf, sizeof(buf), "f64#%016" PRIX64, value->i64); const_ptr_type = F64_PTR_TYPE; + const_type = F64_TYPE; break; default: bh_assert(0); @@ -2727,8 +2760,9 @@ aot_load_const_from_table(AOTCompContext *comp_ctx, LLVMValueRef base, return NULL; } - if (!(const_addr = LLVMBuildInBoundsGEP( - comp_ctx->builder, base, &const_index, 1, "const_addr_tmp"))) { + if (!(const_addr = + LLVMBuildInBoundsGEP2(comp_ctx->builder, OPQ_PTR_TYPE, base, + &const_index, 1, "const_addr_tmp"))) { aot_set_last_error("get const addr by index failed."); return NULL; } @@ -2739,11 +2773,12 @@ aot_load_const_from_table(AOTCompContext *comp_ctx, LLVMValueRef base, return NULL; } - if (!(const_value = - LLVMBuildLoad(comp_ctx->builder, const_addr, "const_value"))) { + if (!(const_value = LLVMBuildLoad2(comp_ctx->builder, const_type, + const_addr, "const_value"))) { aot_set_last_error("load const failed."); return NULL; } + (void)const_type; return const_value; } diff --git a/core/iwasm/compilation/aot_llvm.h b/core/iwasm/compilation/aot_llvm.h index 3e321f45d..28967cc78 100644 --- a/core/iwasm/compilation/aot_llvm.h +++ b/core/iwasm/compilation/aot_llvm.h @@ -38,6 +38,20 @@ extern "C" { #endif +#if LLVM_VERSION_MAJOR < 14 +#define LLVMBuildLoad2(builder, type, value, name) \ + LLVMBuildLoad(builder, value, name) + +#define LLVMBuildCall2(builder, type, func, args, num_args, name) \ + LLVMBuildCall(builder, func, args, num_args, name) + +#define LLVMBuildInBoundsGEP2(builder, type, ptr, indices, num_indices, name) \ + LLVMBuildInBoundsGEP(builder, ptr, indices, num_indices, name) +#else +/* Opaque pointer type */ +#define OPQ_PTR_TYPE INT8_PTR_TYPE +#endif + /** * Value in the WASM operation stack, each stack element * is an LLVM value diff --git a/core/iwasm/compilation/aot_llvm_extra.cpp b/core/iwasm/compilation/aot_llvm_extra.cpp index b25852cf4..5cc2019ae 100644 --- a/core/iwasm/compilation/aot_llvm_extra.cpp +++ b/core/iwasm/compilation/aot_llvm_extra.cpp @@ -492,7 +492,11 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx) if (!disable_llvm_lto) { /* Apply LTO for AOT mode */ +#if LLVM_VERSION_MAJOR < 14 MPM.addPass(PB.buildLTODefaultPipeline(OL, NULL)); +#else + MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(OL)); +#endif } else { MPM.addPass(PB.buildPerModuleDefaultPipeline(OL)); diff --git a/core/iwasm/compilation/simd/simd_load_store.c b/core/iwasm/compilation/simd/simd_load_store.c index 9d084efd7..d166e954c 100644 --- a/core/iwasm/compilation/simd/simd_load_store.c +++ b/core/iwasm/compilation/simd/simd_load_store.c @@ -13,7 +13,8 @@ /* data_length in bytes */ static LLVMValueRef simd_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align, - uint32 offset, uint32 data_length, LLVMTypeRef ptr_type) + uint32 offset, uint32 data_length, LLVMTypeRef ptr_type, + LLVMTypeRef data_type) { LLVMValueRef maddr, data; @@ -29,7 +30,7 @@ simd_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align, return NULL; } - if (!(data = LLVMBuildLoad(comp_ctx->builder, maddr, "data"))) { + if (!(data = LLVMBuildLoad2(comp_ctx->builder, data_type, maddr, "data"))) { HANDLE_FAILURE("LLVMBuildLoad"); return NULL; } @@ -46,7 +47,7 @@ aot_compile_simd_v128_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMValueRef result; if (!(result = simd_load(comp_ctx, func_ctx, align, offset, 16, - V128_PTR_TYPE))) { + V128_PTR_TYPE, V128_TYPE))) { return false; } @@ -73,7 +74,7 @@ aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMVectorType(INT16_TYPE, 4), LLVMVectorType(INT16_TYPE, 4), LLVMVectorType(I32_TYPE, 2), LLVMVectorType(I32_TYPE, 2), }; - LLVMTypeRef sub_vector_type; + LLVMTypeRef sub_vector_type, sub_vector_ptr_type; bh_assert(opcode_index < 6); @@ -81,13 +82,13 @@ aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, /* to vector ptr type */ if (!sub_vector_type - || !(sub_vector_type = LLVMPointerType(sub_vector_type, 0))) { + || !(sub_vector_ptr_type = LLVMPointerType(sub_vector_type, 0))) { HANDLE_FAILURE("LLVMPointerType"); return false; } if (!(sub_vector = simd_load(comp_ctx, func_ctx, align, offset, 8, - sub_vector_type))) { + sub_vector_ptr_type, sub_vector_type))) { return false; } @@ -117,6 +118,8 @@ aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMValueRef element, result; LLVMTypeRef element_ptr_types[] = { INT8_PTR_TYPE, INT16_PTR_TYPE, INT32_PTR_TYPE, INT64_PTR_TYPE }; + LLVMTypeRef element_data_types[] = { INT8_TYPE, INT16_TYPE, I32_TYPE, + I64_TYPE }; uint32 data_lengths[] = { 1, 2, 4, 8 }; LLVMValueRef undefs[] = { LLVM_CONST(i8x16_undef), @@ -135,7 +138,8 @@ aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (!(element = simd_load(comp_ctx, func_ctx, align, offset, data_lengths[opcode_index], - element_ptr_types[opcode_index]))) { + element_ptr_types[opcode_index], + element_data_types[opcode_index]))) { return false; } @@ -166,6 +170,8 @@ aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 data_lengths[] = { 1, 2, 4, 8 }; LLVMTypeRef element_ptr_types[] = { INT8_PTR_TYPE, INT16_PTR_TYPE, INT32_PTR_TYPE, INT64_PTR_TYPE }; + LLVMTypeRef element_data_types[] = { INT8_TYPE, INT16_TYPE, I32_TYPE, + I64_TYPE }; LLVMTypeRef vector_types[] = { V128_i8x16_TYPE, V128_i16x8_TYPE, V128_i32x4_TYPE, V128_i64x2_TYPE }; LLVMValueRef lane = simd_lane_id_to_llvm_value(comp_ctx, lane_id); @@ -179,7 +185,8 @@ aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (!(element = simd_load(comp_ctx, func_ctx, align, offset, data_lengths[opcode_index], - element_ptr_types[opcode_index]))) { + element_ptr_types[opcode_index], + element_data_types[opcode_index]))) { return false; } @@ -200,6 +207,7 @@ aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 opcode_index = opcode - SIMD_v128_load32_zero; uint32 data_lengths[] = { 4, 8 }; LLVMTypeRef element_ptr_types[] = { INT32_PTR_TYPE, INT64_PTR_TYPE }; + LLVMTypeRef element_data_types[] = { I32_TYPE, I64_TYPE }; LLVMValueRef zero[] = { LLVM_CONST(i32x4_vec_zero), LLVM_CONST(i64x2_vec_zero), @@ -219,7 +227,8 @@ aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (!(element = simd_load(comp_ctx, func_ctx, align, offset, data_lengths[opcode_index], - element_ptr_types[opcode_index]))) { + element_ptr_types[opcode_index], + element_data_types[opcode_index]))) { return false; } From 625d59191d20906a1ff9fba89b0fd7d987172178 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 28 Jun 2022 16:05:16 +0800 Subject: [PATCH 6/6] Update spec cases to latest version (#1253) Update spec cases of mvp/threads to latest version, update wabt to 1.0.29. And enhance the wasm loader. --- core/iwasm/interpreter/wasm_loader.c | 20 ++++++- core/iwasm/interpreter/wasm_runtime.c | 4 +- .../spec-test-script/ignore_cases.patch | 59 ++++++++++--------- tests/wamr-test-suites/test_wamr.sh | 20 +++---- 4 files changed, 60 insertions(+), 43 deletions(-) diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index bc3cf1a89..82f4a3036 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -2171,6 +2171,15 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, export = module->exports; for (i = 0; i < export_count; i++, export ++) { +#if WASM_ENABLE_THREAD_MGR == 0 + if (p == p_end) { + /* export section with inconsistent count: + n export declared, but less than n given */ + set_error_buf(error_buf, error_buf_size, + "length out of bounds"); + return false; + } +#endif read_leb_uint32(p, p_end, str_len); CHECK_BUF(p, p_end, str_len); @@ -9319,8 +9328,15 @@ re_scan: } if (loader_ctx->csp_num > 0) { - set_error_buf(error_buf, error_buf_size, - "function body must end with END opcode"); + if (cur_func_idx < module->function_count - 1) + /* Function with missing end marker (between two functions) */ + set_error_buf(error_buf, error_buf_size, "END opcode expected"); + else + /* Function with missing end marker + (at EOF or end of code sections) */ + set_error_buf(error_buf, error_buf_size, + "unexpected end of section or function, " + "or section size mismatch"); goto fail; } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index deba92dca..568b9db1d 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1491,8 +1491,8 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size, if (stack_size == 0) stack_size = DEFAULT_WASM_STACK_SIZE; #if WASM_ENABLE_SPEC_TEST != 0 - if (stack_size < 48 * 1024) - stack_size = 48 * 1024; + if (stack_size < 128 * 1024) + stack_size = 128 * 1024; #endif module_inst->default_wasm_stack_size = stack_size; diff --git a/tests/wamr-test-suites/spec-test-script/ignore_cases.patch b/tests/wamr-test-suites/spec-test-script/ignore_cases.patch index 70256dfed..1d94d91af 100644 --- a/tests/wamr-test-suites/spec-test-script/ignore_cases.patch +++ b/tests/wamr-test-suites/spec-test-script/ignore_cases.patch @@ -1,8 +1,8 @@ diff --git a/test/core/binary.wast b/test/core/binary.wast -index c6f9755..a479212 100644 +index 891aad3..07356a3 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast -@@ -161,7 +161,7 @@ +@@ -206,7 +206,7 @@ ) ;; Type section with signed LEB128 encoded type @@ -11,7 +11,7 @@ index c6f9755..a479212 100644 (module binary "\00asm" "\01\00\00\00" "\01" ;; Type section id -@@ -171,7 +171,7 @@ +@@ -216,7 +216,7 @@ "\00\00" ) "integer representation too long" @@ -20,7 +20,7 @@ index c6f9755..a479212 100644 ;; Unsigned LEB128 must not be overlong (assert_malformed -@@ -1582,7 +1582,7 @@ +@@ -1683,7 +1683,7 @@ ) ;; 2 elem segment declared, 1 given @@ -29,7 +29,7 @@ index c6f9755..a479212 100644 (module binary "\00asm" "\01\00\00\00" "\01\04\01" ;; type section -@@ -1595,7 +1595,7 @@ +@@ -1696,7 +1696,7 @@ ;; "\00\41\00\0b\01\00" ;; elem 1 (missed) ) "unexpected end" @@ -38,6 +38,24 @@ index c6f9755..a479212 100644 ;; 2 elem segment declared, 1.5 given (assert_malformed +@@ -1813,7 +1813,7 @@ + ) + + ;; 1 br_table target declared, 2 given +-(assert_malformed ++(;assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\01\04\01" ;; type section +@@ -1832,7 +1832,7 @@ + "\0b\0b\0b" ;; end + ) + "unexpected end" +-) ++;) + + ;; Start section + (module binary diff --git a/test/core/data.wast b/test/core/data.wast index 4f339be..0b5b3e6 100644 --- a/test/core/data.wast @@ -93,26 +111,10 @@ index 4f339be..0b5b3e6 100644 ;; Invalid offsets diff --git a/test/core/elem.wast b/test/core/elem.wast -index 575ecef..204b748 100644 +index 575ecef..6eecab9 100644 --- a/test/core/elem.wast +++ b/test/core/elem.wast -@@ -467,6 +467,7 @@ - "type mismatch" - ) - -+(; not supported by wat2wasm - (assert_invalid - (module - (table 1 funcref) -@@ -507,6 +508,7 @@ - ) - "constant expression required" - ) -+;) - - ;; Two elements target the same slot - -@@ -571,9 +573,11 @@ +@@ -571,9 +571,11 @@ (func $const-i32-d (type $out-i32) (i32.const 68)) ) @@ -124,7 +126,7 @@ index 575ecef..204b748 100644 (module $module3 (type $out-i32 (func (result i32))) -@@ -584,6 +588,8 @@ +@@ -584,6 +586,8 @@ (func $const-i32-f (type $out-i32) (i32.const 70)) ) @@ -785,7 +787,7 @@ index 0b2d26f..bdab6a0 100644 (table $t1 30 30 funcref) (elem (table $t1) (i32.const 2) func 3 1 4 1) diff --git a/test/core/unreached-valid.wast b/test/core/unreached-valid.wast -index 0025217..07d2788 100644 +index b7ebabf..4f2abfb 100644 --- a/test/core/unreached-valid.wast +++ b/test/core/unreached-valid.wast @@ -46,6 +46,7 @@ @@ -796,9 +798,8 @@ index 0025217..07d2788 100644 (module (func (export "meet-bottom") (block (result f64) -@@ -59,4 +60,5 @@ - (drop) - ) +@@ -61,3 +62,4 @@ ) -+;) + (assert_trap (invoke "meet-bottom") "unreachable") ++;) diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index ea66ee353..0cb26e730 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -275,12 +275,12 @@ function spec_test() # update basic test cases echo "update spec test cases" - git fetch origin master + git fetch origin main # restore from XX_ignore_cases.patch # resotre branch - git checkout -B master - # [spec] Fix instruction table (#1402) Thu Dec 2 17:21:54 2021 +0100 - git reset --hard 2460ad02b51fb5ed5824f44de287a8638b19a5f8 + git checkout -B main + # [spec] Update note on module initialization trapping (#1493) + git reset --hard 044d0d2e77bdcbe891f7e0b9dd2ac01d56435f0b git apply ../../spec-test-script/ignore_cases.patch if [[ ${ENABLE_SIMD} == 1 ]]; then git apply ../../spec-test-script/simd_ignore_cases.patch @@ -295,8 +295,8 @@ function spec_test() # fetch spec for threads proposal git fetch threads - # [interpreter] Threading (#179) Fri Aug 6 18:02:59 2021 +0200 - git reset --hard 0d115b494d640eb0c1c352941fd14ca0bad926d3 + # Fix error in Web embedding desc for atomic.notify (#185) + git reset --hard 85b562cd6805947876ec5e8b975ab0127c55a0a2 git checkout threads/main git apply ../../spec-test-script/thread_proposal_ignore_cases.patch @@ -321,16 +321,16 @@ function spec_test() exit 1 ;; esac - if [ ! -f /tmp/wabt-1.0.24-${WABT_PLATFORM}.tar.gz ]; then + if [ ! -f /tmp/wabt-1.0.29-${WABT_PLATFORM}.tar.gz ]; then wget \ - https://github.com/WebAssembly/wabt/releases/download/1.0.24/wabt-1.0.24-${WABT_PLATFORM}.tar.gz \ + https://github.com/WebAssembly/wabt/releases/download/1.0.29/wabt-1.0.29-${WABT_PLATFORM}.tar.gz \ -P /tmp fi cd /tmp \ - && tar zxf wabt-1.0.24-${WABT_PLATFORM}.tar.gz \ + && tar zxf wabt-1.0.29-${WABT_PLATFORM}.tar.gz \ && mkdir -p ${WORK_DIR}/wabt/out/gcc/Release/ \ - && install wabt-1.0.24/bin/wa* ${WORK_DIR}/wabt/out/gcc/Release/ \ + && install wabt-1.0.29/bin/wa* ${WORK_DIR}/wabt/out/gcc/Release/ \ && cd - fi else