Skip to content

Commit 6f97822

Browse files
authored
Add wamrc parameter to configure stack frame features (bytecodealliance#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. bytecodealliance#3758
1 parent b4380fb commit 6f97822

File tree

9 files changed

+127
-19
lines changed

9 files changed

+127
-19
lines changed

core/iwasm/compilation/aot_compiler.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,10 @@ aot_gen_commit_values(AOTCompFrame *frame)
337337
LLVMValueRef value;
338338
uint32 n;
339339

340+
if (!frame->comp_ctx->call_stack_features.values) {
341+
return true;
342+
}
343+
340344
/* First, commit reference flags
341345
* For LLVM JIT, iterate all local and stack ref flags
342346
* 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)
629633
offset_sp = offsetof(WASMInterpFrame, sp);
630634
}
631635

632-
if (commit_ip) {
636+
if (commit_ip && comp_ctx->call_stack_features.ip) {
633637
if (!comp_ctx->is_jit_mode) {
634638
WASMModule *module = comp_ctx->comp_data->wasm_module;
635639
if (is_64bit)
@@ -654,7 +658,7 @@ aot_gen_commit_sp_ip(AOTCompFrame *frame, bool commit_sp, bool commit_ip)
654658
}
655659
}
656660

657-
if (commit_sp) {
661+
if (commit_sp && comp_ctx->call_stack_features.values) {
658662
n = (uint32)(sp - frame->lp);
659663
value = I32_CONST(offset_of_local(comp_ctx, n));
660664
if (!value) {

core/iwasm/compilation/aot_emit_exception.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
4141
return false;
4242
}
4343

44-
if (comp_ctx->aot_frame) {
44+
if (comp_ctx->aot_frame && comp_ctx->call_stack_features.trap_ip) {
4545
/* Create exception ip phi */
4646
if (!(func_ctx->exception_ip_phi = LLVMBuildPhi(
4747
comp_ctx->builder, is_64bit ? I64_TYPE : I32_TYPE,
@@ -134,7 +134,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
134134
/* Add phi incoming value to got_exception block */
135135
LLVMAddIncoming(func_ctx->exception_id_phi, &exce_id, &block_curr, 1);
136136

137-
if (comp_ctx->aot_frame) {
137+
if (comp_ctx->aot_frame && comp_ctx->call_stack_features.trap_ip) {
138138
const uint8 *ip = comp_ctx->aot_frame->frame_ip;
139139
LLVMValueRef exce_ip = NULL;
140140

core/iwasm/compilation/aot_emit_function.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -682,24 +682,29 @@ alloc_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
682682

683683
new_frame = wasm_stack_top;
684684

685-
if (!(check_wasm_stack_succ = LLVMAppendBasicBlockInContext(
686-
comp_ctx->context, func_ctx->func, "check_wasm_stack_succ"))) {
687-
aot_set_last_error("llvm add basic block failed.");
688-
return false;
689-
}
685+
if (comp_ctx->call_stack_features.bounds_checks) {
686+
if (!(check_wasm_stack_succ = LLVMAppendBasicBlockInContext(
687+
comp_ctx->context, func_ctx->func,
688+
"check_wasm_stack_succ"))) {
689+
aot_set_last_error("llvm add basic block failed.");
690+
return false;
691+
}
690692

691-
LLVMMoveBasicBlockAfter(check_wasm_stack_succ,
692-
LLVMGetInsertBlock(comp_ctx->builder));
693+
LLVMMoveBasicBlockAfter(check_wasm_stack_succ,
694+
LLVMGetInsertBlock(comp_ctx->builder));
693695

694-
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT, wasm_stack_top_max,
695-
wasm_stack_top_bound, "cmp"))) {
696-
aot_set_last_error("llvm build icmp failed");
697-
return false;
698-
}
696+
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT,
697+
wasm_stack_top_max, wasm_stack_top_bound,
698+
"cmp"))) {
699+
aot_set_last_error("llvm build icmp failed");
700+
return false;
701+
}
699702

700-
if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_OPERAND_STACK_OVERFLOW,
701-
true, cmp, check_wasm_stack_succ))) {
702-
return false;
703+
if (!(aot_emit_exception(comp_ctx, func_ctx,
704+
EXCE_OPERAND_STACK_OVERFLOW, true, cmp,
705+
check_wasm_stack_succ))) {
706+
return false;
707+
}
703708
}
704709

