> On 4 Aug 2026, at 06:56, Jeffrey Law <[email protected]> wrote: > > > > 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). >
Yes. The normal region and EBB schedulers do not usually create pseudos during dependency analysis, so a nonempty pool should rarely need to be drained. Before reload, max_reg_num() is monotonic. After reload, the size is always FIRST_PSEUDO_REGISTER. Also, sched_deps_finish() clears the pool between scheduling passes. Therefore, a size mismatch with a nonempty pool can only mean that max_reg increased and the existing vectors are too small. Selective scheduling can request an older, smaller size from a lazy dependency context, but it never returns arrays to this pool. Its free loop is therefore empty. SMS creates pseudos only after it has built all dependency graphs. > Assuming those are correct, then this is OK for the trunk. Thanks for the reviews! I’ll push to trunk shortly Kyrill > > > jeff
