aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-04-02 12:31:04 +0200
committerRichard Biener <rguenther@suse.de>2024-04-03 08:56:45 +0200
commite7b7188b1cf8c174f0e890d4ac279ff480b51043 (patch)
treefa0547bbce28802c3410647f94608063d54ceed5
parent8677182f32234786fccce25583232ec5181dde75 (diff)
downloadgcc-e7b7188b1cf8c174f0e890d4ac279ff480b51043.zip
gcc-e7b7188b1cf8c174f0e890d4ac279ff480b51043.tar.gz
gcc-e7b7188b1cf8c174f0e890d4ac279ff480b51043.tar.bz2
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.
-rw-r--r--gcc/tree-phinodes.cc10
-rw-r--r--gcc/tree-vect-loop.cc2
2 files changed, 10 insertions, 2 deletions
diff --git a/gcc/tree-phinodes.cc b/gcc/tree-phinodes.cc
index ddd7313..5a7e4a9 100644
--- a/gcc/tree-phinodes.cc
+++ b/gcc/tree-phinodes.cc
@@ -223,6 +223,14 @@ release_phi_node (gimple *phi)
delink_imm_use (imm);
}
+ /* Immediately return the memory to the allocator when we would
+ only ever re-use it for a smaller size allocation. */
+ 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);
@@ -445,9 +453,9 @@ remove_phi_node (gimple_stmt_iterator *gsi, bool release_lhs_p)
/* If we are deleting the PHI node, then we should release the
SSA_NAME node so that it can be reused. */
- release_phi_node (phi);
if (release_lhs_p)
release_ssa_name (gimple_phi_result (phi));
+ release_phi_node (phi);
}
/* Remove all the phi nodes from BB. */
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index f33629e..984636e 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -10962,8 +10962,8 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info,
lhs_type, &exit_gsi);
auto gsi = gsi_for_stmt (use_stmt);
- remove_phi_node (&gsi, false);
tree lhs_phi = gimple_phi_result (use_stmt);
+ remove_phi_node (&gsi, false);
gimple *copy = gimple_build_assign (lhs_phi, new_tree);
gsi_insert_before (&exit_gsi, copy, GSI_SAME_STMT);
break;