From 2e097cec409182c3cb39b74489387480bf8a278f Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Sat, 22 Aug 2026 22:27:33 +0200 Subject: optimize main state machine transitions with tail calls * On newer GCC (>= 15) and Clang (>= 13) versions we can tail call at the end of input_cb() implementations to the next state's input_cb(), which will be optimized to jumps (often direct jumps). That is, the compilers always optimized tail calls, but we can guarantee tail calls with the __attribute__((musttail)) statement attribute. * Every `return &teco_state_xxx` has to be replaced with `TECO_RETURN(ctx, &teco_state_xxx, error)`. * This speeds up `-O2 -flto` builds by 18% (e.g. tested on grosciteco for sciteco(7)). Part of the speed up could also be because of inlining through TECO_RETURN(). * The other state machines (stringbuilding and q-reg spec) cannot currently be optimized the same way since they get their characters passed in from the "main" state machine. * All loops around callbacks could be optimized the same way. E.g. the undo token runner could also tail call into the next runner, but it's probably not important to optimize undo token executions. --- src/stdio-commands.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/stdio-commands.c') diff --git a/src/stdio-commands.c b/src/stdio-commands.c index 34179c3..94da3c7 100644 --- a/src/stdio-commands.c +++ b/src/stdio-commands.c @@ -139,7 +139,7 @@ static teco_state_t * teco_state_print_decimal_input(teco_machine_main_t *ctx, gunichar chr, GError **error) { if (chr == '=') - return &teco_state_print_octal; + TECO_RETURN(ctx, &teco_state_print_octal, error); if (ctx->flags.mode == TECO_MODE_NORMAL) { if (G_LIKELY(!is_executing) && !teco_print(ctx, 10, error)) @@ -197,7 +197,7 @@ teco_state_print_octal_input(teco_machine_main_t *ctx, gunichar chr, GError **er return NULL; teco_expressions_pop_num(0); } - return &teco_state_start; + TECO_RETURN(ctx, &teco_state_start, error); } if (ctx->flags.mode == TECO_MODE_NORMAL) { -- cgit v1.2.3