aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-08-26 13:21:57 +0200
committerRichard Biener <rguenth@gcc.gnu.org>2024-08-26 14:42:16 +0200
commit03b802e14f497e393e6437b7df5be1c690ddf1df (patch)
tree95a78d587b7262b5c2c41d7f81a4af75859f6143 /gcc
parentd3e71b99194bff878d3bf3b35f9528a350d10df9 (diff)
downloadgcc-03b802e14f497e393e6437b7df5be1c690ddf1df.zip
gcc-03b802e14f497e393e6437b7df5be1c690ddf1df.tar.gz
gcc-03b802e14f497e393e6437b7df5be1c690ddf1df.tar.bz2
Delay edge removal in forwprop
SSA forwprop has switch simplification code that calls remove edge and as side-effect releases dominator info. For a followup we want to retain that so the following delays removing edges until the end of the pass. As usual we have to deal with parts of the edge vanishing due to EH/abnormal pruning so record edges as basic-block index pairs and remove them only when they are still there. * tree-ssa-forwprop.cc (simplify_gimple_switch_label_vec): Delay removing edges and releasing dominator info, instead record into edges_to_remove vector. (simplify_gimple_switch): Pass through vector of to remove edges. (pass_forwprop::execute): Likewise. Remove queued edges.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/tree-ssa-forwprop.cc34
1 files changed, 25 insertions, 9 deletions
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 9595555..e7342b4 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -972,7 +972,8 @@ forward_propagate_addr_expr (tree name, tree rhs, bool parent_single_use_p)
have values outside the range of the new type. */
static void
-simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type)
+simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type,
+ vec<std::pair<int, int> > &edges_to_remove)
{
unsigned int branch_num = gimple_switch_num_labels (stmt);
auto_vec<tree> labels (branch_num);
@@ -1026,11 +1027,8 @@ simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type)
for (ei = ei_start (gimple_bb (stmt)->succs); (e = ei_safe_edge (ei)); )
{
if (! bitmap_bit_p (target_blocks, e->dest->index))
- {
- remove_edge (e);
- cfg_changed = true;
- free_dominance_info (CDI_DOMINATORS);
- }
+ edges_to_remove.safe_push (std::make_pair (e->src->index,
+ e->dest->index));
else
ei_next (&ei);
}
@@ -1042,7 +1040,8 @@ simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type)
the condition which we may be able to optimize better. */
static bool
-simplify_gimple_switch (gswitch *stmt)
+simplify_gimple_switch (gswitch *stmt,
+ vec<std::pair<int, int> > &edges_to_remove)
{
/* The optimization that we really care about is removing unnecessary
casts. That will let us do much better in propagating the inferred
@@ -1078,7 +1077,8 @@ simplify_gimple_switch (gswitch *stmt)
&& (!max || int_fits_type_p (max, ti)))
{
gimple_switch_set_index (stmt, def);
- simplify_gimple_switch_label_vec (stmt, ti);
+ simplify_gimple_switch_label_vec (stmt, ti,
+ edges_to_remove);
update_stmt (stmt);
return true;
}
@@ -3518,6 +3518,7 @@ pass_forwprop::execute (function *fun)
|= EDGE_EXECUTABLE;
auto_vec<gimple *, 4> to_fixup;
auto_vec<gimple *, 32> to_remove;
+ auto_vec<std::pair<int, int>, 10> edges_to_remove;
auto_bitmap simple_dce_worklist;
auto_bitmap need_ab_cleanup;
to_purge = BITMAP_ALLOC (NULL);
@@ -4024,7 +4025,8 @@ pass_forwprop::execute (function *fun)
}
case GIMPLE_SWITCH:
- changed = simplify_gimple_switch (as_a <gswitch *> (stmt));
+ changed = simplify_gimple_switch (as_a <gswitch *> (stmt),
+ edges_to_remove);
break;
case GIMPLE_COND:
@@ -4173,6 +4175,20 @@ pass_forwprop::execute (function *fun)
cfg_changed |= gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);
BITMAP_FREE (to_purge);
+ /* Remove edges queued from switch stmt simplification. */
+ for (auto ep : edges_to_remove)
+ {
+ basic_block src = BASIC_BLOCK_FOR_FN (fun, ep.first);
+ basic_block dest = BASIC_BLOCK_FOR_FN (fun, ep.second);
+ edge e;
+ if (src && dest && (e = find_edge (src, dest)))
+ {
+ free_dominance_info (CDI_DOMINATORS);
+ remove_edge (e);
+ cfg_changed = true;
+ }
+ }
+
if (get_range_query (fun) != get_global_range_query ())
disable_ranger (fun);