re PR target/65032 (ICE in reload_combine_note_use, at postreload.c:1556 on i686...
authorVladimir Makarov <vmakarov@redhat.com>
Fri, 27 Feb 2015 14:15:02 +0000 (14:15 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Fri, 27 Feb 2015 14:15:02 +0000 (14:15 +0000)
2015-02-27  Vladimir Makarov  <vmakarov@redhat.com>

PR target/65032
* lra-remat.c (update_scratch_ops): New.
(do_remat): Call it.
* lra.c (lra_register_new_scratch_op): New. Take code from ...
(remove_scratches): ... here.
* lra-int.h (lra_register_new_scratch_op): New prototype.

2015-02-27  Vladimir Makarov  <vmakarov@redhat.com>

PR target/65032
* g++.dg/pr65032.C: New.

From-SVN: r221062

gcc/ChangeLog
gcc/lra-int.h
gcc/lra-remat.c
gcc/lra.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/pr65032.C [new file with mode: 0644]

index bee990ba1c645a8fa452b63662d74216688a7a5c..439b42820dd9b34072c5ce2d675269e492eb371d 100644 (file)
@@ -1,3 +1,12 @@
+2015-02-27  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR target/65032
+       * lra-remat.c (update_scratch_ops): New.
+       (do_remat): Call it.
+       * lra.c (lra_register_new_scratch_op): New. Take code from ...
+       (remove_scratches): ... here.
+       * lra-int.h (lra_register_new_scratch_op): New prototype.
+
 2015-02-27  Marek Polacek  <polacek@redhat.com>
 
        PR c/65040
index 972030992ba3243e39d2d13a21233cdc1fb2d883..735259123d666b021188c4f1a6171dd4fe3a6d8f 100644 (file)
@@ -321,6 +321,7 @@ extern void lra_create_copy (int, int, int);
 extern lra_copy_t lra_get_copy (int);
 extern bool lra_former_scratch_p (int);
 extern bool lra_former_scratch_operand_p (rtx_insn *, int);
+extern void lra_register_new_scratch_op (rtx_insn *, int);
 
 extern int lra_new_regno_start;
 extern int lra_constraint_new_regno_start;
index fb0eb3c1f7b7cd0ee268c75082a7bd4a41586cca..ac827795713db4e8440d02baca971dd2b0ec8055 100644 (file)
@@ -1044,6 +1044,29 @@ get_hard_regs (struct lra_insn_reg *reg, int &nregs)
   return hard_regno;
 }
 
+/* Make copy of and register scratch pseudos in rematerialized insn
+   REMAT_INSN.  */
+static void
+update_scratch_ops (rtx_insn *remat_insn)
+{
+  lra_insn_recog_data_t id = lra_get_insn_recog_data (remat_insn);
+  struct lra_static_insn_data *static_id = id->insn_static_data;
+  for (int i = 0; i < static_id->n_operands; i++)
+    {
+      rtx *loc = id->operand_loc[i];
+      if (! REG_P (*loc))
+       continue;
+      int regno = REGNO (*loc);
+      if (! lra_former_scratch_p (regno))
+       continue;
+      *loc = lra_create_new_reg (GET_MODE (*loc), *loc,
+                                lra_get_allocno_class (regno),
+                                "scratch pseudo copy");
+      lra_register_new_scratch_op (remat_insn, i);
+    }
+  
+}
+
 /* Insert rematerialization insns using the data-flow data calculated
    earlier.  */
 static bool
@@ -1193,6 +1216,7 @@ do_remat (void)
              HOST_WIDE_INT sp_offset_change = cand_sp_offset - id->sp_offset;
              if (sp_offset_change != 0)
                change_sp_offset (remat_insn, sp_offset_change);
+             update_scratch_ops (remat_insn);
              lra_process_new_insns (insn, remat_insn, NULL,
                                     "Inserting rematerialization insn");
              lra_set_insn_deleted (insn);
index abe0c334b32fc3a00df05f479f7914f949bbbdb2..727a70e063076739121bcda22265ae511b895d54 100644 (file)
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -1907,6 +1907,24 @@ lra_former_scratch_operand_p (rtx_insn *insn, int nop)
                       INSN_UID (insn) * MAX_RECOG_OPERANDS + nop) != 0;
 }
 
