diff options
author | Jeff Law <law@redhat.com> | 2017-12-12 15:46:46 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2017-12-12 15:46:46 -0700 |
commit | df80fc5328ebafa5c33a783a32dd819271a49312 (patch) | |
tree | e41c0f11f99141ab8639d901936689c17b09a152 /gcc/tree-ssa-threadedge.c | |
parent | 708eab9b5bfdb5be44253dbac5f58cea5c652c55 (diff) | |
download | gcc-df80fc5328ebafa5c33a783a32dd819271a49312.zip gcc-df80fc5328ebafa5c33a783a32dd819271a49312.tar.gz gcc-df80fc5328ebafa5c33a783a32dd819271a49312.tar.bz2 |
re PR tree-optimization/83298 (wrong code at -O1, -O2 and -O3 on x86_64-linux-gnu)
PR tree-optimization/83298
PR tree-optimization/83362
PR tree-optimization/83383
* gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Make
push_value_range a public interface. Add new argument to
record_ranges_from_stmt.
* gimple-ssa-evrp-analyze.c
(evrp_range_analyzer::record_ranges_from_stmt): Add new argument.
Update comments. Handle recording temporary equivalences.
* tree-ssa-dom.c (dom_opt_opt_walker::before_dom_children): Add
new argument to call to evrp_range_analyzer::record_ranges_from_stmt.
* gimple-ssa-evrp.c (evrp_dom_walker::before_dom_children): Likewise.
* tree-ssa-threadedge.c: Include alloc-pool.h, vr-values.h and
gimple-ssa-evrp-analyze.h.
(record_temporary_equivalences_from_phis): Add new argument. When
the PHI arg is an SSA_NAME, set the result's range to the range
of the PHI arg.
(record_temporary_equivalences_from_stmts_at_dest): Record ranges
from statements too.
(thread_through_normal_block): Accept new argument, evrp_range_analyzer.
Pass it down to children as needed.
(thread_outgoing_edges): Likewise.
(thread_across_edge): Likewise. Push/pop range state as needed.
* tree-ssa-threadedge.h (thread_outgoing_edges): Update prototype.
PR tree-optimization/83298
PR tree-optimization/83362
PR tree-optimization/83383
* gcc.c-torture/execute/pr83298.c: New test.
* gcc.c-torture/execute/pr83362.c New test.
* gcc.c-torture/execute/pr83383.c New test.
From-SVN: r255593
Diffstat (limited to 'gcc/tree-ssa-threadedge.c')
-rw-r--r-- | gcc/tree-ssa-threadedge.c | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 91793bf..b7781dc 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -37,6 +37,9 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-dom.h" #include "gimple-fold.h" #include "cfganal.h" +#include "alloc-pool.h" +#include "vr-values.h" +#include "gimple-ssa-evrp-analyze.h" /* To avoid code explosion due to jump threading, we limit the number of statements we are going to copy. This variable @@ -114,17 +117,16 @@ potentially_threadable_block (basic_block bb) } /* Record temporary equivalences created by PHIs at the target of the - edge E. Record unwind information for the equivalences onto STACK. + edge E. Record unwind information for the equivalences into + CONST_AND_COPIES and EVRP_RANGE_DATA. If a PHI which prevents threading is encountered, then return FALSE - indicating we should not thread this edge, else return TRUE. - - If SRC_MAP/DST_MAP exist, then mark the source and destination SSA_NAMEs - of any equivalences recorded. We use this to make invalidation after - traversing back edges less painful. */ + indicating we should not thread this edge, else return TRUE. */ static bool -record_temporary_equivalences_from_phis (edge e, const_and_copies *const_and_copies) +record_temporary_equivalences_from_phis (edge e, + const_and_copies *const_and_copies, + evrp_range_analyzer *evrp_range_analyzer) { gphi_iterator gsi; @@ -152,6 +154,14 @@ record_temporary_equivalences_from_phis (edge e, const_and_copies *const_and_cop stmt_count++; const_and_copies->record_const_or_copy (dst, src); + + /* Also update the value range associated with DST, using + the range from SRC. */ + if (evrp_range_analyzer && TREE_CODE (src) == SSA_NAME) + { + value_range *vr = evrp_range_analyzer->get_value_range (src); + evrp_range_analyzer->push_value_range (dst, vr); + } } return true; } @@ -191,6 +201,7 @@ static gimple * record_temporary_equivalences_from_stmts_at_dest (edge e, const_and_copies *const_and_copies, avail_exprs_stack *avail_exprs_stack, + evrp_range_analyzer *evrp_range_analyzer, pfn_simplify simplify) { gimple *stmt = NULL; @@ -235,6 +246,11 @@ record_temporary_equivalences_from_stmts_at_dest (edge e, if (stmt_count > max_stmt_count) return NULL; + /* These are temporary ranges, do nto reflect them back into + the global range data. */ + if (evrp_range_analyzer) + evrp_range_analyzer->record_ranges_from_stmt (stmt, true); + /* If this is not a statement that sets an SSA_NAME to a new value, then do not try to simplify this statement as it will not simplify in any way that is helpful for jump threading. */ @@ -981,6 +997,7 @@ thread_through_normal_block (edge e, gcond *dummy_cond, const_and_copies *const_and_copies, avail_exprs_stack *avail_exprs_stack, + evrp_range_analyzer *evrp_range_analyzer, pfn_simplify simplify, vec<jump_thread_edge *> *path, bitmap visited) @@ -992,7 +1009,8 @@ thread_through_normal_block (edge e, Note that if we found a PHI that made the block non-threadable, then we need to bubble that up to our caller in the same manner we do when we prematurely stop processing statements below. */ - if (!record_temporary_equivalences_from_phis (e, const_and_copies)) + if (!record_temporary_equivalences_from_phis (e, const_and_copies, + evrp_range_analyzer)) return -1; /* Now walk each statement recording any context sensitive @@ -1000,6 +1018,7 @@ thread_through_normal_block (edge e, gimple *stmt = record_temporary_equivalences_from_stmts_at_dest (e, const_and_copies, avail_exprs_stack, + evrp_range_analyzer, simplify); /* There's two reasons STMT might be null, and distinguishing @@ -1114,12 +1133,15 @@ thread_across_edge (gcond *dummy_cond, edge e, class const_and_copies *const_and_copies, class avail_exprs_stack *avail_exprs_stack, + class evrp_range_analyzer *evrp_range_analyzer, pfn_simplify simplify) { bitmap visited = BITMAP_ALLOC (NULL); const_and_copies->push_marker (); avail_exprs_stack->push_marker (); + if (evrp_range_analyzer) + evrp_range_analyzer->push_marker (); stmt_count = 0; @@ -1133,6 +1155,7 @@ thread_across_edge (gcond *dummy_cond, threaded = thread_through_normal_block (e, dummy_cond, const_and_copies, avail_exprs_stack, + evrp_range_analyzer, simplify, path, visited); else @@ -1144,6 +1167,8 @@ thread_across_edge (gcond *dummy_cond, e->dest); const_and_copies->pop_to_marker (); avail_exprs_stack->pop_to_marker (); + if (evrp_range_analyzer) + evrp_range_analyzer->pop_to_marker (); BITMAP_FREE (visited); register_jump_thread (path); return; @@ -1169,6 +1194,8 @@ thread_across_edge (gcond *dummy_cond, BITMAP_FREE (visited); const_and_copies->pop_to_marker (); avail_exprs_stack->pop_to_marker (); + if (evrp_range_analyzer) + evrp_range_analyzer->pop_to_marker (); return; } } @@ -1196,6 +1223,8 @@ thread_across_edge (gcond *dummy_cond, { const_and_copies->pop_to_marker (); avail_exprs_stack->pop_to_marker (); + if (evrp_range_analyzer) + evrp_range_analyzer->pop_to_marker (); BITMAP_FREE (visited); return; } @@ -1211,6 +1240,8 @@ thread_across_edge (gcond *dummy_cond, for each of E->dest's successors. */ const_and_copies->push_marker (); avail_exprs_stack->push_marker (); + if (evrp_range_analyzer) + evrp_range_analyzer->push_marker (); /* Avoid threading to any block we have already visited. */ bitmap_clear (visited); @@ -1238,6 +1269,7 @@ thread_across_edge (gcond *dummy_cond, found = thread_through_normal_block (path->last ()->e, dummy_cond, const_and_copies, avail_exprs_stack, + evrp_range_analyzer, simplify, path, visited) > 0; @@ -1253,12 +1285,16 @@ thread_across_edge (gcond *dummy_cond, delete_jump_thread_path (path); /* And unwind the equivalence table. */ + if (evrp_range_analyzer) + evrp_range_analyzer->pop_to_marker (); avail_exprs_stack->pop_to_marker (); const_and_copies->pop_to_marker (); } BITMAP_FREE (visited); } + if (evrp_range_analyzer) + evrp_range_analyzer->pop_to_marker (); const_and_copies->pop_to_marker (); avail_exprs_stack->pop_to_marker (); } @@ -1280,6 +1316,7 @@ void thread_outgoing_edges (basic_block bb, gcond *dummy_cond, class const_and_copies *const_and_copies, class avail_exprs_stack *avail_exprs_stack, + class evrp_range_analyzer *evrp_range_analyzer, tree (*simplify) (gimple *, gimple *, class avail_exprs_stack *, basic_block)) @@ -1297,7 +1334,7 @@ thread_outgoing_edges (basic_block bb, gcond *dummy_cond, { thread_across_edge (dummy_cond, single_succ_edge (bb), const_and_copies, avail_exprs_stack, - simplify); + evrp_range_analyzer, simplify); } else if ((last = last_stmt (bb)) && gimple_code (last) == GIMPLE_COND @@ -1313,11 +1350,13 @@ thread_outgoing_edges (basic_block bb, gcond *dummy_cond, more than one predecessor and more than one successor. */ if (potentially_threadable_block (true_edge->dest)) thread_across_edge (dummy_cond, true_edge, - const_and_copies, avail_exprs_stack, simplify); + const_and_copies, avail_exprs_stack, + evrp_range_analyzer, simplify); /* Similarly for the ELSE arm. */ if (potentially_threadable_block (false_edge->dest)) thread_across_edge (dummy_cond, false_edge, - const_and_copies, avail_exprs_stack, simplify); + const_and_copies, avail_exprs_stack, + evrp_range_analyzer, simplify); } } |