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
This commit is contained in:
Wenyong Huang 2024-01-23 16:15:04 +08:00 committed by GitHub
parent 4f0551ac25
commit 7c812ece9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 166 additions and 30 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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