+/* Register operand NOP in INSN as a former scratch.  It will be
+   changed to scratch back, if it is necessary, at the LRA end.  */
+void
+lra_register_new_scratch_op (rtx_insn *insn, int nop)
+{
+  lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
+  rtx op = *id->operand_loc[nop];
+  sloc_t loc = XNEW (struct sloc);
+  lra_assert (REG_P (op));
+  loc->insn = insn;
+  loc->nop = nop;
+  scratches.safe_push (loc);
+  bitmap_set_bit (&scratch_bitmap, REGNO (op));
+  bitmap_set_bit (&scratch_operand_bitmap,
+                 INSN_UID (insn) * MAX_RECOG_OPERANDS + nop);
+  add_reg_note (insn, REG_UNUSED, op);
+}
+
 /* Change scratches onto pseudos and save their location.  */
 static void
 remove_scratches (void)
@@ -1916,7 +1934,6 @@ remove_scratches (void)
   basic_block bb;
   rtx_insn *insn;
   rtx reg;
-  sloc_t loc;
   lra_insn_recog_data_t id;
   struct lra_static_insn_data *static_id;
 
@@ -1938,15 +1955,7 @@ remove_scratches (void)
              *id->operand_loc[i] = reg
                = lra_create_new_reg (static_id->operand[i].mode,
                                      *id->operand_loc[i], ALL_REGS, NULL);
-             add_reg_note (insn, REG_UNUSED, reg);
-             lra_update_dup (id, i);
-             loc = XNEW (struct sloc);
-             loc->insn = insn;
-             loc->nop = i;
-             scratches.safe_push (loc);
-             bitmap_set_bit (&scratch_bitmap, REGNO (*id->operand_loc[i]));
-             bitmap_set_bit (&scratch_operand_bitmap,
-                             INSN_UID (insn) * MAX_RECOG_OPERANDS + i);
+             lra_register_new_scratch_op (insn, i);
              if (lra_dump_file != NULL)
                fprintf (lra_dump_file,
                         "Removing SCRATCH in insn #%u (nop %d)\n",
index 11139f977e543b74e1f12704e8eed4603ff287a5..fae312eb7bf67e9c364825b6075b106dc72ddc6d 100644 (file)
@@ -1,3 +1,8 @@
+2015-02-27  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR target/65032
+       * g++.dg/pr65032.C: New.
+
 2015-02-27  Marek Polacek  <polacek@redhat.com>
 
        PR c/65040
diff --git a/gcc/testsuite/g++.dg/pr65032.C b/gcc/testsuite/g++.dg/pr65032.C
new file mode 100644 (file)
index 0000000..a62f50b
--- /dev/null
@@ -0,0 +1,87 @@
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-options "-Os -std=c++11 -fPIC -fstack-protector-strong -fomit-frame-pointer" }
+
+#pragma GCC visibility push(hidden)
+#pragma GCC visibility push(default)
+extern "C" {
+  typedef int int64_t __attribute__ ((__mode__ (__DI__)));
+}
+enum class nsresult;
+#pragma GCC visibility pop
+class A
+{
+  float mRawPtr;
+
+ public:
+  A (float *);
+};
+class B
+{
+ public:
+  B (int64_t, int, int);
+};
+typedef struct
+{
+  int channels;
+} vorbis_info;
+template <typename _Key> class C
+{
+ public:
+  typedef int size_type;
+  size_type erase (_Key &);
+};
+
+template <typename _Key> class D
+{
+ public:
+  typedef _Key key_type;
+  typedef C<key_type> _Rep_type;
+  _Rep_type _M_t;
+  typename _Rep_type::size_type
+    erase (key_type p1)
+  {
+    return _M_t.erase (p1);
+  }
+};
+
+class F
+{
+ public:
+  vorbis_info mInfo;
+  D<int *> mVorbisPacketSamples;
+  void ValidateVorbisPacketSamples (int *);
+  int64_t Time (int64_t);
+};
+class G
+{
+  nsresult DecodeVorbis (int *);
+  F *mVorbisState;
+  int64_t mDecodedAudioFrames;
+};
+int fn1 (float ***);
+void fn2 (int);
+void
+F::ValidateVorbisPacketSamples (int *p1)
+{
+  mVorbisPacketSamples.erase (p1);
+}
+
+nsresult
+G::DecodeVorbis (int *p1)
+{
+  float **a;
+  int b;
+  long long c;
+  while ((b = fn1 (&a)))
+    {
+      mVorbisState->ValidateVorbisPacketSamples (p1);
+      A (new float);
+      for (; mVorbisState->mInfo.channels;)
+       {
+       }
+      int64_t d = mVorbisState->Time (c - b);
+      (B (d, b, mVorbisState->mInfo.channels));
+      mDecodedAudioFrames -= b;
+      fn2 (b);
+    }
+}