Просмотр исходного кода

Enhance aot feature flags emit and load (#3048)

- Emit SIMD/ref-types/bulk-memory flags into AOT file only when the features
  are really used in wasm file
- Remove unused tail-call flag and stringref flag
- Add memoy64 flag and dynamic-linking flag
- Change WASM_FEATURE_THREADS to WASM_FEATURE_MULTI_THREAD
Wenyong Huang 2 лет назад
Родитель
Сommit
7c812ece9a

+ 6 - 10
core/iwasm/aot/aot_loader.c

@@ -481,7 +481,7 @@ check_feature_flags(char *error_buf, uint32 error_buf_size,
 #endif
 
 #if WASM_ENABLE_THREAD_MGR == 0
-    if (feature_flags & WASM_FEATURE_THREADS) {
+    if (feature_flags & WASM_FEATURE_MULTI_THREAD) {
         set_error_buf(error_buf, error_buf_size,
                       "thread is not enabled in this build");
         return false;
@@ -496,14 +496,6 @@ check_feature_flags(char *error_buf, uint32 error_buf_size,
     }
 #endif
 
-#if WASM_ENABLE_TAIL_CALL == 0
-    if (feature_flags & WASM_FEATURE_TAIL_CALL) {
-        set_error_buf(error_buf, error_buf_size,
-                      "tail call is not enabled in this build");
-        return false;
-    }
-#endif
-
 #if WASM_ENABLE_GC == 0
     if (feature_flags & WASM_FEATURE_GARBAGE_COLLECTION) {
         set_error_buf(error_buf, error_buf_size,
@@ -1186,8 +1178,12 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
         case INIT_EXPR_TYPE_GET_GLOBAL:
             read_uint32(buf, buf_end, expr->u.global_index);
             break;
-#if WASM_ENABLE_GC != 0 || WASM_ENABLE_REF_TYPES != 0
+        /* INIT_EXPR_TYPE_FUNCREF_CONST can be used when
+           both reference types and GC are disabled */
         case INIT_EXPR_TYPE_FUNCREF_CONST:
+            read_uint32(buf, buf_end, expr->u.ref_index);
+            break;
+#if WASM_ENABLE_GC != 0 || WASM_ENABLE_REF_TYPES != 0
         case INIT_EXPR_TYPE_REFNULL_CONST:
             read_uint32(buf, buf_end, expr->u.ref_index);
             break;

+ 8 - 8
core/iwasm/aot/aot_runtime.h

@@ -25,16 +25,16 @@ extern "C" {
 /* Wasm feature supported, mainly used by AOTTargetInfo now */
 #define WASM_FEATURE_SIMD_128BIT (1 << 0)
 #define WASM_FEATURE_BULK_MEMORY (1 << 1)
-#define WASM_FEATURE_THREADS (1 << 2)
+#define WASM_FEATURE_MULTI_THREAD (1 << 2)
 #define WASM_FEATURE_REF_TYPES (1 << 3)
-#define WASM_FEATURE_TAIL_CALL (1 << 4)
+#define WASM_FEATURE_GARBAGE_COLLECTION (1 << 4)
 #define WASM_FEATURE_EXCEPTION_HANDLING (1 << 5)
-#define WASM_FEATURE_GARBAGE_COLLECTION (1 << 6)
-#define WASM_FEATURE_COMPONENT_MODEL (1 << 7)
-#define WASM_FEATURE_MULTIPLE_MEMORY (1 << 8)
-#define WASM_FEATURE_RELAXED_SIMD (1 << 9)
-#define WASM_FEATURE_FLEXIBLE_VECTORS (1 << 10)
-#define WASM_FEATURE_STRING_REF (1 << 11)
+#define WASM_FEATURE_MEMORY64 (1 << 6)
+#define WASM_FEATURE_MULTI_MEMORY (1 << 7)
+#define WASM_FEATURE_DYNAMIC_LINKING (1 << 8)
+#define WASM_FEATURE_COMPONENT_MODEL (1 << 9)
+#define WASM_FEATURE_RELAXED_SIMD (1 << 10)
+#define WASM_FEATURE_FLEXIBLE_VECTORS (1 << 11)
 
 typedef enum AOTSectionType {
     AOT_SECTION_TYPE_TARGET_INFO = 0,

+ 1 - 4
core/iwasm/compilation/aot_emit_aot_file.c

@@ -4389,14 +4389,11 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
         obj_data->target_info.feature_flags |= WASM_FEATURE_BULK_MEMORY;
     }
     if (comp_ctx->enable_thread_mgr) {
-        obj_data->target_info.feature_flags |= WASM_FEATURE_THREADS;
+        obj_data->target_info.feature_flags |= WASM_FEATURE_MULTI_THREAD;
     }
     if (comp_ctx->enable_ref_types) {
         obj_data->target_info.feature_flags |= WASM_FEATURE_REF_TYPES;
     }
-    if (comp_ctx->enable_tail_call) {
-        obj_data->target_info.feature_flags |= WASM_FEATURE_TAIL_CALL;
-    }
     if (comp_ctx->enable_gc) {
         obj_data->target_info.feature_flags |= WASM_FEATURE_GARBAGE_COLLECTION;
     }

+ 12 - 4
core/iwasm/compilation/aot_llvm.c

@@ -3075,17 +3075,25 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
     LLVMDisposeMessage(triple);
 
 #if WASM_ENABLE_WAMR_COMPILER != 0
+    WASMModule *wasm_module = (WASMModule *)comp_data->wasm_module;
+
     /* Return error if SIMD is disabled by command line but SIMD instructions
      * are used */
-    if (!option->enable_simd
-        && ((WASMModule *)comp_data->wasm_module)->is_simd_used) {
+    if (!option->enable_simd && wasm_module->is_simd_used) {
         aot_set_last_error("SIMD is disabled by --disable-simd but SIMD "
                            "instructions are used in this module");
         goto fail;
     }
 
-    if (!((WASMModule *)comp_data->wasm_module)->is_simd_used) {
-        option->enable_simd = false;
+    /* Disable features when they are not actually used */
+    if (!wasm_module->is_simd_used) {
+        option->enable_simd = comp_ctx->enable_simd = false;
+    }
+    if (!wasm_module->is_ref_types_used) {
+        option->enable_ref_types = comp_ctx->enable_ref_types = false;
+    }
+    if (!wasm_module->is_bulk_memory_used) {
+        option->enable_bulk_memory = comp_ctx->enable_bulk_memory = false;
     }
 #endif
 

+ 2 - 0
core/iwasm/interpreter/wasm.h

@@ -980,6 +980,8 @@ struct WASMModule {
 
 #if WASM_ENABLE_WAMR_COMPILER != 0
     bool is_simd_used;
+    bool is_ref_types_used;
+    bool is_bulk_memory_used;
 #endif
 };
 

+ 137 - 4
core/iwasm/interpreter/wasm_loader.c

@@ -854,6 +854,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
                                            0, &cur_value, error_buf,
                                            error_buf_size))
                     goto fail;
+#endif
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                module->is_ref_types_used = true;
 #endif
                 break;
             }
@@ -896,6 +899,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
                                                error_buf_size))
                         goto fail;
                 }
+#endif
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                module->is_ref_types_used = true;
 #endif
                 break;
             }
@@ -1619,6 +1625,13 @@ resolve_func_type(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
     type->quick_aot_entry = wasm_native_lookup_quick_aot_entry(type);
 #endif
 
+#if WASM_ENABLE_WAMR_COMPILER != 0
+    for (i = 0; i < type->param_count + type->result_count; i++) {
+        if (type->types[i] == VALUE_TYPE_V128)
+            module->is_simd_used = true;
+    }
+#endif
+
     /* Calculate the minimal type index of the type equal to this type */
     type->min_type_idx_normalized = type_idx;
     for (i = 0; i < type_idx; i++) {
@@ -1994,6 +2007,16 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
             type->quick_aot_entry = wasm_native_lookup_quick_aot_entry(type);
 #endif
 
+#if WASM_ENABLE_WAMR_COMPILER != 0
+            for (j = 0; j < type->param_count + type->result_count; j++) {
+                if (type->types[j] == VALUE_TYPE_V128)
+                    module->is_simd_used = true;
+                else if (type->types[j] == VALUE_TYPE_FUNCREF
+                         || type->types[j] == VALUE_TYPE_EXTERNREF)
+                    module->is_ref_types_used = true;
+            }
+#endif
+
             /* If there is already a same type created, use it instead */
             for (j = 0; j < i; j++) {
                 if (wasm_type_equal(type, module->types[j], module->types, i)) {
@@ -2627,6 +2650,10 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
     table->flags = declare_max_size_flag;
     table->max_size = declare_max_size;
 
+#if WASM_ENABLE_WAMR_COMPILER != 0
+    if (table->elem_type == VALUE_TYPE_EXTERNREF)
+        parent_module->is_ref_types_used = true;
+#endif
     (void)parent_module;
     return true;
 fail:
@@ -2868,6 +2895,12 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
     global->type = declare_type;
     global->is_mutable = (declare_mutable == 1);
 
+#if WASM_ENABLE_WAMR_COMPILER != 0
+    if (global->type == VALUE_TYPE_V128)
+        parent_module->is_simd_used = true;
+    else if (global->type == VALUE_TYPE_EXTERNREF)
+        parent_module->is_ref_types_used = true;
+#endif
     (void)parent_module;
     (void)ret;
     return true;
@@ -2955,6 +2988,11 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
 
     adjust_table_max_size(table->init_size, table->flags, &table->max_size);
 
+#if WASM_ENABLE_WAMR_COMPILER != 0
+    if (table->elem_type == VALUE_TYPE_EXTERNREF)
+        module->is_ref_types_used = true;
+#endif
+
     *p_buf = p;
     return true;
 fail:
@@ -3095,13 +3133,15 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
                         read_leb_uint32(p, p_end, u32);
                     module->import_table_count++;
 
-#if WASM_ENABLE_REF_TYPES == 0 && WASM_ENABLE_GC == 0
                     if (module->import_table_count > 1) {
+#if WASM_ENABLE_REF_TYPES == 0 && WASM_ENABLE_GC == 0
                         set_error_buf(error_buf, error_buf_size,
                                       "multiple tables");
                         return false;
-                    }
+#elif WASM_ENABLE_WAMR_COMPILER != 0
+                        module->is_ref_types_used = true;
 #endif
+                    }
                     break;
 
                 case IMPORT_KIND_MEMORY: /* import memory */
@@ -3510,6 +3550,13 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
                 for (k = 0; k < sub_local_count; k++) {
                     func->local_types[local_type_index++] = type;
                 }
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                if (type == VALUE_TYPE_V128)
+                    module->is_simd_used = true;
+                else if (type == VALUE_TYPE_FUNCREF
+                         || type == VALUE_TYPE_EXTERNREF)
+                    module->is_ref_types_used = true;
+#endif
             }
 
             bh_assert(local_type_index == func->local_count);
@@ -3573,13 +3620,15 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
     WASMTable *table;
 
     read_leb_uint32(p, p_end, table_count);
-#if WASM_ENABLE_REF_TYPES == 0 && WASM_ENABLE_GC == 0
     if (module->import_table_count + table_count > 1) {
+#if WASM_ENABLE_REF_TYPES == 0 && WASM_ENABLE_GC == 0
         /* a total of one table is allowed */
         set_error_buf(error_buf, error_buf_size, "multiple tables");
         return false;
-    }
+#elif WASM_ENABLE_WAMR_COMPILER != 0
+        module->is_ref_types_used = true;
 #endif
+    }
 
     if (table_count) {
         module->table_count = table_count;
@@ -3643,6 +3692,11 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
                 }
             }
 #endif /* end of WASM_ENABLE_GC != 0 */
+
+#if WASM_ENABLE_WAMR_COMPILER != 0
+            if (table->elem_type == VALUE_TYPE_EXTERNREF)
+                module->is_ref_types_used = true;
+#endif
         }
     }
 
