re PR rtl-optimization/64087 (ICE on valid code at -O3 on x86_64-linux-gnu in in...
authorVladimir Makarov <vmakarov@redhat.com>
Fri, 28 Nov 2014 15:39:52 +0000 (15:39 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Fri, 28 Nov 2014 15:39:52 +0000 (15:39 +0000)
2014-11-28  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/64087
* lra-lives.c (process_bb_lives): Add debug output.
(lra_create_live_ranges): Don't remove dead insn on the second
call of lra_create_live_ranges_1.

2014-11-28  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/64087
*  gcc.dg/pr64087.c: New.

From-SVN: r218162

gcc/ChangeLog
gcc/lra-lives.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr64087.c [new file with mode: 0644]

index 4ce634a..24112ee 100644 (file)
@@ -1,3 +1,10 @@
+2014-11-28  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/64087
+       * lra-lives.c (process_bb_lives): Add debug output.
+       (lra_create_live_ranges): Don't remove dead insn on the second
+       call of lra_create_live_ranges_1.
+
 2014-11-28  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR rtl-optimization/64037
index df0143f..a593b02 100644 (file)
@@ -971,14 +971,23 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
       live_pseudos_num++;
       if (! sparseset_bit_p (pseudos_live, j))
        {
-         live_change_p = TRUE;
+         live_change_p = true;
+         if (lra_dump_file != NULL)
+           fprintf (lra_dump_file,
+                    "  r%d is removed as live at bb%d start\n", j, bb->index);
          break;
        }
     }
-  live_change_p
-    = (live_change_p
-       || sparseset_cardinality (pseudos_live) != live_pseudos_num);
-  
+  if (! live_change_p
+      && sparseset_cardinality (pseudos_live) != live_pseudos_num)
+    {
+      live_change_p = true;
+      if (lra_dump_file != NULL)
+       EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, j)
+         if (! bitmap_bit_p (df_get_live_in (bb), j))
+           fprintf (lra_dump_file,
+                    "  r%d is added to live at bb%d start\n", j, bb->index);
+    }
   /* See if we'll need an increment at the end of this basic block.
      An increment is needed if the PSEUDOS_LIVE set is not empty,
      to make sure the finish points are set up correctly.  */
@@ -1322,11 +1331,16 @@ lra_create_live_ranges (bool all_p, bool dead_insn_p)
   if (lra_dump_file != NULL)
     fprintf (lra_dump_file, "Live info was changed -- recalculate it\n");
   /* Live info was changed on a bb border.  It means that some info,
-     e.g. about conflict regs, calls crossed may be wrong, live
-     ranges.  We need this info for allocation.  So recalcualate it
-     again.  */
+     e.g. about conflict regs, calls crossed, and live ranges may be
+     wrong.  We need this info for allocation.  So recalculate it
+     again but without removing dead insns which can change live info
+     again.  Repetitive live range calculations are expensive therefore
+     we stop here as we already have correct info although some
+     improvement in rare cases could be possible on this sub-pass if
+     we do dead insn elimination again (still the improvement may
+     happen later).  */
   lra_clear_live_ranges ();
-  bool res = lra_create_live_ranges_1 (all_p, dead_insn_p);
+  bool res = lra_create_live_ranges_1 (all_p, false);
   lra_assert (! res);
 }
 
index ebd899d..3528b18 100644 (file)
@@ -1,3 +1,8 @@
+2014-11-28  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/64087
+       *  gcc.dg/pr64087.c: New.
+
 2014-11-28  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR rtl-optimization/64037
diff --git a/gcc/testsuite/gcc.dg/pr64087.c b/gcc/testsuite/gcc.dg/pr64087.c
new file mode 100644 (file)
index 0000000..fe3c634
--- /dev/null
@@ -0,0 +1,35 @@
+/* PR rtl-optimization/64087 */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int printf (const char *, ...);
+
+int a[72], b, c, d, e;
+
+int
+main ()
+{
+  int h;
+  for (b = 0; b < 72; b++)
+    {
+      h = 1;
+      if (b)
+       h >>= 1;
+      a[b] = h;
+    }
+  for (; e; e++)
+    for (c = 0; c < 1;)
+      for (; d;)
+       {
+         printf ("0");
+         int g;
+         for (b = 0; b < 72; b++)
+           {
+             g = 1;
+             if (b)
+               g >>= 1;
+             a[b] = g;
+           }
+       }
+  return 0;
+}