On 7/30/2026 9:28 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>
The region scheduler initializes one deps_desc for each basic block in a
region. Each initialization allocates and zeroes max_reg deps_reg entries.
The total allocation and zeroing work is
O (max_reg * sum (RGN_NR_BLOCKS (region))).
Before reload, max_reg is max_reg_num (). This work can therefore grow
quadratically with function size.
free_deps now empties each entry that was written. Keep these all-zero
arrays in a pool keyed by max_reg and reuse them in later regions. Reset
the list length fields before returning an array. Under -fchecking=2,
verify that every field is zero. Drain the pool in sched_deps_finish.
Selective scheduling does not return arrays to the pool because
remove_from_deps can leave an untracked control-use list.
Add a selftest that fills every list field and both length fields. It
verifies that free_deps returns the same array through the pool with all
fields cleared. Also add a compile test that drives a debug-only use
through pool release and reuse under -fchecking=2. Disabling the pool makes
the selftest fail. Dropping the reg_last_dirty recording from patch 2 makes
the compile test ICE.
On an aarch64 system, I saw a ~1.5% improvement in compile speed of
gimple-match-6 at -O3.
Generated assembly doesn't change.
Bootstrapped and tested on aarch64-none-linux-gnu and x86_64-linux.
gcc/ChangeLog:
* sched-deps.cc (reg_last_pool, reg_last_pool_max_reg): New.
(alloc_reg_last, release_reg_last): New.
(init_deps, init_deps_reg_last): Use alloc_reg_last.
(free_deps): Reset the list length fields and release reg_last to the
pool.
(sched_deps_finish): Release the pooled arrays.
(selftest::test_reg_last_pool): New.
(selftest::sched_deps_cc_tests): Run it.
gcc/testsuite/ChangeLog:
* gcc.dg/sched-deps-debug-1.c: New test.
Signed-off-by: Kyrylo Tkachov <[email protected]>
OK. Presumably it's relatively rare to see new pseudos created at this
point in scheduling, so it should be rare to trigger that free loop in
alloc_reg_last? And presumably any time max_reg !=
reg_last_pool_max_reg max_reg is going to be larger (ie we need a bigger
vector and can't reuse an existing vector).
Assuming those are correct, then this is OK for the trunk.
jeff