Support extended constant expressions (#4432)

* implement extended const expr (#4318)
* add a toggle to enable extended const on wamrc (#4412)
This commit is contained in:
TianlongLiang
2025-07-07 13:34:02 +08:00
committed by GitHub
parent be33a40ba7
commit 7d05dbc988
28 changed files with 1734 additions and 379 deletions

View File

@ -216,7 +216,7 @@ get_init_expr_size(const AOTCompContext *comp_ctx, const AOTCompData *comp_data,
#if WASM_ENABLE_GC != 0
WASMModule *module = comp_data->wasm_module;
#endif
bh_assert(expr != NULL);
/* + init value size */
switch (expr->init_expr_type) {
case INIT_EXPR_NONE:
@ -248,7 +248,7 @@ get_init_expr_size(const AOTCompContext *comp_ctx, const AOTCompData *comp_data,
{
uint32 i;
WASMStructNewInitValues *struct_new_init_values =
(WASMStructNewInitValues *)expr->u.data;
(WASMStructNewInitValues *)expr->u.unary.v.data;
/* type_index + field_count + fields */
size += sizeof(uint32) + sizeof(uint32);
@ -285,7 +285,7 @@ get_init_expr_size(const AOTCompContext *comp_ctx, const AOTCompData *comp_data,
case INIT_EXPR_TYPE_ARRAY_NEW_FIXED:
{
WASMArrayNewInitValues *array_new_init_values =
(WASMArrayNewInitValues *)expr->u.data;
(WASMArrayNewInitValues *)expr->u.unary.v.data;
WASMArrayType *array_type = NULL;
uint32 value_count;
@ -308,6 +308,21 @@ get_init_expr_size(const AOTCompContext *comp_ctx, const AOTCompData *comp_data,
break;
}
#endif /* end of WASM_ENABLE_GC != 0 */
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
case INIT_EXPR_TYPE_I32_ADD:
case INIT_EXPR_TYPE_I32_SUB:
case INIT_EXPR_TYPE_I32_MUL:
case INIT_EXPR_TYPE_I64_ADD:
case INIT_EXPR_TYPE_I64_SUB:
case INIT_EXPR_TYPE_I64_MUL:
{
size +=
get_init_expr_size(comp_ctx, comp_data, expr->u.binary.l_expr);
size +=
get_init_expr_size(comp_ctx, comp_data, expr->u.binary.r_expr);
break;
}
#endif
default:
bh_assert(0);
}
@ -324,15 +339,16 @@ get_table_init_data_size(AOTCompContext *comp_ctx,
/*
* mode (4 bytes), elem_type (4 bytes)
*
* table_index(4 bytes) + init expr type (4 bytes) + init expr value (8
* bytes)
* table_index(4 bytes)
*/
size = (uint32)(sizeof(uint32) * 2 + sizeof(uint32) + sizeof(uint32)
+ sizeof(uint64))
size = (uint32)(sizeof(uint32) * 2 + sizeof(uint32))
/* Size of WasmRefType - inner padding (ref type + nullable +
heap_type) */
+ 8;
size += get_init_expr_size(comp_ctx, comp_ctx->comp_data,
&table_init_data->offset);
/* + value count/func index count (4 bytes) + init_values */
size += sizeof(uint32);
for (i = 0; i < table_init_data->value_count; i++) {
@ -1811,6 +1827,10 @@ static bool
aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
AOTCompContext *comp_ctx, InitializerExpression *expr)
{
if (expr == NULL) {
aot_set_last_error("invalid init expr.");
return false;
}
uint32 offset = *p_offset;
#if WASM_ENABLE_GC != 0
WASMModule *module = comp_ctx->comp_data->wasm_module;
@ -1824,31 +1844,31 @@ aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
break;
case INIT_EXPR_TYPE_I32_CONST:
case INIT_EXPR_TYPE_F32_CONST:
EMIT_U32(expr->u.i32);
EMIT_U32(expr->u.unary.v.i32);
break;
case INIT_EXPR_TYPE_I64_CONST:
case INIT_EXPR_TYPE_F64_CONST:
EMIT_U64(expr->u.i64);
EMIT_U64(expr->u.unary.v.i64);
break;
case INIT_EXPR_TYPE_V128_CONST:
EMIT_V128(expr->u.v128);
EMIT_V128(expr->u.unary.v.v128);
break;
case INIT_EXPR_TYPE_GET_GLOBAL:
EMIT_U32(expr->u.global_index);
EMIT_U32(expr->u.unary.v.global_index);
break;
case INIT_EXPR_TYPE_FUNCREF_CONST:
case INIT_EXPR_TYPE_REFNULL_CONST:
EMIT_U32(expr->u.ref_index);
EMIT_U32(expr->u.unary.v.ref_index);
break;
#if WASM_ENABLE_GC != 0
case INIT_EXPR_TYPE_I31_NEW:
EMIT_U32(expr->u.i32);
EMIT_U32(expr->u.unary.v.i32);
break;
case INIT_EXPR_TYPE_STRUCT_NEW:
{
uint32 i;
WASMStructNewInitValues *init_values =
(WASMStructNewInitValues *)expr->u.data;
(WASMStructNewInitValues *)expr->u.unary.v.data;
WASMStructType *struct_type = NULL;
EMIT_U32(init_values->type_idx);
@ -1879,7 +1899,7 @@ aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
break;
}
case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
EMIT_U32(expr->u.type_index);
EMIT_U32(expr->u.unary.v.type_index);
break;
case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT:
{
@ -1889,11 +1909,11 @@ aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
< module->type_count);
array_type =
(WASMArrayType *)
module->types[expr->u.array_new_default.type_index];
module->types[expr->u.unary.v.array_new_default.type_index];
EMIT_U32(array_type->elem_type);
EMIT_U32(expr->u.array_new_default.type_index);
EMIT_U32(expr->u.array_new_default.length);
EMIT_U32(expr->u.unary.v.array_new_default.type_index);
EMIT_U32(expr->u.unary.v.array_new_default.length);
break;
}
case INIT_EXPR_TYPE_ARRAY_NEW:
@ -1901,7 +1921,7 @@ aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
{
uint32 value_count, i, field_size;
WASMArrayNewInitValues *init_values =
(WASMArrayNewInitValues *)expr->u.data;
(WASMArrayNewInitValues *)expr->u.unary.v.data;
WASMArrayType *array_type = NULL;
bh_assert(init_values->type_idx < module->type_count);
@ -1933,6 +1953,25 @@ aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
break;
}
#endif /* end of WASM_ENABLE_GC != 0 */
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
case INIT_EXPR_TYPE_I32_ADD:
case INIT_EXPR_TYPE_I32_SUB:
case INIT_EXPR_TYPE_I32_MUL:
case INIT_EXPR_TYPE_I64_ADD:
case INIT_EXPR_TYPE_I64_SUB:
case INIT_EXPR_TYPE_I64_MUL:
if (comp_ctx->enable_extended_const) {
if (!aot_emit_init_expr(buf, buf_end, &offset, comp_ctx,
expr->u.binary.l_expr)) {
return false;
}
if (!aot_emit_init_expr(buf, buf_end, &offset, comp_ctx,
expr->u.binary.r_expr)) {
return false;
}
}
break;
#endif
default:
aot_set_last_error("invalid init expr type.");
return false;
@ -2034,8 +2073,10 @@ aot_emit_table_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
EMIT_U32(init_datas[i]->mode);
EMIT_U32(init_datas[i]->elem_type);
EMIT_U32(init_datas[i]->table_index);
EMIT_U32(init_datas[i]->offset.init_expr_type);
EMIT_U64(init_datas[i]->offset.u.i64);
if (!aot_emit_init_expr(buf, buf_end, &offset, comp_ctx,
&init_datas[i]->offset))
return false;
#if WASM_ENABLE_GC != 0
if (comp_ctx->enable_gc && init_datas[i]->elem_ref_type) {
EMIT_U16(init_datas[i]->elem_ref_type->ref_ht_common.ref_type);

View File

@ -2787,6 +2787,9 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
if (option->enable_shared_chain)
comp_ctx->enable_shared_chain = true;
if (option->enable_extended_const)
comp_ctx->enable_extended_const = true;
comp_ctx->opt_level = option->opt_level;
comp_ctx->size_level = option->size_level;

View File

@ -461,6 +461,9 @@ typedef struct AOTCompContext {
/* Enable LLVM PGO (Profile-Guided Optimization) */
bool enable_llvm_pgo;
/* Enable extended constant expression */
bool enable_extended_const;
/* Treat unknown import function as wasm-c-api import function
and allow to directly invoke it from AOT/JIT code */
bool quick_invoke_c_api_import;