aot compiler: Propagate const-ness by ourselves (#3567)

aot_load_const_from_table() hides the const-ness of the
value and prevents optimizations like
https://github.com/bytecodealliance/wasm-micro-runtime/pull/3552.

This commit makes the aot compiler tracks the const-ness
of the value directly in the AOTValue and enables the above
mentioned optimization for XIP.
This commit is contained in:
YAMAMOTO Takashi
2024-06-25 11:57:49 +09:00
committed by GitHub
parent e66b41427f
commit 867dbd8912
4 changed files with 26 additions and 4 deletions

View File

@ -605,6 +605,14 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type)
#define PUSH_PAGE_COUNT(v) \
PUSH(v, MEMORY64_COND_VALUE(VALUE_TYPE_I64, VALUE_TYPE_I32))
#define SET_CONST(v) \
do { \
AOTValue *aot_value = \
func_ctx->block_stack.block_list_end->value_stack.value_list_end; \
aot_value->is_const = true; \
aot_value->const_value = (v); \
} while (0)
#define TO_LLVM_TYPE(wasm_type) \
wasm_type_to_llvm_type(comp_ctx, &comp_ctx->basic_types, wasm_type)

View File

@ -28,6 +28,7 @@ aot_compile_op_i32_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
PUSH_I32(value);
SET_CONST((uint64)(uint32)i32_const);
return true;
fail:
return false;
@ -55,6 +56,7 @@ aot_compile_op_i64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
PUSH_I64(value);
SET_CONST((uint64)i64_const);
return true;
fail:
return false;

View File

@ -107,7 +107,9 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMBasicBlockRef check_succ;
AOTValue *aot_value_top;
uint32 local_idx_of_aot_value = 0;
uint64 const_value;
bool is_target_64bit, is_local_of_aot_value = false;
bool is_const = false;
#if WASM_ENABLE_SHARED_MEMORY != 0
bool is_shared_memory =
comp_ctx->comp_data->memories[0].flags & SHARED_MEMORY_FLAG;
@ -162,7 +164,9 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* aot_value_top is freed in the following POP_I32(addr),
so save its fields here for further use */
is_local_of_aot_value = aot_value_top->is_local;
is_const = aot_value_top->is_const;
local_idx_of_aot_value = aot_value_top->local_idx;
const_value = aot_value_top->const_value;
}
POP_MEM_OFFSET(addr);
@ -172,9 +176,15 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
* have been thrown when converting float to integer before
*/
/* return address directly if constant offset and inside memory space */
if (LLVMIsEfficientConstInt(addr)) {
uint64 mem_offset =
(uint64)LLVMConstIntGetZExtValue(addr) + (uint64)offset;
if (LLVMIsEfficientConstInt(addr) || is_const) {
uint64 value;
if (LLVMIsEfficientConstInt(addr)) {
value = (uint64)LLVMConstIntGetZExtValue(addr);
}
else {
value = const_value;
}
uint64 mem_offset = value + (uint64)offset;
uint32 num_bytes_per_page =
comp_ctx->comp_data->memories[0].num_bytes_per_page;
uint32 init_page_count =

View File

@ -75,10 +75,12 @@ typedef struct AOTValue {
struct AOTValue *next;
struct AOTValue *prev;
LLVMValueRef value;
uint64 const_value; /* valid if is_const is true */
uint32 local_idx;
/* VALUE_TYPE_I32/I64/F32/F64/VOID */
uint8 type;
bool is_local;
uint32 local_idx;
bool is_const;
} AOTValue;
/**