diff options
author | Jeff Law <law@redhat.com> | 2015-09-30 14:28:14 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2015-09-30 14:28:14 -0600 |
commit | d64f8dd280e6d2d70aec5b133e913b1af51832d9 (patch) | |
tree | 8a5d0ddc85f0e869a286b391f3deb283fd6db817 /gcc/tree-ssa-dom.c | |
parent | 9702ee6a6f2086fffd543cdb785d0caac05e7fcc (diff) | |
download | gcc-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.c | 50 |
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. */ |