> On 15 Oct 2026, at 05:56, Jeff Law <[email protected]> wrote: > > > > 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. >
Yes, we can do that. We’d need to take into account: - On targets without a length attribute, get_attr_min_length returns 0. Then --param=max-goto-duplication-insns does not limit the copies, and 0 does not disable them. Computed gotos already behave like this. I would count one unit per insn on such targets. - hw-doloop (arc, bfin, c6x, xtensa) must not redirect a hardware-loop entry edge that comes from a shared table. - When every predecessor takes a copy, the original dispatch is deleted and its table can end up last in the function. alpha and ia64 look for a final call or trap with prev_active_insn, and the ia64 stop-bit code expects the insn before a table to be its jump. These must handle such a table. Or we opt these targets out initially ;) I can flesh out the tests in the next revision. > 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. There is no loop structure to update at that point. compgotos runs after the RTL loop passes have cleared PROP_loops and freed the loop tree. The handlers now dispatch to each other directly, so the dispatch loop becomes an irreducible region. Unlike computed-goto edges, tablejump edges are not abnormal, so a handler that can dispatch to itself also becomes a small natural loop. The later passes that look at loops (if_after_reload, compute_alignments and some machine reorgs) use AVOID_CFG_MODIFICATIONS. On AArch64 the exception was selective scheduling with pipelining. It tried to create preheaders for those small loops by redirecting shared-table edges. That is why patch 1 makes is_cfg_nonregular reject shared tables, and switch-dispatch-7.c covers it. Under opt-out, hw-doloop is a second case (see above). Thanks, Kyrill > > This is sensible. OK if and when the prereqs are approve.d > > jeff
