]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR118358, LRA]: Decrease pressure after issuing input reload insns
authorVladimir N. Makarov <vmakarov@redhat.com>
Fri, 21 Nov 2025 16:49:31 +0000 (11:49 -0500)
committerVladimir N. Makarov <vmakarov@redhat.com>
Fri, 21 Nov 2025 17:43:16 +0000 (12:43 -0500)
LRA can generate sequence of reload insns for one input operand using
intermediate pseudos.  Register pressure when reload insn for another
input operand is placed before the sequence is more than when the
reload insn is placed after the sequence.  The problem report reveals
a case when several such sequences increase the pressure for input
reload insns beyond available registers and as a consequence this
results in LRA cycling.

gcc/ChangeLog:

PR target/118358
* lra-constraints.cc (curr_insn_transform): Move insn reloading
constant into a register right before insn using it.

gcc/testsuite/ChangeLog:

PR target/118358
* gcc.target/xstormy16/pr118358.c: New.

gcc/lra-constraints.cc
gcc/testsuite/gcc.target/xstormy16/pr118358.c [new file with mode: 0644]

index 82cf0a829bf15068d6e7fd6c444d4e2b617cd09d..d843226c8c86faa10b32d90850fd1a5c7e3a7bad 100644 (file)
@@ -4960,7 +4960,47 @@ curr_insn_transform (bool check_only_p)
          }
       lra_assert (done_p);
     }
+  int const_regno = -1;
+  rtx set;
+  rtx_insn *prev, *const_insn = NULL;
+  if (before != NULL_RTX && (prev = PREV_INSN (curr_insn)) != NULL_RTX
+      && (set = single_set (prev)) != NULL_RTX && CONSTANT_P (SET_SRC (set)))
+    {
+      rtx reg = SET_DEST (set);
+      if (GET_CODE (reg) == SUBREG)
+       reg = SUBREG_REG (reg);
+      /* Consider only reload insns as we don't want to change the order
+        created by previous optimizations.  */
+      if (REG_P (reg) && (int) REGNO (reg) >= lra_new_regno_start
+         && bitmap_bit_p (&lra_reg_info[REGNO (reg)].insn_bitmap,
+                          INSN_UID (curr_insn)))
+       {
+         const_regno = REGNO (reg);
+         const_insn = prev;
+       }
+    }
   lra_process_new_insns (curr_insn, before, after, "Inserting insn reload");
+  if (const_regno >= 0) {
+    bool move_p = true;
+    for (rtx_insn *insn = before; insn != curr_insn; insn = NEXT_INSN (insn))
+      if (bitmap_bit_p (&lra_reg_info[const_regno].insn_bitmap,
+                       INSN_UID (insn)))
+       {
+         move_p = false;
+         break;
+       }
+    if (move_p)
+      {
+       reorder_insns_nobb (const_insn, const_insn, PREV_INSN (curr_insn));
+       if (lra_dump_file != NULL)
+         {
+           dump_insn_slim (lra_dump_file, const_insn);
+           fprintf (lra_dump_file,
+                    "    to decrease reg pressure, it is moved before:\n");
+           dump_insn_slim (lra_dump_file, curr_insn);
+         }
+      }
+  }
   return change_p;
 }
 
diff --git a/gcc/testsuite/gcc.target/xstormy16/pr118358.c b/gcc/testsuite/gcc.target/xstormy16/pr118358.c
new file mode 100644 (file)
index 0000000..0743a02
--- /dev/null
@@ -0,0 +1,90 @@
+/* PR target/118358.  */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern void exit (int);
+
+typedef struct
+{
+  union
+  {
+    struct
+    {
+      unsigned char a3;
+      unsigned char a4;
+    } a2;
+    unsigned int a5;
+  } a0;
+  unsigned int a1;
+} A;
+
+static int
+foo (unsigned int *b, unsigned int n, unsigned int s, const unsigned int *d,
+     const unsigned int *e, A **t, unsigned int *m, A *hp, unsigned int *hn,
+     unsigned int *v)
+{
+  unsigned int a, c[15 + 1], f;
+  int g, h;
+  unsigned int i, j, k;
+  int l;
+  unsigned int ee;
+  unsigned int *p;
+  A *q, r, *u[15];
+  int w;
+  unsigned int x[15 + 1], *xx;
+  int y;
+  unsigned int z;
+  for (j = 1; j <= 15; j++)
+    if (c[j])
+      break;
+  if ((unsigned int) l < j)
+    l = j;
+  for (i = 15; i; i--)
+    if (c[i])
+      break;
+  g = i;
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return -3;
+  h = -1;
+  z = 0;
+  for (; k <= g; k++)
+    {
+          while (k > w + l)
+            {
+              h++;
+              w += l;
+              if ((f = 1 << (j = k - w)) > a + 1)
+                ;
+              z = 1 << j;
+              if (*hn + z > 1440)
+                return -3;
+              u[h] = q = hp + *hn;
+                  r.a0.a2.a4 = (unsigned char) l;
+                  r.a1 = (unsigned int) (q - u[h - 1] - j);
+            }
+          for (j = i >> w; j < z; j += f)
+            q[j] = r;
+          for (j = 1 << (k - 1); i & j; j >>= 1)
+            i ^= j;
+          while ((i & ee) != x[h])
+            {
+              h--;
+              w -= l;
+            }
+    }
+  return y != 0 && g != 1 ? (-5) : 0;
+}
+
+unsigned int a[19] = { 3, 4, 0, 2, 2, [17] = 3, 3 };
+unsigned int d[19];
+A h[1440];
+
+int
+main (void)
+{
+  unsigned int b = 0, c = 0;
+  A *e = 0;
+  foo (a, 19, 19, 0, 0, &e, &b, h, &c, d);
+  exit (0);
+}