aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-09-25 12:46:28 +0200
committerRichard Biener <rguenth@gcc.gnu.org>2024-09-25 14:23:15 +0200
commitaf8ff0047e45b95c8b7b9dd291b4978fcdf9001d (patch)
treee00e1d8faa652fbaa705785b153d7371cc2499d5 /gcc
parent9b7626383822799d60ea3c62e62e700f16337cd6 (diff)
downloadgcc-af8ff0047e45b95c8b7b9dd291b4978fcdf9001d.zip
gcc-af8ff0047e45b95c8b7b9dd291b4978fcdf9001d.tar.gz
gcc-af8ff0047e45b95c8b7b9dd291b4978fcdf9001d.tar.bz2
remove dominator recursion from reassoc
The reassoc pass currently walks dominators in a recursive way where I ran into a stack overflow with. The following replaces it with worklists following patterns used elsewhere. * tree-ssa-reassoc.cc (break_up_subtract_bb): Remove recursion. (reassociate_bb): Likewise. (do_reassoc): Implement worklist based dominator walks for both break_up_subtract_bb and reassociate_bb.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/tree-ssa-reassoc.cc45
1 files changed, 32 insertions, 13 deletions
diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc
index 70c810c..347350f 100644
--- a/gcc/tree-ssa-reassoc.cc
+++ b/gcc/tree-ssa-reassoc.cc
@@ -6346,7 +6346,6 @@ static void
break_up_subtract_bb (basic_block bb)
{
gimple_stmt_iterator gsi;
- basic_block son;
unsigned int uid = 1;
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -6378,10 +6377,6 @@ break_up_subtract_bb (basic_block bb)
&& can_reassociate_op_p (gimple_assign_rhs1 (stmt)))
plus_negates.safe_push (gimple_assign_lhs (stmt));
}
- for (son = first_dom_son (CDI_DOMINATORS, bb);
- son;
- son = next_dom_son (CDI_DOMINATORS, son))
- break_up_subtract_bb (son);
}
/* Used for repeated factor analysis. */
@@ -7007,7 +7002,6 @@ static bool
reassociate_bb (basic_block bb)
{
gimple_stmt_iterator gsi;
- basic_block son;
gimple *stmt = last_nondebug_stmt (bb);
bool cfg_cleanup_needed = false;
@@ -7270,10 +7264,6 @@ reassociate_bb (basic_block bb)
}
}
}
- for (son = first_dom_son (CDI_POST_DOMINATORS, bb);
- son;
- son = next_dom_son (CDI_POST_DOMINATORS, son))
- cfg_cleanup_needed |= reassociate_bb (son);
return cfg_cleanup_needed;
}
@@ -7382,10 +7372,39 @@ debug_ops_vector (vec<operand_entry *> ops)
/* Bubble up return status from reassociate_bb. */
static bool
-do_reassoc (void)
+do_reassoc ()
{
- break_up_subtract_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun));
- return reassociate_bb (EXIT_BLOCK_PTR_FOR_FN (cfun));
+ bool cfg_cleanup_needed = false;
+ basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
+
+ unsigned sp = 0;
+ for (auto son = first_dom_son (CDI_DOMINATORS, ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ son; son = next_dom_son (CDI_DOMINATORS, son))
+ worklist[sp++] = son;
+ while (sp)
+ {
+ basic_block bb = worklist[--sp];
+ break_up_subtract_bb (bb);
+ for (auto son = first_dom_son (CDI_DOMINATORS, bb);
+ son; son = next_dom_son (CDI_DOMINATORS, son))
+ worklist[sp++] = son;
+ }
+
+ for (auto son = first_dom_son (CDI_POST_DOMINATORS,
+ EXIT_BLOCK_PTR_FOR_FN (cfun));
+ son; son = next_dom_son (CDI_POST_DOMINATORS, son))
+ worklist[sp++] = son;
+ while (sp)
+ {
+ basic_block bb = worklist[--sp];
+ cfg_cleanup_needed |= reassociate_bb (bb);
+ for (auto son = first_dom_son (CDI_POST_DOMINATORS, bb);
+ son; son = next_dom_son (CDI_POST_DOMINATORS, son))
+ worklist[sp++] = son;
+ }
+
+ free (worklist);
+ return cfg_cleanup_needed;
}
/* Initialize the reassociation pass. */