OSDN Git Service

PR target/25005
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Dec 2005 09:43:36 +0000 (09:43 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Dec 2005 09:43:36 +0000 (09:43 +0000)
* regrename.c (replace_oldest_value_reg): Use validate_change with
IN_GROUP set to 1 instead of doing direct modifications.
(copyprop_hardreg_forward_1): Likewise.  If any replace_oldest_*
replacements have been performed on an instruction, use
apply_change_group ().

* g++.dg/opt/pr25005.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109013 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/regrename.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr25005.C [new file with mode: 0644]

index 1b64d26..524b84a 100644 (file)
@@ -1,3 +1,12 @@
+2005-12-23  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/25005
+       * regrename.c (replace_oldest_value_reg): Use validate_change with
+       IN_GROUP set to 1 instead of doing direct modifications.
+       (copyprop_hardreg_forward_1): Likewise.  If any replace_oldest_*
+       replacements have been performed on an instruction, use
+       apply_change_group ().
+
 2005-12-23  Hans-Peter Nilsson  <hp@axis.com>
 
        * config/cris/arit.c (do_31div): Clarify what "31" refers to.
index c9e1ac5..a73e5f7 100644 (file)
@@ -1408,7 +1408,7 @@ replace_oldest_value_reg (rtx *loc, enum reg_class cl, rtx insn,
        fprintf (dump_file, "insn %u: replaced reg %u with %u\n",
                 INSN_UID (insn), REGNO (*loc), REGNO (new));
 
-      *loc = new;
+      validate_change (insn, loc, new, 1);
       return true;
     }
   return false;
@@ -1574,8 +1574,9 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
   for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
     {
       int n_ops, i, alt, predicated;
-      bool is_asm;
+      bool is_asm, any_replacements;
       rtx set;
+      bool replaced[MAX_RECOG_OPERANDS];
 
       if (! INSN_P (insn))
        {
@@ -1687,11 +1688,13 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
        }
       no_move_special_case:
 
+      any_replacements = false;
+
       /* For each input operand, replace a hard register with the
         eldest live copy that's in an appropriate register class.  */
       for (i = 0; i < n_ops; i++)
        {
-         bool replaced = false;
+         replaced[i] = false;
 
          /* Don't scan match_operand here, since we've no reg class
             information to pass down.  Any operands that we could
@@ -1708,37 +1711,57 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
          if (recog_data.operand_type[i] == OP_IN)
            {
              if (recog_op_alt[i][alt].is_address)
-               replaced
+               replaced[i]
                  = replace_oldest_value_addr (recog_data.operand_loc[i],
                                               recog_op_alt[i][alt].cl,
                                               VOIDmode, insn, vd);
              else if (REG_P (recog_data.operand[i]))
-               replaced
+               replaced[i]
                  = replace_oldest_value_reg (recog_data.operand_loc[i],
                                              recog_op_alt[i][alt].cl,
                                              insn, vd);
              else if (MEM_P (recog_data.operand[i]))
-               replaced = replace_oldest_value_mem (recog_data.operand[i],
-                                                    insn, vd);
+               replaced[i] = replace_oldest_value_mem (recog_data.operand[i],
+                                                       insn, vd);
            }
          else if (MEM_P (recog_data.operand[i]))
-           replaced = replace_oldest_value_mem (recog_data.operand[i],
-                                                insn, vd);
+           replaced[i] = replace_oldest_value_mem (recog_data.operand[i],
+                                                   insn, vd);
 
          /* If we performed any replacement, update match_dups.  */
-         if (replaced)
+         if (replaced[i])
            {
              int j;
              rtx new;
 
-             changed = true;
-
              new = *recog_data.operand_loc[i];
              recog_data.operand[i] = new;
              for (j = 0; j < recog_data.n_dups; j++)
                if (recog_data.dup_num[j] == i)
-                 *recog_data.dup_loc[j] = new;
+                 validate_change (insn, recog_data.dup_loc[j], new, 1);
+
+             any_replacements = true;
+           }
+       }
+
+      if (any_replacements)
+       {
+         if (! apply_change_group ())
+           {
+             for (i = 0; i < n_ops; i++)
+               if (replaced[i])
+                 {
+                   rtx old = *recog_data.operand_loc[i];
+                   recog_data.operand[i] = old;
+                 }
+
+             if (dump_file)
+               fprintf (dump_file,
+                        "insn %u: reg replacements not verified\n",
+                        INSN_UID (insn));
            }
+         else
+           changed = true;
        }
 
     did_replacement:
index 87557d8..a61ab6f 100644 (file)
@@ -1,3 +1,8 @@
+2005-12-23  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/25005
+       * g++.dg/opt/pr25005.C: New test.
+
 2005-12-22  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/25369
diff --git a/gcc/testsuite/g++.dg/opt/pr25005.C b/gcc/testsuite/g++.dg/opt/pr25005.C
new file mode 100644 (file)
index 0000000..f62f8a2
--- /dev/null
@@ -0,0 +1,34 @@
+// PR target/25005
+// { dg-options "-O2 -funroll-loops" }
+// { dg-do compile }
+
+inline void *operator new (__SIZE_TYPE__, void *__p) throw() { return __p; }
+
+struct M { ~M() { } };
+
+struct P
+{
+  P () { v[0] = 0; v[1] = 0; v[2] = 0; }
+  P (const P &x) { for (int i = 0; i < 3; ++i) v[i] = x.v[i]; }
+  double v[3];
+};
+
+struct V : public M
+{
+  V (const P *x, const P *y)
+  {
+    P *b = this->a = ::new P[2];
+    for (; x != y; ++x, ++b)
+      ::new (b) P(*x);
+  }
+  P *a;
+};
+
+void bar (const V &);
+
+void
+foo ()
+{
+  const P d[2] = { P(), P() };
+  bar (V (&d[0], &d[2]));
+}