diff mbox series

Punt on hard reg setters in modulo sched (PR target/83507)

Message ID 20180108235904.GY1833@tucnak
State New
Headers show
Series Punt on hard reg setters in modulo sched (PR target/83507) | expand

Commit Message

Jakub Jelinek Jan. 8, 2018, 11:59 p.m. UTC
Hi!

SMS is done before reload and assumes it can extend the lifetime by making
copies of the destination registers without trying to re-recognize the
instructions etc.  That can work only with pseudos, for some hard registers
there isn't even a valid move instruction to pseudo (e.g. the powerpc CA
register), for others it can be very much undesirable.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-01-09  Jakub Jelinek  <jakub@redhat.com>

	PR target/83507
	* modulo-sched.c (schedule_reg_moves): Punt if we'd need to move
	hard registers.  Formatting fixes.

	* gcc.dg/sms-13.c: New test.


	Jakub

Comments

Richard Biener Jan. 9, 2018, 6:56 a.m. UTC | #1
On January 9, 2018 12:59:04 AM GMT+01:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!
>
>SMS is done before reload and assumes it can extend the lifetime by
>making
>copies of the destination registers without trying to re-recognize the
>instructions etc.  That can work only with pseudos, for some hard
>registers
>there isn't even a valid move instruction to pseudo (e.g. the powerpc
>CA
>register), for others it can be very much undesirable.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK. 

Richard. 

>2018-01-09  Jakub Jelinek  <jakub@redhat.com>
>
>	PR target/83507
>	* modulo-sched.c (schedule_reg_moves): Punt if we'd need to move
>	hard registers.  Formatting fixes.
>
>	* gcc.dg/sms-13.c: New test.
>
>--- gcc/modulo-sched.c.jj	2018-01-03 10:19:55.710534046 +0100
>+++ gcc/modulo-sched.c	2018-01-08 16:53:01.232465389 +0100
>@@ -687,9 +687,9 @@ schedule_reg_moves (partial_schedule_ptr
>       rtx set = single_set (u->insn);
>       
>       /* Skip instructions that do not set a register.  */
>-      if ((set && !REG_P (SET_DEST (set))))
>+      if (set && !REG_P (SET_DEST (set)))
>         continue;
>- 
>+
>    /* Compute the number of reg_moves needed for u, by looking at life
> 	 ranges started at u (excluding self-loops).  */
>       distances[0] = distances[1] = false;
>@@ -743,7 +743,10 @@ schedule_reg_moves (partial_schedule_ptr
>       first_move += ps->g->num_nodes;
> 
>       /* Generate each move.  */
>-      old_reg = prev_reg = SET_DEST (single_set (u->insn));
>+      old_reg = prev_reg = SET_DEST (set);
>+      if (HARD_REGISTER_P (old_reg))
>+	return false;
>+
>       for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
> 	{
> 	  ps_reg_move_info *move = ps_reg_move (ps, first_move + i_reg_move);
>--- gcc/testsuite/gcc.dg/sms-13.c.jj	2018-01-08 17:00:16.427534076
>+0100
>+++ gcc/testsuite/gcc.dg/sms-13.c	2018-01-08 16:56:15.704496101 +0100
>@@ -0,0 +1,32 @@
>+/* PR target/83507 */
>+/* { dg-do compile } */
>+/* { dg-options "-O2 -fmodulo-sched -fno-tree-ter
>-fno-tree-coalesce-vars" } */
>+
>+void
>+foo (unsigned short int x, unsigned char y)
>+{
>+  unsigned char *a = &y;
>+  unsigned short int b;
>+  int c;
>+
>+  while (y < 3)
>+    {
>+      if (x != 0)
>+        ++y;
>+      ++y;
>+    }
>+
>+  for (c = 0; c < 5; ++c)
>+    {
>+      int d = 1;
>+      d += b > x;
>+      y &= d;
>+    }
>+
>+  do
>+    {
>+      c += y;
>+      x = c;
>+    }
>+  while (x != 0);
>+}
>
>	Jakub
diff mbox series

Patch

--- gcc/modulo-sched.c.jj	2018-01-03 10:19:55.710534046 +0100
+++ gcc/modulo-sched.c	2018-01-08 16:53:01.232465389 +0100
@@ -687,9 +687,9 @@  schedule_reg_moves (partial_schedule_ptr
       rtx set = single_set (u->insn);
       
       /* Skip instructions that do not set a register.  */
-      if ((set && !REG_P (SET_DEST (set))))
+      if (set && !REG_P (SET_DEST (set)))
         continue;
- 
+
       /* Compute the number of reg_moves needed for u, by looking at life
 	 ranges started at u (excluding self-loops).  */
       distances[0] = distances[1] = false;
@@ -743,7 +743,10 @@  schedule_reg_moves (partial_schedule_ptr
       first_move += ps->g->num_nodes;
 
       /* Generate each move.  */
-      old_reg = prev_reg = SET_DEST (single_set (u->insn));
+      old_reg = prev_reg = SET_DEST (set);
+      if (HARD_REGISTER_P (old_reg))
+	return false;
+
       for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
 	{
 	  ps_reg_move_info *move = ps_reg_move (ps, first_move + i_reg_move);
--- gcc/testsuite/gcc.dg/sms-13.c.jj	2018-01-08 17:00:16.427534076 +0100
+++ gcc/testsuite/gcc.dg/sms-13.c	2018-01-08 16:56:15.704496101 +0100
@@ -0,0 +1,32 @@ 
+/* PR target/83507 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fmodulo-sched -fno-tree-ter -fno-tree-coalesce-vars" } */
+
+void
+foo (unsigned short int x, unsigned char y)
+{
+  unsigned char *a = &y;
+  unsigned short int b;
+  int c;
+
+  while (y < 3)
+    {
+      if (x != 0)
+        ++y;
+      ++y;
+    }
+
+  for (c = 0; c < 5; ++c)
+    {
+      int d = 1;
+      d += b > x;
+      y &= d;
+    }
+
+  do
+    {
+      c += y;
+      x = c;
+    }
+  while (x != 0);
+}