Add wamrc parameter to configure stack frame features (#3763)

Those parameters can be used to reduce the size of the AOT code.

There's going to be more changes related to AOT code size reduction,
this is just the initial step.

p.s. https://github.com/bytecodealliance/wasm-micro-runtime/issues/3758
This commit is contained in:
Marcin Kolny
2024-09-05 14:44:06 +01:00
committed by GitHub
parent b4380fb3b1
commit 6f97822c18
9 changed files with 127 additions and 19 deletions

View File

@ -337,6 +337,10 @@ aot_gen_commit_values(AOTCompFrame *frame)
LLVMValueRef value;
uint32 n;
if (!frame->comp_ctx->call_stack_features.values) {
return true;
}
/* First, commit reference flags
* For LLVM JIT, iterate all local and stack ref flags
* For AOT, ignore local(params + locals) ref flags */
@ -629,7 +633,7 @@ aot_gen_commit_sp_ip(AOTCompFrame *frame, bool commit_sp, bool commit_ip)
offset_sp = offsetof(WASMInterpFrame, sp);
}
if (commit_ip) {
if (commit_ip && comp_ctx->call_stack_features.ip) {
if (!comp_ctx->is_jit_mode) {
WASMModule *module = comp_ctx->comp_data->wasm_module;
if (is_64bit)
@ -654,7 +658,7 @@ aot_gen_commit_sp_ip(AOTCompFrame *frame, bool commit_sp, bool commit_ip)
}
}
if (commit_sp) {
if (commit_sp && comp_ctx->call_stack_features.values) {
n = (uint32)(sp - frame->lp);
value = I32_CONST(offset_of_local(comp_ctx, n));
if (!value) {

View File

@ -41,7 +41,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false;
}
if (comp_ctx->aot_frame) {
if (comp_ctx->aot_frame && comp_ctx->call_stack_features.trap_ip) {
/* Create exception ip phi */
if (!(func_ctx->exception_ip_phi = LLVMBuildPhi(
comp_ctx->builder, is_64bit ? I64_TYPE : I32_TYPE,
@ -134,7 +134,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Add phi incoming value to got_exception block */
LLVMAddIncoming(func_ctx->exception_id_phi, &exce_id, &block_curr, 1);
if (comp_ctx->aot_frame) {
if (comp_ctx->aot_frame && comp_ctx->call_stack_features.trap_ip) {
const uint8 *ip = comp_ctx->aot_frame->frame_ip;
LLVMValueRef exce_ip = NULL;

View File

@ -682,24 +682,29 @@ alloc_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
new_frame = wasm_stack_top;
if (!(check_wasm_stack_succ = LLVMAppendBasicBlockInContext(
comp_ctx->context, func_ctx->func, "check_wasm_stack_succ"))) {
aot_set_last_error("llvm add basic block failed.");
return false;
}
if (comp_ctx->call_stack_features.bounds_checks) {
if (!(check_wasm_stack_succ = LLVMAppendBasicBlockInContext(
comp_ctx->context, func_ctx->func,
"check_wasm_stack_succ"))) {
aot_set_last_error("llvm add basic block failed.");
return false;
}
LLVMMoveBasicBlockAfter(check_wasm_stack_succ,
LLVMGetInsertBlock(comp_ctx->builder));
LLVMMoveBasicBlockAfter(check_wasm_stack_succ,
LLVMGetInsertBlock(comp_ctx->builder));
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT, wasm_stack_top_max,
wasm_stack_top_bound, "cmp"))) {
aot_set_last_error("llvm build icmp failed");
return false;
}
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT,
wasm_stack_top_max, wasm_stack_top_bound,
"cmp"))) {
aot_set_last_error("llvm build icmp failed");
return false;
}
if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_OPERAND_STACK_OVERFLOW,
true, cmp, check_wasm_stack_succ))) {
return false;
if (!(aot_emit_exception(comp_ctx, func_ctx,
EXCE_OPERAND_STACK_OVERFLOW, true, cmp,
check_wasm_stack_succ))) {
return false;
}
}
#if WASM_ENABLE_GC != 0
@ -1285,6 +1290,10 @@ commit_params_to_frame_of_import_func(AOTCompContext *comp_ctx,
{
uint32 i, n;
if (!comp_ctx->call_stack_features.values) {
return true;
}
for (i = 0, n = 0; i < func_type->param_count; i++, n++) {
switch (func_type->types[i]) {
case VALUE_TYPE_I32:

View File

@ -2580,6 +2580,8 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
if (option->enable_aux_stack_frame)
comp_ctx->enable_aux_stack_frame = true;
comp_ctx->call_stack_features = option->call_stack_features;
if (option->enable_perf_profiling)
comp_ctx->enable_perf_profiling = true;

View File

@ -412,6 +412,9 @@ typedef struct AOTCompContext {
/* Generate auxiliary stack frame */
bool enable_aux_stack_frame;
/* Auxiliary call stack features */
AOTCallStackFeatures call_stack_features;
/* Function performance profiling */
bool enable_perf_profiling;

View File

@ -6,6 +6,23 @@
#ifndef __AOT_COMP_OPTION_H__
#define __AOT_COMP_OPTION_H__
typedef struct {
/* Enables or disables bounds checks for stack frames. When enabled, the AOT
* compiler generates code to check if the stack pointer is within the
* bounds of the current stack frame (and if not, traps). */
bool bounds_checks;
/* Enables or disables instruction pointer (IP) tracking.*/
bool ip;
/* Enables or disables tracking instruction pointer of a trap. Only takes
* effect when `ip` is enabled.*/
bool trap_ip;
/* Enables or disables parameters, locals and stack operands. */
bool values;
} AOTCallStackFeatures;
typedef struct AOTCompOption {
bool is_jit_mode;
bool is_indirect_mode;
@ -22,6 +39,7 @@ typedef struct AOTCompOption {
bool enable_gc;
bool enable_aux_stack_check;
bool enable_aux_stack_frame;
AOTCallStackFeatures call_stack_features;
bool enable_perf_profiling;
bool enable_memory_profiling;
bool disable_llvm_intrinsics;

View File

@ -5407,6 +5407,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
#if WASM_ENABLE_PERF_PROFILING != 0 || WASM_ENABLE_DUMP_CALL_STACK != 0 \
|| WASM_ENABLE_AOT_STACK_FRAME != 0
option.enable_aux_stack_frame = true;
memset(&option.call_stack_features, 1, sizeof(AOTCallStackFeatures));
#endif
#if WASM_ENABLE_PERF_PROFILING != 0
option.enable_perf_profiling = true;

View File

@ -2149,6 +2149,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
#if WASM_ENABLE_PERF_PROFILING != 0 || WASM_ENABLE_DUMP_CALL_STACK != 0 \
|| WASM_ENABLE_AOT_STACK_FRAME != 0
option.enable_aux_stack_frame = true;
memset(&option.call_stack_features, 1, sizeof(AOTCallStackFeatures));
#endif
#if WASM_ENABLE_PERF_PROFILING != 0
option.enable_perf_profiling = true;