summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir N. Makarov <vmakarov@redhat.com>2025-11-21 11:49:31 -0500
committerVladimir N. Makarov <vmakarov@redhat.com>2025-11-21 12:43:16 -0500
commitb7f137e56867dd3aa1f05f3409f146391dec131c (patch)
tree643effb3c681389d780789b5176478e36fd4eb4a
parentfe3c8455d0709751d23617303a1bf9311f888153 (diff)
[PR118358, LRA]: Decrease pressure after issuing input reload insns
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.
-rw-r--r--gcc/lra-constraints.cc40
-rw-r--r--gcc/testsuite/gcc.target/xstormy16/pr118358.c90
2 files changed, 130 insertions, 0 deletions
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 82cf0a829bf..d843226c8c8 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -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
index 00000000000..0743a023586
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xstormy16/pr118358.c
@@ -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);
+}