On 9/22/26 3:33 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>
A bytecode interpreter written with a switch at its loop head normally has one
jump-table dispatch. Every opcode transition returns to the same indirect
branch instruction. This can make indirect target prediction less effective.
The existing compgotos pass already gives each eligible predecessor its own
computed goto. Apply the same transformation to the jump-table form.
The guarded tablejump is a short chain rather than one block:
handler -> fetch and range check -> tablejump
Collect the single-predecessor fall-through chain and copy it into eligible
predecessors. The copies share the table through the representation added by
the first patch. Require a direct DFS back edge into the collected chain head
before the first tablejump duplication. This limits the new transformation
to a loop head. Recursive copies do not repeat the test. Computed gotos keep
their existing behavior.
Use the existing max-goto-duplication-insns budget. Charge the tablejump as
one unconditional-jump unit and charge every accompanying RTL instruction at
its minimum length. A zero budget rejects the transformation. Require the
target's can_share_jump_table_p hook to permit sharing and reject
partitioned functions.
Reject functions that use stack registers. Stack-register conversion can
split outgoing edges to reconcile different stack layouts, but a shared-table
edge cannot be changed for only one dispatch.
Set PROP_rtl_allow_tablejump_duplication only while the pass scans and copies
dispatches. Clear it before CFG cleanup and before any later pass runs.
Plugin tests check per-function target options, both default hook results,
existing instruction-copy vetoes, and output after eligibility becomes false.
On an AArch64 Vera system, explicit enablement improves 714.cpython_r by
10.3%, mawk by 6.9%, and QuickJS-ng by 24.9%.
gcc/ChangeLog:
PR middle-end/126236
* common.opt (fduplicate-switch-dispatch): New option.
* doc/invoke.texi: Document it.
* params.opt (max-goto-duplication-insns): Mention switch dispatches.
* bb-reorder.cc (dispatch_jump_p): New function.
(can_attach_dispatch_copy_p): New function.
(find_dispatch_chain): New function.
(maybe_duplicate_computed_goto): Rename to...
(maybe_duplicate_dispatch): ...this. Copy a dispatch chain and
optionally require a DFS back edge into its head.
(duplicate_computed_gotos): Mark DFS back edges, select eligible
tablejumps, and scope PROP_rtl_allow_tablejump_duplication.
gcc/testsuite/ChangeLog:
PR middle-end/126236
* gcc.dg/plugin/plugin.exp: Register the capability test.
* gcc.dg/plugin/tablejump_capability_plugin.cc: New plugin.
* gcc.dg/plugin/tablejump-capability.c: New test.
* gcc.dg/plugin/tablejump-test.h: New test header.
* gcc.dg/switch-dispatch-2.c: New test.
* gcc.dg/switch-dispatch-3.c: New test.
* gcc.dg/torture/switch-dispatch-run-1.c: New test.
* gcc.dg/torture/switch-dispatch-run-2.c: New test.
* gcc.dg/torture/switch-dispatch-run-3.c: New test.
* gcc.dg/torture/switch-dispatch-run-4.c: New test.
* gcc.target/aarch64/switch-dispatch-1.c: New test.
* gcc.target/aarch64/switch-dispatch-2.c: New test.
* gcc.target/aarch64/switch-dispatch-3.c: New test.
* gcc.target/aarch64/switch-dispatch-4.c: New test.
* gcc.target/aarch64/switch-dispatch-5.c: New test.
* gcc.target/aarch64/switch-dispatch-6.c: New test.
* gcc.target/aarch64/switch-dispatch-7.c: New test.
Signed-off-by: Kyrylo Tkachov <[email protected]>
So we've got an explicit opt-in. I'd tend to lean towards opt-out since
if we do this right it should work on any target except those which
implicitly assume the jump table immediately follows the jump. If we
have good tests which we strongly believe will test execution paths for
a shared table, then we can quickly evaluate how the majority of our
targets behave in my tester to catch targets we might have missed.
Targets which don't have real execution testing we can opt-out and let
the port owners know they may want to re-evaluate. The dispatch-run
tests would seem to fit the need.
It never really occurred to me, does this muck up loop structure? I
guess it's running late enough to not matter. So call it curiosity
rather than a review concern.
This is sensible. OK if and when the prereqs are approve.d
jeff