aboutsummaryrefslogtreecommitdiff
path: root/gcc/domwalk.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-04-01 11:36:25 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-04-01 11:36:25 +0000
commite37240b0b556c2bcdf94b0a84ff798cd4bd5a316 (patch)
treec0f105af1a80974454d81ff0d3c560467a115568 /gcc/domwalk.c
parent90f1430589e2f3efa8136346615fc08edfd936f3 (diff)
downloadgcc-e37240b0b556c2bcdf94b0a84ff798cd4bd5a316.zip
gcc-e37240b0b556c2bcdf94b0a84ff798cd4bd5a316.tar.gz
gcc-e37240b0b556c2bcdf94b0a84ff798cd4bd5a316.tar.bz2
re PR tree-optimization/46590 (long compile time with -O2 and many loops)
2019-04-01 Richard Biener <rguenther@suse.de> PR tree-optimization/46590 * domwalk.h (dom_walker::dom_walker): Consolidate constructors. (dom_walker::m_reachability): Add in place of... (dom_walker::m_skip_unreachable_blocks): ...this. * domwalk.c (dom_walker::dom_walker): Consoliate constructors. Move complex initialization ... (dom_walker::walk): Here. Especially compute m_bb_to_rpo lazily and initialize edge flags on each invocation. (dom_walker::bb_reachable): Use m_reachability. From-SVN: r270055
Diffstat (limited to 'gcc/domwalk.c')
-rw-r--r--gcc/domwalk.c81
1 files changed, 20 insertions, 61 deletions
diff --git a/gcc/domwalk.c b/gcc/domwalk.c
index 3849eed..8c0fdec 100644
--- a/gcc/domwalk.c
+++ b/gcc/domwalk.c
@@ -190,69 +190,11 @@ dom_walker::dom_walker (cdi_direction direction,
enum reachability reachability,
int *bb_index_to_rpo)
: m_dom_direction (direction),
- m_skip_unreachable_blocks (reachability != ALL_BLOCKS),
- m_user_bb_to_rpo (true),
+ m_reachability (reachability),
+ m_user_bb_to_rpo (bb_index_to_rpo != NULL),
m_unreachable_dom (NULL),
m_bb_to_rpo (bb_index_to_rpo)
{
- /* Set up edge flags if need be. */
- switch (reachability)
- {
- default:
- gcc_unreachable ();
- case ALL_BLOCKS:
- /* No need to touch edge flags. */
- break;
-
- case REACHABLE_BLOCKS:
- set_all_edges_as_executable (cfun);
- break;
-
- case REACHABLE_BLOCKS_PRESERVING_FLAGS:
- /* Preserve the edge flags. */
- break;
- }
-}
-
-/* Constructor for a dom walker. */
-
-dom_walker::dom_walker (cdi_direction direction,
- enum reachability reachability)
- : m_dom_direction (direction),
- m_skip_unreachable_blocks (reachability != ALL_BLOCKS),
- m_user_bb_to_rpo (false),
- m_unreachable_dom (NULL),
- m_bb_to_rpo (NULL)
-{
- /* Compute the basic-block index to RPO mapping. */
- if (direction == CDI_DOMINATORS)
- {
- int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
- int postorder_num = pre_and_rev_post_order_compute (NULL, postorder,
- true);
- m_bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (cfun));
- for (int i = 0; i < postorder_num; ++i)
- m_bb_to_rpo[postorder[i]] = i;
- free (postorder);
- }
-
- /* Set up edge flags if need be. */
- switch (reachability)
- {
- default:
- gcc_unreachable ();
- case ALL_BLOCKS:
- /* No need to touch edge flags. */
- break;
-
- case REACHABLE_BLOCKS:
- set_all_edges_as_executable (cfun);
- break;
-
- case REACHABLE_BLOCKS_PRESERVING_FLAGS:
- /* Preserve the edge flags. */
- break;
- }
}
/* Destructor. */
@@ -270,7 +212,7 @@ dom_walker::bb_reachable (struct function *fun, basic_block bb)
{
/* If we're not skipping unreachable blocks, then assume everything
is reachable. */
- if (!m_skip_unreachable_blocks)
+ if (m_reachability == ALL_BLOCKS)
return true;
/* If any of the predecessor edges that do not come from blocks dominated
@@ -331,6 +273,23 @@ const edge dom_walker::STOP = (edge)-1;
void
dom_walker::walk (basic_block bb)
{
+ /* Compute the basic-block index to RPO mapping lazily. */
+ if (!m_bb_to_rpo
+ && m_dom_direction == CDI_DOMINATORS)
+ {
+ int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
+ int postorder_num = pre_and_rev_post_order_compute (NULL, postorder,
+ true);
+ m_bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (cfun));
+ for (int i = 0; i < postorder_num; ++i)
+ m_bb_to_rpo[postorder[i]] = i;
+ free (postorder);
+ }
+
+ /* Set up edge flags if need be. */
+ if (m_reachability == REACHABLE_BLOCKS)
+ set_all_edges_as_executable (cfun);
+
basic_block dest;
basic_block *worklist = XNEWVEC (basic_block,
n_basic_blocks_for_fn (cfun) * 2);