Commit 7581ce9a by Richard Biener Committed by Richard Biener

tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): Skip unreachable…

tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): Skip unreachable blocks and destinations.

2017-05-11  Richard Biener  <rguenther@suse.de>

	* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
	Skip unreachable blocks and destinations.
	(eliminate): Move stmt removal and fixup ...
	(fini_eliminate): ... here.  Skip inserted exprs.
	(pass_pre::execute): Move fini_pre after fini_eliminate.
	* tree-ssa-tailmerge.c: Include tree-cfgcleanup.h.
	(tail_merge_optimize): Run cleanup_tree_cfg if requested by
	PRE to get rid of dead code that has invalid SSA form and
	split critical edges again.

From-SVN: r247882
parent 86b001e0
2017-05-11 Richard Biener <rguenther@suse.de>
* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
Skip unreachable blocks and destinations.
(eliminate): Move stmt removal and fixup ...
(fini_eliminate): ... here. Skip inserted exprs.
(pass_pre::execute): Move fini_pre after fini_eliminate.
* tree-ssa-tailmerge.c: Include tree-cfgcleanup.h.
(tail_merge_optimize): Run cleanup_tree_cfg if requested by
PRE to get rid of dead code that has invalid SSA form and
split critical edges again.
2017-05-11 Bin Cheng <bin.cheng@arm.com> 2017-05-11 Bin Cheng <bin.cheng@arm.com>
* rtlanal.c (rtx_cost): Handle TRUNCATE between tieable modes. * rtlanal.c (rtx_cost): Handle TRUNCATE between tieable modes.
......
...@@ -4196,9 +4196,14 @@ eliminate_dom_walker::before_dom_children (basic_block b) ...@@ -4196,9 +4196,14 @@ eliminate_dom_walker::before_dom_children (basic_block b)
/* Mark new bb. */ /* Mark new bb. */
el_avail_stack.safe_push (NULL_TREE); el_avail_stack.safe_push (NULL_TREE);
/* ??? If we do nothing for unreachable blocks then this will confuse /* Skip unreachable blocks marked unreachable during the SCCVN domwalk. */
tailmerging. Eventually we can reduce its reliance on SCCVN now edge_iterator ei;
that we fully copy/constant-propagate (most) things. */ edge e;
FOR_EACH_EDGE (e, ei, b->preds)
if (e->flags & EDGE_EXECUTABLE)
break;
if (! e)
return NULL;
for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);) for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);)
{ {
...@@ -4695,10 +4700,8 @@ eliminate_dom_walker::before_dom_children (basic_block b) ...@@ -4695,10 +4700,8 @@ eliminate_dom_walker::before_dom_children (basic_block b)
} }
/* Replace destination PHI arguments. */ /* Replace destination PHI arguments. */
edge_iterator ei;
edge e;
FOR_EACH_EDGE (e, ei, b->succs) FOR_EACH_EDGE (e, ei, b->succs)
{ if (e->flags & EDGE_EXECUTABLE)
for (gphi_iterator gsi = gsi_start_phis (e->dest); for (gphi_iterator gsi = gsi_start_phis (e->dest);
!gsi_end_p (gsi); !gsi_end_p (gsi);
gsi_next (&gsi)) gsi_next (&gsi))
...@@ -4717,7 +4720,6 @@ eliminate_dom_walker::before_dom_children (basic_block b) ...@@ -4717,7 +4720,6 @@ eliminate_dom_walker::before_dom_children (basic_block b)
gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true); gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true);
} }
} }
}
return NULL; return NULL;
} }
...@@ -4743,9 +4745,6 @@ eliminate_dom_walker::after_dom_children (basic_block) ...@@ -4743,9 +4745,6 @@ eliminate_dom_walker::after_dom_children (basic_block)
static unsigned int static unsigned int
eliminate (bool do_pre) eliminate (bool do_pre)
{ {
gimple_stmt_iterator gsi;
gimple *stmt;
need_eh_cleanup = BITMAP_ALLOC (NULL); need_eh_cleanup = BITMAP_ALLOC (NULL);
need_ab_cleanup = BITMAP_ALLOC (NULL); need_ab_cleanup = BITMAP_ALLOC (NULL);
...@@ -4761,6 +4760,18 @@ eliminate (bool do_pre) ...@@ -4761,6 +4760,18 @@ eliminate (bool do_pre)
el_avail.release (); el_avail.release ();
el_avail_stack.release (); el_avail_stack.release ();
return el_todo;
}
/* Perform CFG cleanups made necessary by elimination. */
static unsigned
fini_eliminate (void)
{
gimple_stmt_iterator gsi;
gimple *stmt;
unsigned todo = 0;
/* We cannot remove stmts during BB walk, especially not release SSA /* We cannot remove stmts during BB walk, especially not release SSA
names there as this confuses the VN machinery. The stmts ending names there as this confuses the VN machinery. The stmts ending
up in el_to_remove are either stores or simple copies. up in el_to_remove are either stores or simple copies.
...@@ -4769,12 +4780,6 @@ eliminate (bool do_pre) ...@@ -4769,12 +4780,6 @@ eliminate (bool do_pre)
{ {
stmt = el_to_remove.pop (); stmt = el_to_remove.pop ();
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Removing dead stmt ");
print_gimple_stmt (dump_file, stmt, 0, 0);
}
tree lhs; tree lhs;
if (gimple_code (stmt) == GIMPLE_PHI) if (gimple_code (stmt) == GIMPLE_PHI)
lhs = gimple_phi_result (stmt); lhs = gimple_phi_result (stmt);
...@@ -4782,8 +4787,15 @@ eliminate (bool do_pre) ...@@ -4782,8 +4787,15 @@ eliminate (bool do_pre)
lhs = gimple_get_lhs (stmt); lhs = gimple_get_lhs (stmt);
if (inserted_exprs if (inserted_exprs
&& TREE_CODE (lhs) == SSA_NAME) && TREE_CODE (lhs) == SSA_NAME
bitmap_clear_bit (inserted_exprs, SSA_NAME_VERSION (lhs)); && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (lhs)))
continue;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Removing dead stmt ");
print_gimple_stmt (dump_file, stmt, 0, 0);
}
gsi = gsi_for_stmt (stmt); gsi = gsi_for_stmt (stmt);
if (gimple_code (stmt) == GIMPLE_PHI) if (gimple_code (stmt) == GIMPLE_PHI)
...@@ -4800,7 +4812,7 @@ eliminate (bool do_pre) ...@@ -4800,7 +4812,7 @@ eliminate (bool do_pre)
} }
/* Removing a stmt may expose a forwarder block. */ /* Removing a stmt may expose a forwarder block. */
el_todo |= TODO_cleanup_cfg; todo |= TODO_cleanup_cfg;
} }
el_to_remove.release (); el_to_remove.release ();
...@@ -4819,18 +4831,10 @@ eliminate (bool do_pre) ...@@ -4819,18 +4831,10 @@ eliminate (bool do_pre)
} }
if (fixup_noreturn_call (stmt)) if (fixup_noreturn_call (stmt))
el_todo |= TODO_cleanup_cfg; todo |= TODO_cleanup_cfg;
} }
el_to_fixup.release (); el_to_fixup.release ();
return el_todo;
}
/* Perform CFG cleanups made necessary by elimination. */
static unsigned
fini_eliminate (void)
{
bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup); bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup);
bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup); bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup);
...@@ -4844,8 +4848,8 @@ fini_eliminate (void) ...@@ -4844,8 +4848,8 @@ fini_eliminate (void)
BITMAP_FREE (need_ab_cleanup); BITMAP_FREE (need_ab_cleanup);
if (do_eh_cleanup || do_ab_cleanup) if (do_eh_cleanup || do_ab_cleanup)
return TODO_cleanup_cfg; todo |= TODO_cleanup_cfg;
return 0; return todo;
} }
/* Borrow a bit of tree-ssa-dce.c for the moment. /* Borrow a bit of tree-ssa-dce.c for the moment.
...@@ -5110,8 +5114,8 @@ pass_pre::execute (function *fun) ...@@ -5110,8 +5114,8 @@ pass_pre::execute (function *fun)
remove_dead_inserted_code (); remove_dead_inserted_code ();
scev_finalize (); scev_finalize ();
fini_pre ();
todo |= fini_eliminate (); todo |= fini_eliminate ();
fini_pre ();
loop_optimizer_finalize (); loop_optimizer_finalize ();
/* Restore SSA info before tail-merging as that resets it as well. */ /* Restore SSA info before tail-merging as that resets it as well. */
......
...@@ -205,6 +205,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -205,6 +205,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-sccvn.h" #include "tree-ssa-sccvn.h"
#include "cfgloop.h" #include "cfgloop.h"
#include "tree-eh.h" #include "tree-eh.h"
#include "tree-cfgcleanup.h"
/* Describes a group of bbs with the same successors. The successor bbs are /* Describes a group of bbs with the same successors. The successor bbs are
cached in succs, and the successor edge flags are cached in succ_flags. cached in succs, and the successor edge flags are cached in succ_flags.
...@@ -1717,6 +1718,16 @@ tail_merge_optimize (unsigned int todo) ...@@ -1717,6 +1718,16 @@ tail_merge_optimize (unsigned int todo)
timevar_push (TV_TREE_TAIL_MERGE); timevar_push (TV_TREE_TAIL_MERGE);
/* We enter from PRE which has critical edges split. Elimination
does not process trivially dead code so cleanup the CFG if we
are told so. And re-split critical edges then. */
if (todo & TODO_cleanup_cfg)
{
cleanup_tree_cfg ();
todo &= ~TODO_cleanup_cfg;
split_critical_edges ();
}
if (!dom_info_available_p (CDI_DOMINATORS)) if (!dom_info_available_p (CDI_DOMINATORS))
{ {
/* PRE can leave us with unreachable blocks, remove them now. */ /* PRE can leave us with unreachable blocks, remove them now. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment