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/qreg-commands.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/qreg-commands.c') diff --git a/src/qreg-commands.c b/src/qreg-commands.c index a6390a1..d7b0a10 100644 --- a/src/qreg-commands.c +++ b/src/qreg-commands.c @@ -62,7 +62,7 @@ teco_state_expectqreg_input(teco_machine_main_t *ctx, gunichar chr, GError **err case TECO_MACHINE_QREGSPEC_ERROR: return NULL; case TECO_MACHINE_QREGSPEC_MORE: - return current; + TECO_RETURN(ctx, current, error); case TECO_MACHINE_QREGSPEC_DONE: break; } @@ -72,7 +72,8 @@ teco_state_expectqreg_input(teco_machine_main_t *ctx, gunichar chr, GError **err * states. This means, it must usually be reset manually in got_register_cb() via: * teco_state_expectqreg_reset(ctx); */ - return current->expectqreg.got_register_cb(ctx, qreg, table, error); + teco_state_t *next = current->expectqreg.got_register_cb(ctx, qreg, table, error); + TECO_RETURN(ctx, next, error); } static teco_state_t * -- cgit v1.2.3