]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/60769 (ICE: Max. number of generated reload insns per insn...
authorVladimir Makarov <vmakarov@redhat.com>
Thu, 10 Apr 2014 23:22:10 +0000 (23:22 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Thu, 10 Apr 2014 23:22:10 +0000 (23:22 +0000)
2014-04-10  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/60769
* lra-constraints.c (simplify_operand_subreg): Force reload of
paradoxical subreg if it is not in the class contents.

2014-04-10  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/60769
* g++.dg/pr60769.C: New.

From-SVN: r209285

gcc/ChangeLog
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/pr60769.C [new file with mode: 0644]

index e6fd9b670883dde8ad021715197b25beb6769401..f3d348d6f9c960b6a790c52e3a24a09909bc255f 100644 (file)
@@ -1,3 +1,9 @@
+2014-04-10  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/60769
+       * lra-constraints.c (simplify_operand_subreg): Force reload of
+       paradoxical subreg if it is not in the class contents.
+
 2014-04-10  Jakub Jelinek  <jakub@redhat.com>
 
        Backport from mainline
index 32e8c45f2874e4eac6b863a748d5d9b757432939..e75305278a5d033e93c9d6465d52c56fb8df4220 100644 (file)
@@ -1156,6 +1156,8 @@ simplify_operand_subreg (int nop, enum machine_mode reg_mode)
   enum machine_mode mode;
   rtx reg, new_reg;
   rtx operand = *curr_id->operand_loc[nop];
+  enum reg_class regclass;
+  enum op_type type;
 
   before = after = NULL_RTX;
 
@@ -1164,6 +1166,7 @@ simplify_operand_subreg (int nop, enum machine_mode reg_mode)
 
   mode = GET_MODE (operand);
   reg = SUBREG_REG (operand);
+  type = curr_static_id->operand[nop].type;
   /* If we change address for paradoxical subreg of memory, the
      address might violate the necessary alignment or the access might
      be slow.  So take this into consideration.  We should not worry
@@ -1236,6 +1239,55 @@ simplify_operand_subreg (int nop, enum machine_mode reg_mode)
                             "Inserting subreg reload");
       return true;
     }
+  /* Force a reload for a paradoxical subreg. For paradoxical subreg,
+     IRA allocates hardreg to the inner pseudo reg according to its mode
+     instead of the outermode, so the size of the hardreg may not be enough
+     to contain the outermode operand, in that case we may need to insert
+     reload for the reg. For the following two types of paradoxical subreg,
+     we need to insert reload:
+     1. If the op_type is OP_IN, and the hardreg could not be paired with
+        other hardreg to contain the outermode operand
+        (checked by in_hard_reg_set_p), we need to insert the reload.
+     2. If the op_type is OP_OUT or OP_INOUT.  */
+  else if (REG_P (reg)
+          && REGNO (reg) >= FIRST_PSEUDO_REGISTER
+          && (hard_regno = lra_get_regno_hard_regno (REGNO (reg))) >= 0
+          && (hard_regno_nregs[hard_regno][GET_MODE (reg)]
+              < hard_regno_nregs[hard_regno][mode])
+          && (regclass = lra_get_allocno_class (REGNO (reg)))
+          && (type != OP_IN
+              || !in_hard_reg_set_p (reg_class_contents[regclass],
+                                     mode, hard_regno)))
+    {
+      /* The class will be defined later in curr_insn_transform.  */
+      enum reg_class rclass
+       = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS);
+      rtx subreg;
+      
+      new_reg = lra_create_new_reg_with_unique_value (mode, reg, rclass,
+                                                     "paradoxical subreg");
+      PUT_MODE (new_reg, mode);
+      subreg = simplify_gen_subreg (GET_MODE (reg), new_reg, mode, 0);
+      if (type != OP_OUT)
+       {
+         push_to_sequence (before);
+         lra_emit_move (subreg, reg);
+         before = get_insns ();
+         end_sequence ();
+       }
+      if (type != OP_IN)
+       {
+         start_sequence ();
+         lra_emit_move (reg, subreg);
+         emit_insn (after);
+         after = get_insns ();
+         end_sequence ();
+       }
+      SUBREG_REG (operand) = new_reg;
+      lra_process_new_insns (curr_insn, before, after,
+                             "Inserting paradoxical subreg reload");
+      return true;
+    }
   return false;
 }
 
index 2fe4b2b83e19920b07468ef2a80e10a40e33dbce..782120dc7b020a9ffe3a37b30d7411ed1816bcf3 100644 (file)
@@ -1,3 +1,8 @@
+2014-04-10  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/60769
+       * g++.dg/pr60769.C: New.
+
 2014-04-10  Jakub Jelinek  <jakub@redhat.com>
 
        Backport from mainline
diff --git a/gcc/testsuite/g++.dg/pr60769.C b/gcc/testsuite/g++.dg/pr60769.C
new file mode 100644 (file)
index 0000000..4c896c6
--- /dev/null
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+template <class T> void fun(T);
+struct B {};
+struct R {
+  int *x;
+  B f;
+};
+R v(int &, R);
+void rfun(R &);
+struct A {
+  void m_fn2(R p1) {
+    R a = p1;
+    rfun(p1);
+    fun(this);
+    fun(a);
+  }
+};
+struct J {
+  A ep;
+  A ap;
+  int c2a;
+  void m_fn1(R &p2) {
+    R d, e, b;
+    v(c2a, p2);
+    e = v(c2a, b);
+    ap.m_fn2(e);
+    v(c2a, p2);
+    d = v(c2a, b);
+    ep.m_fn2(d);
+  }
+};
+struct N {
+  int &p_;
+  J cfo;
+};
+void fn3(N&n) {
+  R h;
+  n.cfo.m_fn1(h);
+}
+extern N &c;
+void fn1() { fn3(c); }