@@ -3741,6 +3795,14 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
             mutable = read_uint8(p);
 #endif /* end of WASM_ENABLE_GC */
 
+#if WASM_ENABLE_WAMR_COMPILER != 0
+            if (global->type == VALUE_TYPE_V128)
+                module->is_simd_used = true;
+            else if (global->type == VALUE_TYPE_FUNCREF
+                     || global->type == VALUE_TYPE_EXTERNREF)
+                module->is_ref_types_used = true;
+#endif
+
             if (!check_mutability(mutable, error_buf, error_buf_size)) {
                 return false;
             }
@@ -4302,6 +4364,11 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
                                      error_buf, error_buf_size))
                 return false;
 #endif /* WASM_ENABLE_REF_TYPES != 0 */
+
+#if WASM_ENABLE_WAMR_COMPILER != 0
+            if (table_segment->elem_type == VALUE_TYPE_EXTERNREF)
+                module->is_ref_types_used = true;
+#endif
         }
     }
 
@@ -4358,6 +4425,9 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
             switch (mem_flag) {
                 case 0x01:
                     is_passive = true;
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                    module->is_bulk_memory_used = true;
+#endif
                     break;
                 case 0x00:
                     /* no memory index, treat index as 0 */
@@ -4366,6 +4436,9 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
                 case 0x02:
                     /* read following memory index */
                     read_leb_uint32(p, p_end, mem_index);
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                    module->is_bulk_memory_used = true;
+#endif
                 check_mem_index:
                     if (mem_index
                         >= module->import_memory_count + module->memory_count) {
@@ -4451,6 +4524,9 @@ load_datacount_section(const uint8 *buf, const uint8 *buf_end,
         return false;
     }
 
+#if WASM_ENABLE_WAMR_COMPILER != 0
+    module->is_bulk_memory_used = true;
+#endif
     LOG_VERBOSE("Load datacount section success.\n");
     return true;
 fail:
@@ -10184,6 +10260,13 @@ re_scan:
                      * the single return value. */
                     block_type.is_value_type = true;
                     block_type.u.value_type.type = value_type;
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                    if (value_type == VALUE_TYPE_V128)
+                        module->is_simd_used = true;
+                    else if (value_type == VALUE_TYPE_FUNCREF
+                             || value_type == VALUE_TYPE_EXTERNREF)
+                        module->is_ref_types_used = true;
+#endif
 #if WASM_ENABLE_GC != 0
                     if (value_type != VALUE_TYPE_VOID) {
                         p_org = p;
@@ -11274,6 +11357,9 @@ re_scan:
 #endif
                 PUSH_REF(type);
 
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                module->is_ref_types_used = true;
+#endif
                 (void)vec_len;
                 break;
             }
@@ -11325,6 +11411,9 @@ re_scan:
                     POP_I32();
                 }
 
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                module->is_ref_types_used = true;
+#endif
                 break;
             }
             case WASM_OP_REF_NULL:
