Explorar o código

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.
YAMAMOTO Takashi hai 1 ano
pai
achega
867dbd8912

+ 8 - 0
core/iwasm/compilation/aot_compiler.h

@@ -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)
 

+ 2 - 0
core/iwasm/compilation/aot_emit_const.c

@@ -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;

+ 13 - 3
core/iwasm/compilation/aot_emit_memory.c

@@ -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 =

+ 3 - 1
core/iwasm/compilation/aot_llvm.h

@@ -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;
 
 /**