aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom de Vries <tom@codesourcery.com>2011-04-07 09:48:39 +0000
committerTom de Vries <vries@gcc.gnu.org>2011-04-07 09:48:39 +0000
commitbf22920b4a994c29b01c0fff1232ef3f3c451895 (patch)
tree591d7b9423c639aa975cf97c2542040d0ea39196
parentc7a69ce198cb28d64bfb2864fb6d3a1d57df5a7d (diff)
downloadgcc-bf22920b4a994c29b01c0fff1232ef3f3c451895.zip
gcc-bf22920b4a994c29b01c0fff1232ef3f3c451895.tar.gz
gcc-bf22920b4a994c29b01c0fff1232ef3f3c451895.tar.bz2
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/cfgcleanup.c27
2 files changed, 27 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8594a76..7d80cea 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,13 @@
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.
+
+2011-04-07 Tom de Vries <tom@codesourcery.com>
+
+ PR target/43920
* cfgcleanup.c (walk_to_nondebug_insn): New function.
(flow_find_cross_jump): Use walk_to_nondebug_insn. Recalculate bb1 and
bb2.
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 27af12f..98c51ad 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -69,7 +69,7 @@ static bool crossjumps_occured;
information; we should run df_analyze to enable more opportunities. */
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 outgoing_edges_match (int, basic_block, basic_block);
static enum replace_direction old_insns_match_p (int, rtx, rtx);
@@ -1761,16 +1761,18 @@ block_has_preserve_label (basic_block bb)
/* E1 and E2 are edges with the same destination block. Search their
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
-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;
basic_block src1 = e1->src, src2 = e2->src;
basic_block redirect_to, redirect_from, to_remove;
basic_block osrc1, osrc2, redirect_edges_to, tmp;
- enum replace_direction dir;
rtx newpos1, newpos2;
edge s;
edge_iterator ei;
@@ -1826,7 +1828,6 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
return false;
/* ... and part the second. */
- dir = dir_forward;
nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2, &dir);
osrc1 = src1;
@@ -1836,6 +1837,16 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
if (newpos2 != NULL_RTX)
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
of matching instructions or the 'from' block was totally matched
(such that its predecessors will hopefully be redirected and the
@@ -2088,7 +2099,7 @@ try_crossjump_bb (int mode, basic_block bb)
|| (fallthru->src->flags & BB_MODIFIED)))
continue;
- if (try_crossjump_to_edge (mode, e, fallthru))
+ if (try_crossjump_to_edge (mode, e, fallthru, dir_forward))
{
changed = true;
ix = 0;
@@ -2136,7 +2147,9 @@ try_crossjump_bb (int mode, basic_block bb)
|| (e2->src->flags & BB_MODIFIED)))
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;
ix = 0;