@@ -11365,6 +11454,10 @@ re_scan:
                 PUSH_OFFSET_TYPE(ref_type);
 #endif
                 PUSH_TYPE(ref_type);
+
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                module->is_ref_types_used = true;
+#endif
                 break;
             }
             case WASM_OP_REF_IS_NULL:
@@ -11416,6 +11509,10 @@ re_scan:
                 }
 #endif
                 PUSH_I32();
+
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                module->is_ref_types_used = true;
+#endif
                 break;
             }
             case WASM_OP_REF_FUNC:
@@ -11483,6 +11580,10 @@ re_scan:
                                              false, type_idx);
                 PUSH_REF(wasm_ref_type.ref_type);
 #endif
+
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                module->is_ref_types_used = true;
+#endif
                 break;
             }
 #endif /* end of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */
@@ -13426,6 +13527,9 @@ re_scan:
                         POP_I32();
 #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
                         func->has_memory_operations = true;
+#endif
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                        module->is_bulk_memory_used = true;
 #endif
                         break;
                     }
@@ -13446,6 +13550,9 @@ re_scan:
 
 #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
                         func->has_memory_operations = true;
+#endif
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                        module->is_bulk_memory_used = true;
 #endif
                         break;
                     }
@@ -13465,6 +13572,9 @@ re_scan:
                         POP_I32();
 #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
                         func->has_memory_operations = true;
