Commit c1e3e2d9 by Steven Bosscher Committed by Richard Biener

re PR middle-end/30905 (Fails to cross-jump)

2008-01-11  Steven Bosscher  <stevenb.gcc@gmail.com>

	PR rtl-optimization/30905
	* cfgcleanup.c: Include dce.h
	(crossjumps_occured): New global variable.
	(try_crossjump_bb): Exit loop after finding a fallthru edge.
	If something changed, set crossjumps_occured to true.
	(try_optimize_cfg): Clear crossjumps_occured at the beginning.
	Don't add/remove fake edges to exit here...
	(cleanup_cfg): ...but do it here, when crossjumping.
	Run a fast DCE when successful crossjumps occured in the latest
	iteration of try_optimize_cfg.

From-SVN: r131468
parent 8d0eca24
2008-01-11 Steven Bosscher <stevenb.gcc@gmail.com>
PR rtl-optimization/30905
* cfgcleanup.c: Include dce.h
(crossjumps_occured): New global variable.
(try_crossjump_bb): Exit loop after finding a fallthru edge.
If something changed, set crossjumps_occured to true.
(try_optimize_cfg): Clear crossjumps_occured at the beginning.
Don't add/remove fake edges to exit here...
(cleanup_cfg): ...but do it here, when crossjumping.
Run a fast DCE when successful crossjumps occured in the latest
iteration of try_optimize_cfg.
2008-01-11 Richard Guenther <rguenther@suse.de> 2008-01-11 Richard Guenther <rguenther@suse.de>
* tree-ssa-sccvn.c (struct vn_binary_op_s): Move hashcode near opcode. * tree-ssa-sccvn.c (struct vn_binary_op_s): Move hashcode near opcode.
...@@ -54,11 +54,16 @@ along with GCC; see the file COPYING3. If not see ...@@ -54,11 +54,16 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h" #include "cfgloop.h"
#include "expr.h" #include "expr.h"
#include "df.h" #include "df.h"
#include "dce.h"
#define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK) #define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK)
/* Set to true when we are running first pass of try_optimize_cfg loop. */ /* Set to true when we are running first pass of try_optimize_cfg loop. */
static bool first_pass; static bool first_pass;
/* Set to true if crossjumps occured in the latest run of try_optimize_cfg. */
static bool crossjumps_occured;
static bool try_crossjump_to_edge (int, edge, edge); static bool try_crossjump_to_edge (int, edge, edge);
static bool try_crossjump_bb (int, basic_block); static bool try_crossjump_bb (int, basic_block);
static bool outgoing_edges_match (int, basic_block, basic_block); static bool outgoing_edges_match (int, basic_block, basic_block);
...@@ -1838,7 +1843,10 @@ try_crossjump_bb (int mode, basic_block bb) ...@@ -1838,7 +1843,10 @@ try_crossjump_bb (int mode, basic_block bb)
FOR_EACH_EDGE (e, ei, bb->preds) FOR_EACH_EDGE (e, ei, bb->preds)
{ {
if (e->flags & EDGE_FALLTHRU) if (e->flags & EDGE_FALLTHRU)
{
fallthru = e; fallthru = e;
break;
}
} }
changed = false; changed = false;
...@@ -1847,7 +1855,8 @@ try_crossjump_bb (int mode, basic_block bb) ...@@ -1847,7 +1855,8 @@ try_crossjump_bb (int mode, basic_block bb)
e = EDGE_PRED (ev, ix); e = EDGE_PRED (ev, ix);
ix++; ix++;
/* As noted above, first try with the fallthru predecessor. */ /* As noted above, first try with the fallthru predecessor (or, a
fallthru predecessor if we are in cfglayout mode). */
if (fallthru) if (fallthru)
{ {
/* Don't combine the fallthru edge into anything else. /* Don't combine the fallthru edge into anything else.
...@@ -1921,6 +1930,9 @@ try_crossjump_bb (int mode, basic_block bb) ...@@ -1921,6 +1930,9 @@ try_crossjump_bb (int mode, basic_block bb)
} }
} }
if (changed)
crossjumps_occured = true;
return changed; return changed;
} }
...@@ -1935,12 +1947,11 @@ try_optimize_cfg (int mode) ...@@ -1935,12 +1947,11 @@ try_optimize_cfg (int mode)
int iterations = 0; int iterations = 0;
basic_block bb, b, next; basic_block bb, b, next;
if (mode & CLEANUP_CROSSJUMP)
add_noreturn_fake_exit_edges ();
if (mode & (CLEANUP_CROSSJUMP | CLEANUP_THREADING)) if (mode & (CLEANUP_CROSSJUMP | CLEANUP_THREADING))
clear_bb_flags (); clear_bb_flags ();
crossjumps_occured = false;
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
update_forwarder_flag (bb); update_forwarder_flag (bb);
...@@ -2131,9 +2142,6 @@ try_optimize_cfg (int mode) ...@@ -2131,9 +2142,6 @@ try_optimize_cfg (int mode)
while (changed); while (changed);
} }
if (mode & CLEANUP_CROSSJUMP)
remove_fake_exit_edges ();
FOR_ALL_BB (b) FOR_ALL_BB (b)
b->flags &= ~(BB_FORWARDER_BLOCK | BB_NONTHREADABLE_BLOCK); b->flags &= ~(BB_FORWARDER_BLOCK | BB_NONTHREADABLE_BLOCK);
...@@ -2235,20 +2243,44 @@ cleanup_cfg (int mode) ...@@ -2235,20 +2243,44 @@ cleanup_cfg (int mode)
compact_blocks (); compact_blocks ();
/* To tail-merge blocks ending in the same noreturn function (e.g.
a call to abort) we have to insert fake edges to exit. Do this
here once. The fake edges do not interfere with any other CFG
cleanups. */
if (mode & CLEANUP_CROSSJUMP)
add_noreturn_fake_exit_edges ();
while (try_optimize_cfg (mode)) while (try_optimize_cfg (mode))
{ {
delete_unreachable_blocks (), changed = true; delete_unreachable_blocks (), changed = true;
if (!(mode & CLEANUP_NO_INSN_DEL) if (!(mode & CLEANUP_NO_INSN_DEL))
&& (mode & CLEANUP_EXPENSIVE) {
&& !reload_completed) /* Try to remove some trivially dead insns when doing an expensive
{ cleanup. But delete_trivially_dead_insns doesn't work after
if (!delete_trivially_dead_insns (get_insns (), max_reg_num ())) reload (it only handles pseudos) and run_fast_dce is too costly
to run in every iteration.
For effective cross jumping, we really want to run a fast DCE to
clean up any dead conditions, or they get in the way of performing
useful tail merges.
Other transformations in cleanup_cfg are not so sensitive to dead
code, so delete_trivially_dead_insns or even doing nothing at all
is good enough. */
if ((mode & CLEANUP_EXPENSIVE) && !reload_completed
&& !delete_trivially_dead_insns (get_insns (), max_reg_num ()))
break; break;
else if ((mode & CLEANUP_CROSSJUMP)
&& crossjumps_occured)
run_fast_dce ();
} }
else else
break; break;
} }
if (mode & CLEANUP_CROSSJUMP)
remove_fake_exit_edges ();
/* Don't call delete_dead_jumptables in cfglayout mode, because /* Don't call delete_dead_jumptables in cfglayout mode, because
that function assumes that jump tables are in the insns stream. that function assumes that jump tables are in the insns stream.
But we also don't _have_ to delete dead jumptables in cfglayout But we also don't _have_ to delete dead jumptables in cfglayout
......
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