aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-dom.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2015-09-30 14:28:14 -0600
committerJeff Law <law@gcc.gnu.org>2015-09-30 14:28:14 -0600
commitd64f8dd280e6d2d70aec5b133e913b1af51832d9 (patch)
tree8a5d0ddc85f0e869a286b391f3deb283fd6db817 /gcc/tree-ssa-dom.c
parent9702ee6a6f2086fffd543cdb785d0caac05e7fcc (diff)
downloadgcc-d64f8dd280e6d2d70aec5b133e913b1af51832d9.zip
gcc-d64f8dd280e6d2d70aec5b133e913b1af51832d9.tar.gz
gcc-d64f8dd280e6d2d70aec5b133e913b1af51832d9.tar.bz2
[PATCH] Improve DOM's optimization of control statements
* tree-ssa-dom.c (optimize_stmt): Collapse control flow statements with constant conditions. * tree-ssa-threadupdate.c (remove_jump_threads_starting_at): New. (remove_ctrl_stmt_and_useless_edges): No longer static. * tree-ssa-threadupdate.h (remove_jump_threads_starting_at): Prototype. (remove_ctrl_stmt_and_useless_edges): Likewise. * gcc.dg/tree-ssa/ssa-dom-branch-1.c: New test. From-SVN: r228306
Diffstat (limited to 'gcc/tree-ssa-dom.c')
-rw-r--r--gcc/tree-ssa-dom.c50
1 files changed, 23 insertions, 27 deletions
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 2c51e36..a8b7038 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1820,31 +1820,8 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si,
if (is_gimple_assign (stmt))
record_equivalences_from_stmt (stmt, may_optimize_p, avail_exprs_stack);
- /* If STMT is a COND_EXPR and it was modified, then we may know
- where it goes. If that is the case, then mark the CFG as altered.
-
- This will cause us to later call remove_unreachable_blocks and
- cleanup_tree_cfg when it is safe to do so. It is not safe to
- clean things up here since removal of edges and such can trigger
- the removal of PHI nodes, which in turn can release SSA_NAMEs to
- the manager.
-
- That's all fine and good, except that once SSA_NAMEs are released
- to the manager, we must not call create_ssa_name until all references
- to released SSA_NAMEs have been eliminated.
-
- All references to the deleted SSA_NAMEs can not be eliminated until
- we remove unreachable blocks.
-
- We can not remove unreachable blocks until after we have completed
- any queued jump threading.
-
- We can not complete any queued jump threads until we have taken
- appropriate variables out of SSA form. Taking variables out of
- SSA form can call create_ssa_name and thus we lose.
-
- Ultimately I suspect we're going to need to change the interface
- into the SSA_NAME manager. */
+ /* If STMT is a COND_EXPR or SWITCH_EXPR and it was modified, then we may
+ know where it goes. */
if (gimple_modified_p (stmt) || modified_p)
{
tree val = NULL;
@@ -1858,8 +1835,27 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si,
else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
val = gimple_switch_index (swtch_stmt);
- if (val && TREE_CODE (val) == INTEGER_CST && find_taken_edge (bb, val))
- cfg_altered = true;
+ if (val && TREE_CODE (val) == INTEGER_CST)
+ {
+ edge taken_edge = find_taken_edge (bb, val);
+ if (taken_edge)
+ {
+ /* Delete threads that start at BB. */
+ remove_jump_threads_starting_at (bb);
+
+ /* Now clean up the control statement at the end of
+ BB and remove unexecutable edges. */
+ remove_ctrl_stmt_and_useless_edges (bb, taken_edge->dest);
+
+ /* Fixup the flags on the single remaining edge. */
+ taken_edge->flags
+ &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE | EDGE_ABNORMAL);
+ taken_edge->flags |= EDGE_FALLTHRU;
+
+ /* Further simplifications may be possible. */
+ cfg_altered = true;
+ }
+ }
/* If we simplified a statement in such a way as to be shown that it
cannot trap, update the eh information and the cfg to match. */