+#endif
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                        module->is_bulk_memory_used = true;
 #endif
                         break;
                     }
@@ -13483,6 +13593,9 @@ re_scan:
                         POP_I32();
 #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
                         func->has_memory_operations = true;
+#endif
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                        module->is_bulk_memory_used = true;
 #endif
                         break;
                     }
@@ -13553,6 +13666,10 @@ re_scan:
                         POP_I32();
                         POP_I32();
                         POP_I32();
+
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                        module->is_ref_types_used = true;
+#endif
                         break;
                     }
                     case WASM_OP_ELEM_DROP:
@@ -13565,6 +13682,10 @@ re_scan:
 #if WASM_ENABLE_FAST_INTERP != 0
                         emit_uint32(loader_ctx, table_seg_idx);
 #endif
+
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                        module->is_ref_types_used = true;
+#endif
                         break;
                     }
                     case WASM_OP_TABLE_COPY:
@@ -13618,6 +13739,10 @@ re_scan:
                         POP_I32();
                         POP_I32();
                         POP_I32();
+
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                        module->is_ref_types_used = true;
+#endif
                         break;
                     }
                     case WASM_OP_TABLE_SIZE:
@@ -13634,6 +13759,10 @@ re_scan:
 #endif
 
                         PUSH_I32();
+
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                        module->is_ref_types_used = true;
+#endif
                         break;
                     }
                     case WASM_OP_TABLE_GROW:
@@ -13687,6 +13816,10 @@ re_scan:
                             PUSH_I32();
                         else
                             POP_I32();
+
+#if WASM_ENABLE_WAMR_COMPILER != 0
+                        module->is_ref_types_used = true;
+#endif
                         break;
                     }
 #endif /* end of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */