Patchwork [PR43920,9/9] Cross-jumping - Allow both directions.

login
register
mail settings
Submitter Tom de Vries
Date April 1, 2011, 2:56 p.m.
Message ID <4D95E7A2.8040702@codesourcery.com>
Download mbox | patch
Permalink /patch/89278/
State New
Headers show

Comments

Tom de Vries - April 1, 2011, 2:56 p.m.
Reposting, with ChangeLog.
Jeff Law - April 5, 2011, 9:46 p.m.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 04/01/11 08:56, Tom de Vries wrote:
> Reposting, with ChangeLog.
> 	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.
OK.

jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNm42uAAoJEBRtltQi2kC7h0AH/AoaZ4aIRIfBwPIWJEra66s2
jnwqPp0QuyY70L3+Ik3/5dJIvnfR0lorJ7AzIyUz2hICRLqKP9grYNFIgUe5HpZH
BwCgS4v46Gj2tbwDCZ6ggoNi8PhVIX4QAh/HoSpoIfOGssVnzHUxP0tKlkCzMmQL
V1+RvMnrxSL2ljYT0FRoo49osJ/OXYrrJUPSC8ELm5DbtA7EydHFKtg0W9dtovcC
1LBUWaBPz/rNqaI34dL7RjXcfgYaaOj5s6SPN1DuGv2cGuTjbvMbupa9rWAYHjwA
qW79rqFbVdHyUo55W5ofUniadWs/1Byz2DpsegyxOjx35UBrcH42SRYR2XMFIzI=
=Cd8G
-----END PGP SIGNATURE-----

Patch

2011-04-01  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.

diff -u gcc/cfgcleanup.c gcc/cfgcleanup.c
--- gcc/cfgcleanup.c	(working copy)
+++ gcc/cfgcleanup.c	(working copy)
@@ -69,7 +69,7 @@ 
    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);
@@ -1695,15 +1695,17 @@ 
 /* 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;
@@ -1757,8 +1759,7 @@ 
     return false;
 
   /* ... and part the second.  */
-  dir = dir_forward;
   nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2, &dir);
 
   osrc1 = src1;
   osrc2 = src2;
@@ -1767,5 +1768,15 @@ 
   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
@@ -2020,7 +2031,7 @@ 
 		   || (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;
@@ -2068,7 +2079,9 @@ 
 		   || (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;