diff options
author | Richard Biener <rguenther@suse.de> | 2024-08-06 14:56:26 +0200 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2024-08-07 09:14:21 +0200 |
commit | 2cf89ae83225f932b226cd57ef2d083a59bcf8a3 (patch) | |
tree | 857a35b6beba26d9dc69ac800ef6a8aaa1015b2b /gcc/tree-ssa-threadedge.cc | |
parent | 9db55ec0547e171eed8e7a7c50c8dad79d62fd65 (diff) | |
download | gcc-2cf89ae83225f932b226cd57ef2d083a59bcf8a3.zip gcc-2cf89ae83225f932b226cd57ef2d083a59bcf8a3.tar.gz gcc-2cf89ae83225f932b226cd57ef2d083a59bcf8a3.tar.bz2 |
tree-optimization/116166 - forward jump-threading going wild
Currently the forward threader isn't limited as to the search space
it explores and with it now using path-ranger for simplifying
conditions it runs into it became pretty slow for degenerate cases
like compiling insn-emit.cc for RISC-V esp. when compiling for
a host with LOGICAL_OP_NON_SHORT_CIRCUIT disabled.
The following makes the forward threader honor the search space
limit I introduced for the backward threader. This reduces
compile-time from minutes to seconds for the testcase in PR116166.
Note this wasn't necessary before we had ranger but with ranger
the work we do is quadatic in the length of the threading path
we build up (the same is true for the backwards threader).
PR tree-optimization/116166
* tree-ssa-threadedge.h (jump_threader::thread_around_empty_blocks):
Add limit parameter.
(jump_threader::thread_through_normal_block): Likewise.
* tree-ssa-threadedge.cc (jump_threader::thread_around_empty_blocks):
Honor and decrement limit parameter.
(jump_threader::thread_through_normal_block): Likewise.
(jump_threader::thread_across_edge): Initialize limit from
param_max_jump_thread_paths and pass it down to workers.
Diffstat (limited to 'gcc/tree-ssa-threadedge.cc')
-rw-r--r-- | gcc/tree-ssa-threadedge.cc | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc index 7f82639..0aa2aa8 100644 --- a/gcc/tree-ssa-threadedge.cc +++ b/gcc/tree-ssa-threadedge.cc @@ -786,13 +786,17 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src) bool jump_threader::thread_around_empty_blocks (vec<jump_thread_edge *> *path, edge taken_edge, - bitmap visited) + bitmap visited, unsigned &limit) { basic_block bb = taken_edge->dest; gimple_stmt_iterator gsi; gimple *stmt; tree cond; + if (limit == 0) + return false; + --limit; + /* The key property of these blocks is that they need not be duplicated when threading. Thus they cannot have visible side effects such as PHI nodes. */ @@ -830,7 +834,8 @@ jump_threader::thread_around_empty_blocks (vec<jump_thread_edge *> *path, m_registry->push_edge (path, taken_edge, EDGE_NO_COPY_SRC_BLOCK); m_state->append_path (taken_edge->dest); bitmap_set_bit (visited, taken_edge->dest->index); - return thread_around_empty_blocks (path, taken_edge, visited); + return thread_around_empty_blocks (path, taken_edge, visited, + limit); } } @@ -872,7 +877,7 @@ jump_threader::thread_around_empty_blocks (vec<jump_thread_edge *> *path, m_registry->push_edge (path, taken_edge, EDGE_NO_COPY_SRC_BLOCK); m_state->append_path (taken_edge->dest); - thread_around_empty_blocks (path, taken_edge, visited); + thread_around_empty_blocks (path, taken_edge, visited, limit); return true; } @@ -899,8 +904,13 @@ jump_threader::thread_around_empty_blocks (vec<jump_thread_edge *> *path, int jump_threader::thread_through_normal_block (vec<jump_thread_edge *> *path, - edge e, bitmap visited) + edge e, bitmap visited, + unsigned &limit) { + if (limit == 0) + return 0; + limit--; + m_state->register_equivs_edge (e); /* PHIs create temporary equivalences. @@ -989,7 +999,7 @@ jump_threader::thread_through_normal_block (vec<jump_thread_edge *> *path, visited. This may be overly conservative. */ bitmap_set_bit (visited, dest->index); bitmap_set_bit (visited, e->dest->index); - thread_around_empty_blocks (path, taken_edge, visited); + thread_around_empty_blocks (path, taken_edge, visited, limit); return 1; } } @@ -1075,9 +1085,12 @@ jump_threader::thread_across_edge (edge e) bitmap_set_bit (visited, e->src->index); bitmap_set_bit (visited, e->dest->index); + /* Limit search space. */ + unsigned limit = param_max_jump_thread_paths; + int threaded = 0; if ((e->flags & EDGE_DFS_BACK) == 0) - threaded = thread_through_normal_block (path, e, visited); + threaded = thread_through_normal_block (path, e, visited, limit); if (threaded > 0) { @@ -1148,11 +1161,12 @@ jump_threader::thread_across_edge (edge e) m_registry->push_edge (path, e, EDGE_START_JUMP_THREAD); m_registry->push_edge (path, taken_edge, EDGE_COPY_SRC_JOINER_BLOCK); - found = thread_around_empty_blocks (path, taken_edge, visited); + found = thread_around_empty_blocks (path, taken_edge, visited, limit); if (!found) found = thread_through_normal_block (path, - path->last ()->e, visited) > 0; + path->last ()->e, visited, + limit) > 0; /* If we were able to thread through a successor of E->dest, then record the jump threading opportunity. */ |