Commit bf22920b by Tom de Vries Committed by Tom de Vries

re PR target/43920 (Choosing conditional execution over conditional branches for…

re PR target/43920 (Choosing conditional execution over conditional branches for code size in some cases.)

2011-04-07  Tom de Vries  <tom@codesourcery.com>

	PR target/43920
	* cfgcleanup.c (try_crossjump_to_edge): Add dir parameter.  Pass dir to
	flow_find_cross_jump.  Swap variables to implement backward replacement.
	(try_crossjump_bb): Add argument to try_crossjump_to_edge.

From-SVN: r172094
parent c7a69ce1
2011-04-07 Tom de Vries <tom@codesourcery.com> 2011-04-07 Tom de Vries <tom@codesourcery.com>
PR target/43920 PR target/43920
* cfgcleanup.c (try_crossjump_to_edge): Add dir parameter. Pass dir to
flow_find_cross_jump. Swap variables to implement backward replacement.
(try_crossjump_bb): Add argument to try_crossjump_to_edge.
2011-04-07 Tom de Vries <tom@codesourcery.com>
PR target/43920
* cfgcleanup.c (walk_to_nondebug_insn): New function. * cfgcleanup.c (walk_to_nondebug_insn): New function.
(flow_find_cross_jump): Use walk_to_nondebug_insn. Recalculate bb1 and (flow_find_cross_jump): Use walk_to_nondebug_insn. Recalculate bb1 and
bb2. bb2.
......
...@@ -69,7 +69,7 @@ static bool crossjumps_occured; ...@@ -69,7 +69,7 @@ static bool crossjumps_occured;
information; we should run df_analyze to enable more opportunities. */ information; we should run df_analyze to enable more opportunities. */
static bool block_was_dirty; static bool block_was_dirty;
static bool try_crossjump_to_edge (int, edge, edge); static bool try_crossjump_to_edge (int, edge, edge, enum replace_direction);
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);
static enum replace_direction old_insns_match_p (int, rtx, rtx); static enum replace_direction old_insns_match_p (int, rtx, rtx);
...@@ -1761,16 +1761,18 @@ block_has_preserve_label (basic_block bb) ...@@ -1761,16 +1761,18 @@ block_has_preserve_label (basic_block bb)
/* E1 and E2 are edges with the same destination block. Search their /* E1 and E2 are edges with the same destination block. Search their
predecessors for common code. If found, redirect control flow from predecessors for common code. If found, redirect control flow from
(maybe the middle of) E1->SRC to (maybe the middle of) E2->SRC. */ (maybe the middle of) E1->SRC to (maybe the middle of) E2->SRC (dir_forward),
or the other way around (dir_backward). DIR specifies the allowed
replacement direction. */
static bool static bool
try_crossjump_to_edge (int mode, edge e1, edge e2) try_crossjump_to_edge (int mode, edge e1, edge e2,
enum replace_direction dir)
{ {
int nmatch; int nmatch;
basic_block src1 = e1->src, src2 = e2->src; basic_block src1 = e1->src, src2 = e2->src;
basic_block redirect_to, redirect_from, to_remove; basic_block redirect_to, redirect_from, to_remove;
basic_block osrc1, osrc2, redirect_edges_to, tmp; basic_block osrc1, osrc2, redirect_edges_to, tmp;
enum replace_direction dir;
rtx newpos1, newpos2; rtx newpos1, newpos2;
edge s; edge s;
edge_iterator ei; edge_iterator ei;
...@@ -1826,7 +1828,6 @@ try_crossjump_to_edge (int mode, edge e1, edge e2) ...@@ -1826,7 +1828,6 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
return false; return false;
/* ... and part the second. */ /* ... and part the second. */
dir = dir_forward;
nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2, &dir); nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2, &dir);
osrc1 = src1; osrc1 = src1;
...@@ -1836,6 +1837,16 @@ try_crossjump_to_edge (int mode, edge e1, edge e2) ...@@ -1836,6 +1837,16 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
if (newpos2 != NULL_RTX) if (newpos2 != NULL_RTX)
src2 = BLOCK_FOR_INSN (newpos2); src2 = BLOCK_FOR_INSN (newpos2);
if (dir == dir_backward)
{
#define SWAP(T, X, Y) do { T tmp = (X); (X) = (Y); (Y) = tmp; } while (0)
SWAP (basic_block, osrc1, osrc2);
SWAP (basic_block, src1, src2);
SWAP (edge, e1, e2);
SWAP (rtx, newpos1, newpos2);
#undef SWAP
}
/* Don't proceed with the crossjump unless we found a sufficient number /* Don't proceed with the crossjump unless we found a sufficient number
of matching instructions or the 'from' block was totally matched of matching instructions or the 'from' block was totally matched
(such that its predecessors will hopefully be redirected and the (such that its predecessors will hopefully be redirected and the
...@@ -2088,7 +2099,7 @@ try_crossjump_bb (int mode, basic_block bb) ...@@ -2088,7 +2099,7 @@ try_crossjump_bb (int mode, basic_block bb)
|| (fallthru->src->flags & BB_MODIFIED))) || (fallthru->src->flags & BB_MODIFIED)))
continue; continue;
if (try_crossjump_to_edge (mode, e, fallthru)) if (try_crossjump_to_edge (mode, e, fallthru, dir_forward))
{ {
changed = true; changed = true;
ix = 0; ix = 0;
...@@ -2136,7 +2147,9 @@ try_crossjump_bb (int mode, basic_block bb) ...@@ -2136,7 +2147,9 @@ try_crossjump_bb (int mode, basic_block bb)
|| (e2->src->flags & BB_MODIFIED))) || (e2->src->flags & BB_MODIFIED)))
continue; continue;
if (try_crossjump_to_edge (mode, e, e2)) /* Both e and e2 are not fallthru edges, so we can crossjump in either
direction. */
if (try_crossjump_to_edge (mode, e, e2, dir_both))
{ {
changed = true; changed = true;
ix = 0; ix = 0;
......
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