mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-09 13:16:26 +00:00
Avoid generating some unused LLVM IRs (#1696)
Refine the generated LLVM IRs at the beginning of each LLVM AOT/JIT function to fasten the LLVM IR optimization: - Only create argv_buf if there are func calls in this function - Only create native stack bound if stack bound check is enabled - Only create aux stack info if there is opcode set_global_aux_stack - Only create native symbol if indirect_mode is enabled - Only create memory info if there are memory operations - Only create func_type_indexes if there is opcode call_indirect
This commit is contained in:
parent
4b0660cf24
commit
c70e1ebc3d
|
@ -219,6 +219,234 @@ fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
create_argv_buf(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||||
|
{
|
||||||
|
LLVMValueRef argv_buf_offset = I32_THREE, argv_buf_addr;
|
||||||
|
LLVMTypeRef int32_ptr_type;
|
||||||
|
|
||||||
|
/* Get argv buffer address */
|
||||||
|
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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(int32_ptr_type = LLVMPointerType(INT32_PTR_TYPE, 0))) {
|
||||||
|
aot_set_last_error("llvm add pointer type failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert to int32 pointer type */
|
||||||
|
if (!(argv_buf_addr = LLVMBuildBitCast(comp_ctx->builder, argv_buf_addr,
|
||||||
|
int32_ptr_type, "argv_buf_ptr"))) {
|
||||||
|
aot_set_last_error("llvm build load failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
create_native_stack_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||||
|
{
|
||||||
|
LLVMValueRef stack_bound_offset = I32_FOUR, 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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
create_aux_stack_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||||
|
{
|
||||||
|
LLVMValueRef aux_stack_bound_offset = I32_SIX, aux_stack_bound_addr;
|
||||||
|
LLVMValueRef aux_stack_bottom_offset = I32_SEVEN, aux_stack_bottom_addr;
|
||||||
|
|
||||||
|
/* Get aux stack boundary address */
|
||||||
|
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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(aux_stack_bound_addr =
|
||||||
|
LLVMBuildBitCast(comp_ctx->builder, aux_stack_bound_addr,
|
||||||
|
INT32_PTR_TYPE, "aux_stack_bound_ptr"))) {
|
||||||
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get aux stack bottom address */
|
||||||
|
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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(aux_stack_bottom_addr =
|
||||||
|
LLVMBuildBitCast(comp_ctx->builder, aux_stack_bottom_addr,
|
||||||
|
INT32_PTR_TYPE, "aux_stack_bottom_ptr"))) {
|
||||||
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
create_native_symbol(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||||
|
{
|
||||||
|
LLVMValueRef native_symbol_offset = I32_EIGHT, 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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(func_ctx->native_symbol =
|
||||||
|
LLVMBuildBitCast(comp_ctx->builder, func_ctx->native_symbol,
|
||||||
|
comp_ctx->exec_env_type, "native_symbol"))) {
|
||||||
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
create_local_variables(AOTCompData *comp_data, AOTCompContext *comp_ctx,
|
||||||
|
AOTFuncContext *func_ctx, AOTFunc *func)
|
||||||
|
{
|
||||||
|
AOTFuncType *aot_func_type = comp_data->func_types[func->func_type_index];
|
||||||
|
char local_name[32];
|
||||||
|
uint32 i, j = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < aot_func_type->param_count; i++, j++) {
|
||||||
|
snprintf(local_name, sizeof(local_name), "l%d", i);
|
||||||
|
func_ctx->locals[i] =
|
||||||
|
LLVMBuildAlloca(comp_ctx->builder,
|
||||||
|
TO_LLVM_TYPE(aot_func_type->types[i]), local_name);
|
||||||
|
if (!func_ctx->locals[i]) {
|
||||||
|
aot_set_last_error("llvm build alloca failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!LLVMBuildStore(comp_ctx->builder, LLVMGetParam(func_ctx->func, j),
|
||||||
|
func_ctx->locals[i])) {
|
||||||
|
aot_set_last_error("llvm build store failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < func->local_count; i++) {
|
||||||
|
LLVMTypeRef local_type;
|
||||||
|
LLVMValueRef local_value = NULL;
|
||||||
|
snprintf(local_name, sizeof(local_name), "l%d",
|
||||||
|
aot_func_type->param_count + i);
|
||||||
|
local_type = TO_LLVM_TYPE(func->local_types[i]);
|
||||||
|
func_ctx->locals[aot_func_type->param_count + i] =
|
||||||
|
LLVMBuildAlloca(comp_ctx->builder, local_type, local_name);
|
||||||
|
if (!func_ctx->locals[aot_func_type->param_count + i]) {
|
||||||
|
aot_set_last_error("llvm build alloca failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch (func->local_types[i]) {
|
||||||
|
case VALUE_TYPE_I32:
|
||||||
|
local_value = I32_ZERO;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_I64:
|
||||||
|
local_value = I64_ZERO;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_F32:
|
||||||
|
local_value = F32_ZERO;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_F64:
|
||||||
|
local_value = F64_ZERO;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_V128:
|
||||||
|
local_value = V128_i64x2_ZERO;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_FUNCREF:
|
||||||
|
case VALUE_TYPE_EXTERNREF:
|
||||||
|
local_value = REF_NULL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bh_assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!LLVMBuildStore(comp_ctx->builder, local_value,
|
||||||
|
func_ctx->locals[aot_func_type->param_count + i])) {
|
||||||
|
aot_set_last_error("llvm build store failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comp_ctx->enable_stack_bound_check) {
|
||||||
|
if (aot_func_type->param_count + func->local_count > 0) {
|
||||||
|
func_ctx->last_alloca = func_ctx->locals[aot_func_type->param_count
|
||||||
|
+ func->local_count - 1];
|
||||||
|
if (!(func_ctx->last_alloca =
|
||||||
|
LLVMBuildBitCast(comp_ctx->builder, func_ctx->last_alloca,
|
||||||
|
INT8_PTR_TYPE, "stack_ptr"))) {
|
||||||
|
aot_set_last_error("llvm build bit cast failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!(func_ctx->last_alloca = LLVMBuildAlloca(
|
||||||
|
comp_ctx->builder, INT8_TYPE, "stack_ptr"))) {
|
||||||
|
aot_set_last_error("llvm build alloca failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
LLVMTypeRef int8_ptr_type, uint32 func_index)
|
LLVMTypeRef int8_ptr_type, uint32 func_index)
|
||||||
|
@ -653,17 +881,12 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
|
||||||
{
|
{
|
||||||
AOTFuncContext *func_ctx;
|
AOTFuncContext *func_ctx;
|
||||||
AOTFuncType *aot_func_type = comp_data->func_types[func->func_type_index];
|
AOTFuncType *aot_func_type = comp_data->func_types[func->func_type_index];
|
||||||
|
WASMModule *module = comp_ctx->comp_data->wasm_module;
|
||||||
|
WASMFunction *wasm_func = module->functions[func_index];
|
||||||
AOTBlock *aot_block;
|
AOTBlock *aot_block;
|
||||||
LLVMTypeRef int8_ptr_type, int32_ptr_type;
|
LLVMTypeRef int8_ptr_type;
|
||||||
LLVMValueRef aot_inst_offset = I32_TWO, aot_inst_addr;
|
LLVMValueRef aot_inst_offset = I32_TWO, aot_inst_addr;
|
||||||
LLVMValueRef argv_buf_offset = I32_THREE, argv_buf_addr;
|
|
||||||
LLVMValueRef stack_bound_offset = I32_FOUR, stack_bound_addr;
|
|
||||||
LLVMValueRef aux_stack_bound_offset = I32_SIX, aux_stack_bound_addr;
|
|
||||||
LLVMValueRef aux_stack_bottom_offset = I32_SEVEN, aux_stack_bottom_addr;
|
|
||||||
LLVMValueRef native_symbol_offset = I32_EIGHT, native_symbol_addr;
|
|
||||||
char local_name[32];
|
|
||||||
uint64 size;
|
uint64 size;
|
||||||
uint32 i, j = 0;
|
|
||||||
|
|
||||||
/* Allocate memory for the function context */
|
/* Allocate memory for the function context */
|
||||||
size = offsetof(AOTFuncContext, locals)
|
size = offsetof(AOTFuncContext, locals)
|
||||||
|
@ -682,13 +905,15 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
|
||||||
/* Add LLVM function */
|
/* Add LLVM function */
|
||||||
if (!(func_ctx->func =
|
if (!(func_ctx->func =
|
||||||
aot_add_llvm_func(comp_ctx, func_ctx->module, aot_func_type,
|
aot_add_llvm_func(comp_ctx, func_ctx->module, aot_func_type,
|
||||||
func_index, &func_ctx->func_type)))
|
func_index, &func_ctx->func_type))) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create function's first AOTBlock */
|
/* Create function's first AOTBlock */
|
||||||
if (!(aot_block =
|
if (!(aot_block =
|
||||||
aot_create_func_block(comp_ctx, func_ctx, func, aot_func_type)))
|
aot_create_func_block(comp_ctx, func_ctx, func, aot_func_type))) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_DEBUG_AOT != 0
|
#if WASM_ENABLE_DEBUG_AOT != 0
|
||||||
func_ctx->debug_func = dwarf_gen_func_info(comp_ctx, func_ctx);
|
func_ctx->debug_func = dwarf_gen_func_info(comp_ctx, func_ctx);
|
||||||
|
@ -700,7 +925,7 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
|
||||||
LLVMPositionBuilderAtEnd(comp_ctx->builder, aot_block->llvm_entry_block);
|
LLVMPositionBuilderAtEnd(comp_ctx->builder, aot_block->llvm_entry_block);
|
||||||
|
|
||||||
/* Save the pameters for fast access */
|
/* Save the pameters for fast access */
|
||||||
func_ctx->exec_env = LLVMGetParam(func_ctx->func, j++);
|
func_ctx->exec_env = LLVMGetParam(func_ctx->func, 0);
|
||||||
|
|
||||||
/* Get aot inst address, the layout of exec_env is:
|
/* Get aot inst address, the layout of exec_env is:
|
||||||
exec_env->next, exec_env->prev, exec_env->module_inst, and argv_buf */
|
exec_env->next, exec_env->prev, exec_env->module_inst, and argv_buf */
|
||||||
|
@ -719,208 +944,59 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get argv buffer address */
|
/* Get argv buffer address */
|
||||||
if (!(argv_buf_addr = LLVMBuildInBoundsGEP2(
|
if (wasm_func->has_op_func_call && !create_argv_buf(comp_ctx, func_ctx)) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(int32_ptr_type = LLVMPointerType(INT32_PTR_TYPE, 0))) {
|
|
||||||
aot_set_last_error("llvm add pointer type failed");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert to int32 pointer type */
|
|
||||||
if (!(argv_buf_addr = LLVMBuildBitCast(comp_ctx->builder, argv_buf_addr,
|
|
||||||
int32_ptr_type, "argv_buf_ptr"))) {
|
|
||||||
aot_set_last_error("llvm build load failed");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get native stack boundary address */
|
/* Get native stack boundary address */
|
||||||
if (!(stack_bound_addr = LLVMBuildInBoundsGEP2(
|
if (comp_ctx->enable_stack_bound_check
|
||||||
comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->exec_env,
|
&& !create_native_stack_bound(comp_ctx, func_ctx)) {
|
||||||
&stack_bound_offset, 1, "stack_bound_addr"))) {
|
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(func_ctx->native_stack_bound =
|
/* Get auxiliary stack info */
|
||||||
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE, stack_bound_addr,
|
if (wasm_func->has_op_set_global_aux_stack
|
||||||
"native_stack_bound"))) {
|
&& !create_aux_stack_info(comp_ctx, func_ctx)) {
|
||||||
aot_set_last_error("llvm build load failed");
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get aux stack boundary address */
|
/* Get native symbol list */
|
||||||
if (!(aux_stack_bound_addr = LLVMBuildInBoundsGEP2(
|
if (comp_ctx->is_indirect_mode
|
||||||
comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->exec_env,
|
&& !create_native_symbol(comp_ctx, func_ctx)) {
|
||||||
&aux_stack_bound_offset, 1, "aux_stack_bound_addr"))) {
|
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(aux_stack_bound_addr =
|
/* Create local variables */
|
||||||
LLVMBuildBitCast(comp_ctx->builder, aux_stack_bound_addr,
|
if (!create_local_variables(comp_data, comp_ctx, func_ctx, func)) {
|
||||||
INT32_PTR_TYPE, "aux_stack_bound_ptr"))) {
|
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(aux_stack_bottom_addr =
|
|
||||||
LLVMBuildBitCast(comp_ctx->builder, aux_stack_bottom_addr,
|
|
||||||
INT32_PTR_TYPE, "aux_stack_bottom_ptr"))) {
|
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
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 = 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 =
|
|
||||||
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE,
|
|
||||||
native_symbol_addr, "native_symbol_tmp"))) {
|
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(func_ctx->native_symbol =
|
|
||||||
LLVMBuildBitCast(comp_ctx->builder, func_ctx->native_symbol,
|
|
||||||
comp_ctx->exec_env_type, "native_symbol"))) {
|
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < aot_func_type->param_count; i++, j++) {
|
|
||||||
snprintf(local_name, sizeof(local_name), "l%d", i);
|
|
||||||
func_ctx->locals[i] =
|
|
||||||
LLVMBuildAlloca(comp_ctx->builder,
|
|
||||||
TO_LLVM_TYPE(aot_func_type->types[i]), local_name);
|
|
||||||
if (!func_ctx->locals[i]) {
|
|
||||||
aot_set_last_error("llvm build alloca failed.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (!LLVMBuildStore(comp_ctx->builder, LLVMGetParam(func_ctx->func, j),
|
|
||||||
func_ctx->locals[i])) {
|
|
||||||
aot_set_last_error("llvm build store failed.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < func->local_count; i++) {
|
|
||||||
LLVMTypeRef local_type;
|
|
||||||
LLVMValueRef local_value = NULL;
|
|
||||||
snprintf(local_name, sizeof(local_name), "l%d",
|
|
||||||
aot_func_type->param_count + i);
|
|
||||||
local_type = TO_LLVM_TYPE(func->local_types[i]);
|
|
||||||
func_ctx->locals[aot_func_type->param_count + i] =
|
|
||||||
LLVMBuildAlloca(comp_ctx->builder, local_type, local_name);
|
|
||||||
if (!func_ctx->locals[aot_func_type->param_count + i]) {
|
|
||||||
aot_set_last_error("llvm build alloca failed.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
switch (func->local_types[i]) {
|
|
||||||
case VALUE_TYPE_I32:
|
|
||||||
local_value = I32_ZERO;
|
|
||||||
break;
|
|
||||||
case VALUE_TYPE_I64:
|
|
||||||
local_value = I64_ZERO;
|
|
||||||
break;
|
|
||||||
case VALUE_TYPE_F32:
|
|
||||||
local_value = F32_ZERO;
|
|
||||||
break;
|
|
||||||
case VALUE_TYPE_F64:
|
|
||||||
local_value = F64_ZERO;
|
|
||||||
break;
|
|
||||||
case VALUE_TYPE_V128:
|
|
||||||
local_value = V128_i64x2_ZERO;
|
|
||||||
break;
|
|
||||||
case VALUE_TYPE_FUNCREF:
|
|
||||||
case VALUE_TYPE_EXTERNREF:
|
|
||||||
local_value = REF_NULL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
bh_assert(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!LLVMBuildStore(comp_ctx->builder, local_value,
|
|
||||||
func_ctx->locals[aot_func_type->param_count + i])) {
|
|
||||||
aot_set_last_error("llvm build store failed.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aot_func_type->param_count + func->local_count > 0) {
|
|
||||||
func_ctx->last_alloca =
|
|
||||||
func_ctx
|
|
||||||
->locals[aot_func_type->param_count + func->local_count - 1];
|
|
||||||
if (!(func_ctx->last_alloca =
|
|
||||||
LLVMBuildBitCast(comp_ctx->builder, func_ctx->last_alloca,
|
|
||||||
INT8_PTR_TYPE, "stack_ptr"))) {
|
|
||||||
aot_set_last_error("llvm build bit cast failed.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!(func_ctx->last_alloca =
|
|
||||||
LLVMBuildAlloca(comp_ctx->builder, INT8_TYPE, "stack_ptr"))) {
|
|
||||||
aot_set_last_error("llvm build alloca failed.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(int8_ptr_type = LLVMPointerType(INT8_PTR_TYPE, 0))) {
|
if (!(int8_ptr_type = LLVMPointerType(INT8_PTR_TYPE, 0))) {
|
||||||
aot_set_last_error("llvm add pointer type failed.");
|
aot_set_last_error("llvm add pointer type failed.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create base addr, end addr, data size of mem, heap */
|
/* Create base addr, end addr, data size of mem, heap */
|
||||||
if (!create_memory_info(comp_ctx, func_ctx, int8_ptr_type, func_index))
|
if (wasm_func->has_memory_operations
|
||||||
|
&& !create_memory_info(comp_ctx, func_ctx, int8_ptr_type, func_index)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* Load current exception */
|
/* Load current exception */
|
||||||
if (!create_cur_exception(comp_ctx, func_ctx))
|
if (!create_cur_exception(comp_ctx, func_ctx)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* Load function type indexes */
|
/* Load function type indexes */
|
||||||
if (!create_func_type_indexes(comp_ctx, func_ctx))
|
if (wasm_func->has_op_call_indirect
|
||||||
|
&& !create_func_type_indexes(comp_ctx, func_ctx)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* Load function pointers */
|
/* Load function pointers */
|
||||||
if (!create_func_ptrs(comp_ctx, func_ctx))
|
if (!create_func_ptrs(comp_ctx, func_ctx)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
return func_ctx;
|
return func_ctx;
|
||||||
|
|
||||||
|
|
|
@ -247,11 +247,6 @@ struct WASMFunction {
|
||||||
|
|
||||||
uint32 max_stack_cell_num;
|
uint32 max_stack_cell_num;
|
||||||
uint32 max_block_num;
|
uint32 max_block_num;
|
||||||
/* Whether function has opcode memory.grow */
|
|
||||||
bool has_op_memory_grow;
|
|
||||||
/* Whether function has opcode call or
|
|
||||||
call_indirect */
|
|
||||||
bool has_op_func_call;
|
|
||||||
uint32 code_size;
|
uint32 code_size;
|
||||||
uint8 *code;
|
uint8 *code;
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
@ -260,12 +255,29 @@ struct WASMFunction {
|
||||||
uint8 *consts;
|
uint8 *consts;
|
||||||
uint32 const_cell_num;
|
uint32 const_cell_num;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_FAST_JIT != 0
|
#if WASM_ENABLE_FAST_JIT != 0
|
||||||
void *fast_jit_jitted_code;
|
void *fast_jit_jitted_code;
|
||||||
#endif
|
#endif
|
||||||
#if WASM_ENABLE_JIT != 0
|
#if WASM_ENABLE_JIT != 0
|
||||||
void *llvm_jit_func_ptr;
|
void *llvm_jit_func_ptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 \
|
||||||
|
|| WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
/* Whether function has opcode memory.grow */
|
||||||
|
bool has_op_memory_grow;
|
||||||
|
/* Whether function has opcode call or call_indirect */
|
||||||
|
bool has_op_func_call;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
/* Whether function has memory operation opcodes */
|
||||||
|
bool has_memory_operations;
|
||||||
|
/* Whether function has opcode call_indirect */
|
||||||
|
bool has_op_call_indirect;
|
||||||
|
/* Whether function has opcode set_global_aux_stack */
|
||||||
|
bool has_op_set_global_aux_stack;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WASMGlobal {
|
struct WASMGlobal {
|
||||||
|
|
|
@ -7448,7 +7448,10 @@ re_scan:
|
||||||
SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true);
|
SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 \
|
||||||
|
|| WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
func->has_op_func_call = true;
|
func->has_op_func_call = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7542,7 +7545,13 @@ re_scan:
|
||||||
SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true);
|
SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 \
|
||||||
|
|| WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
func->has_op_func_call = true;
|
func->has_op_func_call = true;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_op_call_indirect = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8160,6 +8169,9 @@ re_scan:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
*p_org = WASM_OP_SET_GLOBAL_AUX_STACK;
|
*p_org = WASM_OP_SET_GLOBAL_AUX_STACK;
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_op_set_global_aux_stack = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else /* else of WASM_ENABLE_FAST_INTERP */
|
#else /* else of WASM_ENABLE_FAST_INTERP */
|
||||||
if (global_type == VALUE_TYPE_I64
|
if (global_type == VALUE_TYPE_I64
|
||||||
|
@ -8232,6 +8244,9 @@ re_scan:
|
||||||
}
|
}
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
emit_uint32(loader_ctx, mem_offset);
|
emit_uint32(loader_ctx, mem_offset);
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
#endif
|
#endif
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
/* load */
|
/* load */
|
||||||
|
@ -8296,6 +8311,9 @@ re_scan:
|
||||||
PUSH_I32();
|
PUSH_I32();
|
||||||
|
|
||||||
module->possible_memory_grow = true;
|
module->possible_memory_grow = true;
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WASM_OP_MEMORY_GROW:
|
case WASM_OP_MEMORY_GROW:
|
||||||
|
@ -8308,8 +8326,14 @@ re_scan:
|
||||||
}
|
}
|
||||||
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
||||||
|
|
||||||
func->has_op_memory_grow = true;
|
|
||||||
module->possible_memory_grow = true;
|
module->possible_memory_grow = true;
|
||||||
|
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 \
|
||||||
|
|| WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_op_memory_grow = true;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WASM_OP_I32_CONST:
|
case WASM_OP_I32_CONST:
|
||||||
|
@ -8659,6 +8683,9 @@ re_scan:
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WASM_OP_DATA_DROP:
|
case WASM_OP_DATA_DROP:
|
||||||
|
@ -8676,6 +8703,9 @@ re_scan:
|
||||||
if (module->data_seg_count1 == 0)
|
if (module->data_seg_count1 == 0)
|
||||||
goto fail_data_cnt_sec_require;
|
goto fail_data_cnt_sec_require;
|
||||||
|
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WASM_OP_MEMORY_COPY:
|
case WASM_OP_MEMORY_COPY:
|
||||||
|
@ -8692,6 +8722,9 @@ re_scan:
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WASM_OP_MEMORY_FILL:
|
case WASM_OP_MEMORY_FILL:
|
||||||
|
@ -8707,7 +8740,11 @@ re_scan:
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
fail_zero_byte_expected:
|
fail_zero_byte_expected:
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"zero byte expected");
|
"zero byte expected");
|
||||||
|
@ -8721,7 +8758,6 @@ re_scan:
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"data count section required");
|
"data count section required");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
#endif /* WASM_ENABLE_BULK_MEMORY */
|
#endif /* WASM_ENABLE_BULK_MEMORY */
|
||||||
#if WASM_ENABLE_REF_TYPES != 0
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
case WASM_OP_TABLE_INIT:
|
case WASM_OP_TABLE_INIT:
|
||||||
|
@ -8897,6 +8933,9 @@ re_scan:
|
||||||
read_leb_uint32(p, p_end, mem_offset); /* offset */
|
read_leb_uint32(p, p_end, mem_offset); /* offset */
|
||||||
|
|
||||||
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_V128);
|
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_V128);
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8914,6 +8953,9 @@ re_scan:
|
||||||
|
|
||||||
POP_V128();
|
POP_V128();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9138,6 +9180,9 @@ re_scan:
|
||||||
if (opcode < SIMD_v128_store8_lane) {
|
if (opcode < SIMD_v128_store8_lane) {
|
||||||
PUSH_V128();
|
PUSH_V128();
|
||||||
}
|
}
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9155,6 +9200,9 @@ re_scan:
|
||||||
read_leb_uint32(p, p_end, mem_offset); /* offset */
|
read_leb_uint32(p, p_end, mem_offset); /* offset */
|
||||||
|
|
||||||
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_V128);
|
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_V128);
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9531,6 +9579,9 @@ re_scan:
|
||||||
emit_uint32(loader_ctx, mem_offset);
|
emit_uint32(loader_ctx, mem_offset);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case WASM_OP_ATOMIC_NOTIFY:
|
case WASM_OP_ATOMIC_NOTIFY:
|
||||||
POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
||||||
|
|
|
@ -5701,7 +5701,10 @@ re_scan:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 \
|
||||||
|
|| WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
func->has_op_func_call = true;
|
func->has_op_func_call = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5776,7 +5779,13 @@ re_scan:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 \
|
||||||
|
|| WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
func->has_op_func_call = true;
|
func->has_op_func_call = true;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_op_call_indirect = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6316,6 +6325,9 @@ re_scan:
|
||||||
else if (module->aux_stack_size > 0
|
else if (module->aux_stack_size > 0
|
||||||
&& global_idx == module->aux_stack_top_global_index) {
|
&& global_idx == module->aux_stack_top_global_index) {
|
||||||
*p_org = WASM_OP_SET_GLOBAL_AUX_STACK;
|
*p_org = WASM_OP_SET_GLOBAL_AUX_STACK;
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_op_set_global_aux_stack = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else /* else of WASM_ENABLE_FAST_INTERP */
|
#else /* else of WASM_ENABLE_FAST_INTERP */
|
||||||
if (is_64bit_type(global_type)) {
|
if (is_64bit_type(global_type)) {
|
||||||
|
@ -6385,6 +6397,9 @@ re_scan:
|
||||||
read_leb_uint32(p, p_end, mem_offset); /* offset */
|
read_leb_uint32(p, p_end, mem_offset); /* offset */
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
emit_uint32(loader_ctx, mem_offset);
|
emit_uint32(loader_ctx, mem_offset);
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
#endif
|
#endif
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
/* load */
|
/* load */
|
||||||
|
@ -6446,6 +6461,9 @@ re_scan:
|
||||||
PUSH_I32();
|
PUSH_I32();
|
||||||
|
|
||||||
module->possible_memory_grow = true;
|
module->possible_memory_grow = true;
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WASM_OP_MEMORY_GROW:
|
case WASM_OP_MEMORY_GROW:
|
||||||
|
@ -6455,8 +6473,14 @@ re_scan:
|
||||||
p++;
|
p++;
|
||||||
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
||||||
|
|
||||||
func->has_op_memory_grow = true;
|
|
||||||
module->possible_memory_grow = true;
|
module->possible_memory_grow = true;
|
||||||
|
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 \
|
||||||
|
|| WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_op_memory_grow = true;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WASM_OP_I32_CONST:
|
case WASM_OP_I32_CONST:
|
||||||
|
@ -6781,6 +6805,7 @@ re_scan:
|
||||||
break;
|
break;
|
||||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||||
case WASM_OP_MEMORY_INIT:
|
case WASM_OP_MEMORY_INIT:
|
||||||
|
{
|
||||||
read_leb_uint32(p, p_end, segment_index);
|
read_leb_uint32(p, p_end, segment_index);
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
emit_uint32(loader_ctx, segment_index);
|
emit_uint32(loader_ctx, segment_index);
|
||||||
|
@ -6798,16 +6823,26 @@ re_scan:
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case WASM_OP_DATA_DROP:
|
case WASM_OP_DATA_DROP:
|
||||||
|
{
|
||||||
read_leb_uint32(p, p_end, segment_index);
|
read_leb_uint32(p, p_end, segment_index);
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
emit_uint32(loader_ctx, segment_index);
|
emit_uint32(loader_ctx, segment_index);
|
||||||
#endif
|
#endif
|
||||||
bh_assert(segment_index < module->data_seg_count);
|
bh_assert(segment_index < module->data_seg_count);
|
||||||
bh_assert(module->data_seg_count1 > 0);
|
bh_assert(module->data_seg_count1 > 0);
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case WASM_OP_MEMORY_COPY:
|
case WASM_OP_MEMORY_COPY:
|
||||||
|
{
|
||||||
/* both src and dst memory index should be 0 */
|
/* both src and dst memory index should be 0 */
|
||||||
bh_assert(*(int16 *)p == 0x0000);
|
bh_assert(*(int16 *)p == 0x0000);
|
||||||
p += 2;
|
p += 2;
|
||||||
|
@ -6819,8 +6854,13 @@ re_scan:
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case WASM_OP_MEMORY_FILL:
|
case WASM_OP_MEMORY_FILL:
|
||||||
|
{
|
||||||
bh_assert(*p == 0);
|
bh_assert(*p == 0);
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
|
@ -6831,7 +6871,11 @@ re_scan:
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
POP_I32();
|
POP_I32();
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
#endif /* WASM_ENABLE_BULK_MEMORY */
|
#endif /* WASM_ENABLE_BULK_MEMORY */
|
||||||
#if WASM_ENABLE_REF_TYPES != 0
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
case WASM_OP_TABLE_INIT:
|
case WASM_OP_TABLE_INIT:
|
||||||
|
@ -6993,6 +7037,9 @@ re_scan:
|
||||||
emit_uint32(loader_ctx, mem_offset);
|
emit_uint32(loader_ctx, mem_offset);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
|
func->has_memory_operations = true;
|
||||||
|
#endif
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case WASM_OP_ATOMIC_NOTIFY:
|
case WASM_OP_ATOMIC_NOTIFY:
|
||||||
POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
||||||
|
|
|
@ -43,7 +43,7 @@ endif ()
|
||||||
# Override the global heap usage
|
# Override the global heap usage
|
||||||
if (NOT DEFINED WAMR_BUILD_GLOBAL_HEAP_POOL)
|
if (NOT DEFINED WAMR_BUILD_GLOBAL_HEAP_POOL)
|
||||||
add_definitions (-DWASM_ENABLE_GLOBAL_HEAP_POOL=1)
|
add_definitions (-DWASM_ENABLE_GLOBAL_HEAP_POOL=1)
|
||||||
endif
|
endif ()
|
||||||
|
|
||||||
# Override the global heap size for small devices
|
# Override the global heap size for small devices
|
||||||
if (NOT DEFINED WAMR_BUILD_GLOBAL_HEAP_SIZE)
|
if (NOT DEFINED WAMR_BUILD_GLOBAL_HEAP_SIZE)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user