On 8/18/2026 10:42 AM, Matt Turner wrote:
> Every indirect branch that cannot use goto_tb ends in
> tcg_gen_lookup_and_goto_ptr(), which calls helper_lookup_tb_ptr(). For an
> emulated compiler that is 8.4 billion helper calls in a single translation
> unit: 24.6% of all TB exits take this path, because jsr/ret/jmp have a
> register destination and because goto_tb is restricted to same-page
> targets.
> 
> The helper itself is already tight, but each call pays for a call frame,
> the can_do_io store, the get_tb_cpu_state() indirect call through
> TCGCPUOps, curr_cflags(), and a breakpoint check, before it gets to the
> jump cache probe that almost always hits (95.8% for this workload).
> 
> Emit the probe inline instead. The destination PC is already in a TCG
> temp, and the flags and cflags the destination must match are constants at
> translation time, so the fast path is a hash, three guarded loads and a
> goto_ptr. Only a miss calls the helper, which still owns filling the cache.
> 
> Two details matter for the generated code. The flags and cflags guards are
> folded into a single aligned 64-bit load and compare, since the fields are
> adjacent. And each path emits its own goto_ptr rather than branching to a
> shared one: a temp live across the label is spilled and reloaded on every
> dispatch, which cost 6.3% on its own.
> 
> Measured with qemu-alpha running an emulated alpha gcc 16.2.0 compiling
> the SQLite 3.45.1 amalgamation (255k lines, -O2) on an x86-64 host, LTO
> build, on top of the preceding three patches:
> 
>     before: 1,402,816,253,499 instructions
>     after:    890,713,633,237 instructions   -36.51%
> 
>     before: 115.75s wall clock
>     after:   84.44s wall clock               -27.05%
> 
> The gap between the two is the point at which this stops being a
> straight-line win: the helper call was highly predictable work that the
> host pipelined well, so removing it retires far fewer instructions than it
> saves time. IPC falls from 2.48 to 2.15 across this patch for that reason.
> 
> Despite emitting more code, this also reduces instruction cache pressure,
> because a dispatch no longer jumps into qemu's .text and evicts translated
> code:
> 
>     before: 11,476,318,964 L1-icache-load-misses
>     after:   6,990,186,701 L1-icache-load-misses   -39.1%
> 
> The mechanism is visible directly in a profile: helper_lookup_tb_ptr()
> falls from 30.97% of samples to 0.42%, and qemu's own .text falls from
> 38.9% to 5.4%, with the balance moving into generated code.
> 
> Combined with the three preceding patches, against an unmodified LTO
> build, 1,647,901,588,726 instructions fall to 890,713,633,237, or -45.95%.
> The emulated compiler produces byte-identical output throughout.
> 
> Open issues, hence RFC:
> 
> - The flags/cflags guards use the *current* TB's values as constants. That
>   assumes the CPU flags feeding get_tb_cpu_state() cannot change within a
>   TB, and that curr_cflags() cannot change under a running TB (gdb
>   attaching to enable single-step would). Both need to be established or
>   the values need to be loaded at runtime.
> - tcg/tcg-op.c has no business including accel/tcg/tb-jmp-cache.h or
>   knowing the CPUJumpCache layout. The probe likely belongs in accel/tcg
>   with a small emit helper exported from tcg/.
> - The jump cache entry is read without qatomic_read(); entries are
>   invalidated concurrently by setting tb to NULL.
> - Only wired up for alpha so far, and only for 64-bit guest PCs.
> 
> Signed-off-by: Matt Turner <[email protected]>
> ---
>  include/tcg/tcg-op-common.h |  2 +
>  target/alpha/translate.c    |  4 +-
>  tcg/tcg-op.c                | 79 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 83 insertions(+), 2 deletions(-)
> 

This change breaks following tcg test:
alpha-linux-user/gdbstub-follow-fork-mode-child

Reproduce with:
ninja -C build &&
make -C build/tests/tcg/alpha-linux-user/ &&
make -C build/tests/tcg/alpha-linux-user/ run-gdbstub-follow-fork-mode-child

Need gdb-multiarch and gcc-alpha-linux-gnu installed on your machine.

Regards,
Pierrick

Reply via email to