On 9/28/26 8:15 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>
Postreload GCSE searches single-predecessor chains and replaces loads by
copies on incoming edges. It misses a fully redundant load after a join,
or when an earlier use of its destination prevents an edge copy:
bb2: r0 = [sp + K]
... paths that preserve r0 and [sp + K] ...
bb5: use (r1)
r1 = [sp + K]
Replace the last load with r1 = r0 at its original position. Select the
nearest eligible dominating occurrence, then use a backward worklist to
check memory transparency and register preservation on every path. Reuse
the existing expression table, alias analysis and register-clobber checks.
Keep partial redundancy elimination as a fallback. In cold blocks,
allow full forwarding only when it does not increase the size cost.
This removes some vector spills and reloads from video filter code
compiled with SVE that motivates this series.
A reduced SVE test covers forwarding across joins. RTL tests cover a
join with an earlier destination use, a transparent loop, and register
alias, memory overwrite, address and loop clobbers.
Bootstrapped and tested on aarch64-none-linux-gnu.
Ok for trunk?
Thanks,
Kyrill
gcc/ChangeLog:
* postreload-gcse.cc (stats): Add loads_forwarded.
(available_from_dominator_p): New function.
(replace_fully_redundant_load): Likewise.
(eliminate_partially_redundant_load): Try full forwarding before
partial elimination. Keep the cold-block gate on partial elimination.
(eliminate_partially_redundant_loads): Scan cold blocks too.
(gcse_after_reload_main): Compute dominators when needed and record
forwarded loads.
gcc/testsuite/ChangeLog:
* gcc.dg/rtl/aarch64/postreload-gcse-forward.c: New test.
* gcc.target/aarch64/sve/spill-gcse.c: New test.
Signed-off-by: Kyrylo Tkachov <[email protected]>
@@ -1002,6 +1004,101 @@ compute_expr_transp (expr **slot, FILE *dump_file
ATTRIBUTE_UNUSED)
return 1;
}
+/* Return true if REG still holds EXPR at the entry to BB after SOURCE.
+ SOURCE must dominate BB. Check every path backwards to SOURCE's block,
+ including queued edge instructions. */
Ouch. This seems like it could end up being expensive. My memory is
fuzzy on postreload-gcse, but would it be better from a compile-time
standpoint to work more like gcse/pre by computing local properties and
propagating them across the CFG? While the on-demand could be more
efficient in the common case if we only have to do a few lookups, it
could explode on us in pathological cases it seems.
So generally supportive of the idea, just concerned about the potential
for compile-time problems, particularly in pathological cases.
jeff