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:
@ -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)
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 =
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user