public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r10-9880] [PR97969] LRA: Transform pattern `plus (plus (hard reg, const), pseudo)` after elimination
@ 2021-06-02 22:26 Przemyslaw Wirkus
  0 siblings, 0 replies; only message in thread
From: Przemyslaw Wirkus @ 2021-06-02 22:26 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:eb13f3f81d56910626529af52e03e74770ffca98

commit r10-9880-geb13f3f81d56910626529af52e03e74770ffca98
Author: Vladimir N. Makarov <vmakarov@redhat.com>
Date:   Tue Jan 12 11:26:15 2021 -0500

    [PR97969] LRA: Transform pattern `plus (plus (hard reg, const), pseudo)` after elimination
    
    LRA can loop infinitely on targets without `reg + imm` insns.  Register elimination
    on such targets can increase register pressure resulting in permanent
    stack size increase and changing elimination offset.  To avoid such situation, a simple
    transformation can be done to avoid register pressure increase after
    generating reload insns containing eliminated hard regs.
    
    gcc/ChangeLog:
    
            PR target/97969
            * lra-eliminations.c (eliminate_regs_in_insn): Add transformation
            of pattern 'plus (plus (hard reg, const), pseudo)'.
    
    gcc/testsuite/ChangeLog:
    
            PR target/97969
            * gcc.target/arm/pr97969.c: New.
    
    (cherry picked from commit cf2ac1c30af0fa783c8d72e527904dda5d8cc330)

Diff:
---
 gcc/lra-eliminations.c                 | 28 +++++++++++++++++-
 gcc/testsuite/gcc.target/arm/pr97969.c | 54 ++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c
index cf745dc6a26..e2d4b24db2a 100644
--- a/gcc/lra-eliminations.c
+++ b/gcc/lra-eliminations.c
@@ -885,7 +885,7 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
 			poly_int64 update_sp_offset)
 {
   int icode = recog_memoized (insn);
-  rtx old_set = single_set (insn);
+  rtx set, old_set = single_set (insn);
   bool validate_p;
   int i;
   rtx substed_operand[MAX_RECOG_OPERANDS];
@@ -1038,6 +1038,32 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
   for (i = 0; i < static_id->n_dups; i++)
     *id->dup_loc[i] = substed_operand[(int) static_id->dup_num[i]];
 
+  /* Transform plus (plus (hard reg, const), pseudo) to plus (plus (pseudo,
+     const), hard reg) in order to keep insn containing eliminated register
+     after all reloads calculating its offset.  This permits to keep register
+     pressure under control and helps to avoid LRA cycling in patalogical
+     cases.  */
+  if (! replace_p && (set = single_set (insn)) != NULL
+      && GET_CODE (SET_SRC (set)) == PLUS
+      && GET_CODE (XEXP (SET_SRC (set), 0)) == PLUS)
+    {
+      rtx reg1, reg2, op1, op2;
+      
+      reg1 = op1 = XEXP (XEXP (SET_SRC (set), 0), 0);
+      reg2 = op2 = XEXP (SET_SRC (set), 1);
+      if (GET_CODE (reg1) == SUBREG)
+	reg1 = SUBREG_REG (reg1);
+      if (GET_CODE (reg2) == SUBREG)
+	reg2 = SUBREG_REG (reg2);
+      if (REG_P (reg1) && REG_P (reg2)
+	  && REGNO (reg1) < FIRST_PSEUDO_REGISTER
+	  && REGNO (reg2) >= FIRST_PSEUDO_REGISTER)
+	{
+	  XEXP (XEXP (SET_SRC (set), 0), 0) = op2;
+	  XEXP (SET_SRC (set), 1) = op1;
+	}
+    }
+
   /* If we had a move insn but now we don't, re-recognize it.
      This will cause spurious re-recognition if the old move had a
      PARALLEL since the new one still will, but we can't call
diff --git a/gcc/testsuite/gcc.target/arm/pr97969.c b/gcc/testsuite/gcc.target/arm/pr97969.c
new file mode 100644
index 00000000000..714a1d18870
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr97969.c
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -fno-omit-frame-pointer -mthumb -w -Os" } */
+
+typedef a[23];
+enum { b };
+typedef struct {
+  int c;
+  char *e;
+  char f
+} d;
+typedef enum { g = 1 } h;
+typedef struct {
+  h i;
+  int j
+} k;
+typedef struct {
+  a l;
+  int a;
+  int m;
+  int n;
+  int o;
+  short p;
+  int q;
+  k r;
+  char e;
+  char *s;
+  d t;
+  d *u;
+  short v;
+  int w
+} aa;
+c(char x, int y, char z, int ab) {
+  aa ac;
+  ac.r.i = 0;
+  d ad;
+  ac.t = ad;
+  ac.u = 0;
+  ae(&ac.v, 0, 0);
+  ac.w = 0;
+  af(&ac, x + y, z, z + ab);
+  if (ag(0))
+    return 0;
+  if (x)
+    ac.s = z + ab;
+  else
+    ac.s = x + y;
+  ac.o |= g;
+  if (!setjmp()) {
+    ah(ac);
+    ai(b);
+    ac.e = z + ab;
+    aj(ac);
+  }
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-06-02 22:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-02 22:26 [gcc r10-9880] [PR97969] LRA: Transform pattern `plus (plus (hard reg, const), pseudo)` after elimination Przemyslaw Wirkus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).