On 6/16/26 5:09 AM, Hongyu Wang wrote:
With x86-64 APX EGPR the caller-saved GPRs grow from 9 to 25 while
callee-saved stays at 6 (rbx, rbp, r12-r15). The inflated register
file causes IRA's low_pressure_loop_node_p to be false, so more loops
been flattened and no region splitting since overall register pressure
appears low with total regnum increased.
But for a loop with indirect calls, without per-loop region splitting,
allocnos that live across those indirect calls could get assigned with
caller-saved registers due to more allocnos became live across the call,
which creates near-call spills.
The example extracted from phoronix tachyon is like below, with -mapxf
movq %rax, 32(%rsp)
call *(%rdx)
movq 32(%rsp), %rax
movq 8(%rax), %rax ;->base pointer assigned with caller-saved
For the non-apx whose low_pressure_loop_pressure_p is marked true,
the code is
call *%rax
movq 8(%rbx), %rbx ;->base pointer assigned with callee-saved
The spill-call-reload-deref sequence on the critical chain introduces
extra latency at the use site, which brings about 7% regression.
This series introduces TARGET_IRA_LOW_PRESSURE_LOOP_P so that a target
can override the low-pressure decision for specific loops. The x86
backend implementation returns false for loops containing indirect calls
when APX EGPR is active, keeping such loops as separate IRA regions.
This ensures the critical-chain allocnos still receive callee-saved
registers and eliminates the hot-path reload penalty.
Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}. The tachyon
regression can be totally fixed.
This is a RFC as there could be better solution, but we've tried
serveral changes like cost-adjusting and found there's no impact to the
final RA decision, so we have to introduce a hook. The testcase to
reproduce the issue is in the second patch.
Appreciated for any comments.
Thank you for finding the problem and proposing the solution.
I'd rather avoid introducing new hooks, there are too many of them.
Also I don't understand why the hook pays attention only to indirect
call presence. It probably solves phoronix benchmark performance issue
but it did not solve a general problem. So the hook itself is just
papering over the problem.
It is a common problem for many targets, simply it became critical and
visible for EGPR x86_64. So the solution should be common too even if
it requires more work. We could calculate register pressure for pseudos
(of given register pressure class) crossing calls in the region. If it
is more than callee-saved regs in the class, create a region.
Sorry, I can not approve solution proposed by the patch. But I'll be
happy to approve patch solving problem in the general way as I wrote.
Hongyu Wang (2):
ira: Add TARGET_IRA_LOW_PRESSURE_LOOP_P target hook
i386: Implement TARGET_IRA_LOW_PRESSURE_LOOP_P for APX EGPR
gcc/config/i386/i386.cc | 40 ++++++++
gcc/doc/tm.texi | 13 +++
gcc/doc/tm.texi.in | 2 +
gcc/ira-build.cc | 5 +
gcc/target.def | 17 ++++
gcc/targhooks.cc | 6 ++
gcc/targhooks.h | 1 +
.../i386/apx-ira-loop-indirect-call.c | 91 +++++++++++++++++++
8 files changed, 175 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/i386/apx-ira-loop-indirect-call.c