diff mbox

patch to fix PR64087

Message ID 5478975A.1090400@redhat.com
State New
Headers show

Commit Message

Vladimir Makarov Nov. 28, 2014, 3:40 p.m. UTC
The following patch fixes

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64087

The patch was bootstrapped and tested on x86-64.

Committed as rev. 218162.

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.
diff mbox

Patch

Index: lra-lives.c
===================================================================
--- lra-lives.c	(revision 218129)
+++ lra-lives.c	(working copy)
@@ -971,14 +971,23 @@  process_bb_lives (basic_block bb, int &c
       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
   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: testsuite/gcc.dg/pr64087.c
===================================================================
--- testsuite/gcc.dg/pr64087.c	(revision 0)
+++ testsuite/gcc.dg/pr64087.c	(working copy)
@@ -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;
+}