705710
#if WASM_ENABLE_GC != 0
@@ -1285,6 +1290,10 @@ commit_params_to_frame_of_import_func(AOTCompContext *comp_ctx,
12851290
{
12861291
uint32 i, n;
12871292

1293+
if (!comp_ctx->call_stack_features.values) {
1294+
return true;
1295+
}
1296+
12881297
for (i = 0, n = 0; i < func_type->param_count; i++, n++) {
12891298
switch (func_type->types[i]) {
12901299
case VALUE_TYPE_I32:

core/iwasm/compilation/aot_llvm.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2580,6 +2580,8 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
25802580
if (option->enable_aux_stack_frame)
25812581
comp_ctx->enable_aux_stack_frame = true;
25822582

2583+
comp_ctx->call_stack_features = option->call_stack_features;
2584+
25832585
if (option->enable_perf_profiling)
25842586
comp_ctx->enable_perf_profiling = true;
25852587

core/iwasm/compilation/aot_llvm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,9 @@ typedef struct AOTCompContext {
412412
/* Generate auxiliary stack frame */
413413
bool enable_aux_stack_frame;
414414

415+
/* Auxiliary call stack features */
416+
AOTCallStackFeatures call_stack_features;
417+
415418
/* Function performance profiling */
416419
bool enable_perf_profiling;
417420

core/iwasm/include/aot_comp_option.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@
66
#ifndef __AOT_COMP_OPTION_H__
77
#define __AOT_COMP_OPTION_H__
88

9+
typedef struct {
10+
/* Enables or disables bounds checks for stack frames. When enabled, the AOT
11+
* compiler generates code to check if the stack pointer is within the
12+
* bounds of the current stack frame (and if not, traps). */
13+
bool bounds_checks;
14+
15+
/* Enables or disables instruction pointer (IP) tracking.*/
16+
bool ip;
17+
18+
/* Enables or disables tracking instruction pointer of a trap. Only takes
19+
* effect when `ip` is enabled.*/
20+
bool trap_ip;
21+
22+
/* Enables or disables parameters, locals and stack operands. */
23+
bool values;
24+
} AOTCallStackFeatures;
25+
926
typedef struct AOTCompOption {
1027
bool is_jit_mode;
1128
bool is_indirect_mode;
@@ -22,6 +39,7 @@ typedef struct AOTCompOption {
2239
bool enable_gc;
2340
bool enable_aux_stack_check;
2441
bool enable_aux_stack_frame;
42+
AOTCallStackFeatures call_stack_features;
2543
bool enable_perf_profiling;
2644
bool enable_memory_profiling;
2745
bool disable_llvm_intrinsics;

core/iwasm/interpreter/wasm_loader.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5407,6 +5407,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
54075407
#if WASM_ENABLE_PERF_PROFILING != 0 || WASM_ENABLE_DUMP_CALL_STACK != 0 \
54085408
|| WASM_ENABLE_AOT_STACK_FRAME != 0
54095409
option.enable_aux_stack_frame = true;
5410+
memset(&option.call_stack_features, 1, sizeof(AOTCallStackFeatures));
54105411
#endif
54115412
#if WASM_ENABLE_PERF_PROFILING != 0
54125413
option.enable_perf_profiling = true;

core/iwasm/interpreter/wasm_mini_loader.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,6 +2149,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
21492149
#if WASM_ENABLE_PERF_PROFILING != 0 || WASM_ENABLE_DUMP_CALL_STACK != 0 \
21502150
|| WASM_ENABLE_AOT_STACK_FRAME != 0
21512151
option.enable_aux_stack_frame = true;
2152+
memset(&option.call_stack_features, 1, sizeof(AOTCallStackFeatures));
21522153
#endif
21532154
#if WASM_ENABLE_PERF_PROFILING != 0
21542155
option.enable_perf_profiling = true;

wamr-compiler/main.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@ print_help()
162162
printf(" GC is enabled\n");
163163
printf(" --disable-aux-stack-check Disable auxiliary stack overflow/underflow check\n");
164164
printf(" --enable-dump-call-stack Enable stack trace feature\n");
165+
printf(" --call-stack-features=<features>\n");
166+
printf(" A comma-separated list of features when generating call stacks.\n");
167+
printf(" By default, all features are enabled. To disable all features,\n");
168+
printf(" provide an empty list (i.e. --call-stack-features=). This flag\n");
169+
printf(" only only takes effect when --enable-dump-call-stack is set.\n");
170+
printf(" Available features: bounds-checks, ip, trap-ip, values.\n");
165171
printf(" --enable-perf-profiling Enable function performance profiling\n");
166172
printf(" --enable-memory-profiling Enable memory usage profiling\n");
167173
printf(" --xip A shorthand of --enable-indirect-mode --disable-llvm-intrinsics\n");
@@ -259,6 +265,48 @@ split_string(char *str, int *count, const char *delimer)
259265
return res;
260266
}
261267

268+
static bool
269+
parse_call_stack_features(char *features_str,
270+
AOTCallStackFeatures *out_features)
271+
{
272+
int size = 0;
273+
char **features;
274+
bool ret = true;
275+
276+
bh_assert(features_str);
277+
bh_assert(out_features);
278+
279+
/* non-empty feature list */
280+
features = split_string(features_str, &size, ",");
281+
if (!features) {
282+
return false;
283+
}
284+
285+
while (size--) {
286+
if (!strcmp(features[size], "bounds-checks")) {
287+
out_features->bounds_checks = true;
288+
}
289+
else if (!strcmp(features[size], "ip")) {
290+
out_features->ip = true;
291+
}
292+
else if (!strcmp(features[size], "trap-ip")) {
293+
out_features->trap_ip = true;
294+
}
295+
else if (!strcmp(features[size], "values")) {
296+
out_features->values = true;
297+
}
298+
else {
299+
ret = false;
300+
printf("Unsupported feature %s\n", features[size]);
301+
goto finish;
302+
}
303+
}
304+
305+
finish:
306+
free(features);
307+
return ret;
308+
}
309+
262310
static uint32
263311
resolve_segue_flags(char *str_flags)
264312
{
@@ -356,6 +404,9 @@ main(int argc, char *argv[])
356404
option.enable_ref_types = true;
357405
option.enable_gc = false;
358406

407+
/* Set all the features to true by default */
408+
memset(&option.call_stack_features, 1, sizeof(AOTCallStackFeatures));
409+
359410
/* Process options */
360411
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
361412
if (!strcmp(argv[0], "-o")) {
@@ -470,6 +521,19 @@ main(int argc, char *argv[])
470521
else if (!strcmp(argv[0], "--enable-dump-call-stack")) {
471522
option.enable_aux_stack_frame = true;
472523
}
524+
else if (!strncmp(argv[0], "--call-stack-features=", 22)) {
525+
/* Reset all the features, only enable the user-defined ones */
526+
memset(&option.call_stack_features, 0,
527+
sizeof(AOTCallStackFeatures));
528+
529+
if (argv[0][22] != '\0') {
530+
if (!parse_call_stack_features(argv[0] + 22,
531+
&option.call_stack_features)) {
532+
printf("Failed to parse call-stack-features\n");
533+
PRINT_HELP_AND_EXIT();
534+
}
535+
}
536+
}
473537
else if (!strcmp(argv[0], "--enable-perf-profiling")) {
474538
option.enable_aux_stack_frame = true;
475539
option.enable_perf_profiling = true;
@@ -608,6 +672,12 @@ main(int argc, char *argv[])
608672
#endif
609673
}
610674

675+
if (option.enable_gc && !option.call_stack_features.values) {
676+
LOG_WARNING("Call stack feature 'values' must be enabled for GC. The "
677+
"feature will be enabled automatically.");
678+
option.call_stack_features.values = true;
679+
}
680+
611681
if (sgx_mode) {
612682
option.size_level = 1;
613683
option.is_sgx_platform = true;

0 commit comments

Comments
 (0)