public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug tree-optimization/114557] New: ehcleanup cleanup_empty_eh_merge_phis eats a lot of memory
@ 2024-04-02  8:59 rguenth at gcc dot gnu.org
  2024-04-02  9:56 ` [Bug tree-optimization/114557] " rguenth at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-04-02  8:59 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114557

            Bug ID: 114557
           Summary: ehcleanup cleanup_empty_eh_merge_phis eats a lot of
                    memory
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org
  Target Milestone: ---

For the testcase in PR114480 we end up redirecting a lot of edges into
very high in-degree blocks.

(gdb) p new_bb->preds.m_vecpfx
$3 = {m_alloc = 4095, m_using_auto_storage = 0, m_num = 3911}

the way the edge redirection works it will resize the target PHI nodes
a lot of time, leaving the old PHIs as garbage until the next GC collection.

For the testcase this piles up to 16GB of garbage.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug tree-optimization/114557] ehcleanup cleanup_empty_eh_merge_phis eats a lot of memory
  2024-04-02  8:59 [Bug tree-optimization/114557] New: ehcleanup cleanup_empty_eh_merge_phis eats a lot of memory rguenth at gcc dot gnu.org
@ 2024-04-02  9:56 ` rguenth at gcc dot gnu.org
  2024-04-02 10:30 ` rguenth at gcc dot gnu.org
  2024-04-03  6:57 ` cvs-commit at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-04-02  9:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114557

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2024-04-02
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
The main reason is that the "large" PHI nodes are never re-used for large
allocations and that the GTY ((deletable (""))) for the free_phinodes
array doesn't seem to be effective for this testcase.

diff --git a/gcc/tree-phinodes.cc b/gcc/tree-phinodes.cc
index ddd731323e1..44dc345a3b7 100644
--- a/gcc/tree-phinodes.cc
+++ b/gcc/tree-phinodes.cc
@@ -223,6 +223,12 @@ release_phi_node (gimple *phi)
       delink_imm_use (imm);
     }

+  if (len - 2 >= NUM_BUCKETS - 2)
+    {
+      ggc_free (phi);
+      return;
+    }
+
   bucket = len > NUM_BUCKETS - 1 ? NUM_BUCKETS - 1 : len;
   bucket -= 2;
   vec_safe_push (free_phinodes[bucket], phi);

cuts memory usage to 10GB.  The free_phinodes buckets are also badly
designed - we always allocate power-of-two overall PHI node memory
through ideal_phi_node_len but have buckets for [2, ..., 10] actual
PHI nodes which likely makes us have exactly a single (maybe two)
free PHI node buckets ...

After ehcleanup (and with the above patch) we have

(gdb) p/r free_phinodes
$5 = {0x0, 0x0, 0x7ffff668e000, 0x0, 0x0, 0x0, 0x0, 0x7ffe8b3df000}

so as I said.  Two slots are used only.

(gdb) p/r (free_phinodes)[2].m_vecpfx
$7 = {m_alloc = 524287, m_using_auto_storage = 0, m_num = 265598}
(gdb) p/r (free_phinodes)[7].m_vecpfx
$8 = {m_alloc = 65535, m_using_auto_storage = 0, m_num = 59610}

After the next collection the array is actually empty:

(gdb) p/r free_phinodes
$9 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}

but memory usage doesn't shrink, likely either due to fragmentation or
due to stale references.  Maybe the 'deleteable' only gets effective
upon next collection but we do not collect anymore after hitting 10GB,
likely because we no longer expand the heap (hitting this peak is the
bug anyway).  We do re-collect in final(), but that doesn't reduce the
memory.  We do have a lot of blocks and edges and thus PHIs.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug tree-optimization/114557] ehcleanup cleanup_empty_eh_merge_phis eats a lot of memory
  2024-04-02  8:59 [Bug tree-optimization/114557] New: ehcleanup cleanup_empty_eh_merge_phis eats a lot of memory rguenth at gcc dot gnu.org
  2024-04-02  9:56 ` [Bug tree-optimization/114557] " rguenth at gcc dot gnu.org
@ 2024-04-02 10:30 ` rguenth at gcc dot gnu.org
  2024-04-03  6:57 ` cvs-commit at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-04-02 10:30 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114557

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
The free_phinodes buckets itself could better use the ->next chain of the
gimple stmts rather than a (re-allocated) GC vector.  Given the current
bucket structure a single chain for the 4-argument case might be good
enough.  Otherwise hooking into the GC special sizes array might be
worthwhile.

Note that ggc_free()ing all PHIs (and thus using the GC allocator freelist
which has its own issues) is a tiny bit faster than keeping the pool for at
least the testcase at hand.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug tree-optimization/114557] ehcleanup cleanup_empty_eh_merge_phis eats a lot of memory
  2024-04-02  8:59 [Bug tree-optimization/114557] New: ehcleanup cleanup_empty_eh_merge_phis eats a lot of memory rguenth at gcc dot gnu.org
  2024-04-02  9:56 ` [Bug tree-optimization/114557] " rguenth at gcc dot gnu.org
  2024-04-02 10:30 ` rguenth at gcc dot gnu.org
@ 2024-04-03  6:57 ` cvs-commit at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-04-03  6:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114557

--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:e7b7188b1cf8c174f0e890d4ac279ff480b51043

commit r14-9767-ge7b7188b1cf8c174f0e890d4ac279ff480b51043
Author: Richard Biener <rguenther@suse.de>
Date:   Tue Apr 2 12:31:04 2024 +0200

    tree-optimization/114557 - reduce ehcleanup peak memory use

    The following reduces peak memory use for the PR114480 testcase at -O1
    which is almost exclusively spent by the ehcleanup pass in allocating
    PHI nodes.  The free_phinodes cache we maintain isn't very effective
    since it has effectively two slots, one for 4 and one for 9 argument
    PHIs and it is only ever used for allocations up to 9 arguments but
    we put all larger PHIs in the 9 argument bucket.  This proves
    uneffective resulting in much garbage to be kept when incrementally
    growing PHI nodes by edge redirection.

    The mitigation is to rely on the GC freelist for larger sizes and
    thus immediately return all larger bucket sized PHIs to it via ggc_free.

    This reduces the peak memory use from 19.8GB to 11.3GB and compile-time
    from 359s to 168s.

            PR tree-optimization/114557
            PR tree-optimization/114480
            * tree-phinodes.cc (release_phi_node): Return PHIs from
            allocation buckets not covered by free_phinodes to GC.
            (remove_phi_node): Release the PHI LHS before freeing the
            PHI node.
            * tree-vect-loop.cc (vectorizable_live_operation): Get PHI lhs
            before releasing it.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-04-03  6:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-02  8:59 [Bug tree-optimization/114557] New: ehcleanup cleanup_empty_eh_merge_phis eats a lot of memory rguenth at gcc dot gnu.org
2024-04-02  9:56 ` [Bug tree-optimization/114557] " rguenth at gcc dot gnu.org
2024-04-02 10:30 ` rguenth at gcc dot gnu.org
2024-04-03  6:57 ` cvs-commit at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).