re PR debug/89463 (debug information for iterator of an empty loop is gone (at -O3))
authorRichard Biener <rguenther@suse.de>
Wed, 27 Mar 2019 09:31:53 +0000 (09:31 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 27 Mar 2019 09:31:53 +0000 (09:31 +0000)
2019-03-27  Richard Biener  <rguenther@suse.de>

PR tree-optimization/89463
* tree-ssa-dce.c (remove_dead_stmt): Take output vector to
queue edges to remove.
(eliminate_unnecessary_stmts): Remove dead PHIs alongside
dead stmts.  Delay edge removal until PHIs are removed to
make debug-stmt creation not confused by seemingly degenerate
PHIs.

* gcc.dg/guality/pr89463.c: New testcase.

From-SVN: r269961

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/guality/pr89463.c [new file with mode: 0644]
gcc/tree-ssa-dce.c

index 8055a646474a075e6b5b99ed6fd4c8c090a006f9..07a1333cee03369bd24bedcf490f601d57d88431 100644 (file)
@@ -1,3 +1,13 @@
+2019-03-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/89463
+       * tree-ssa-dce.c (remove_dead_stmt): Take output vector to
+       queue edges to remove.
+       (eliminate_unnecessary_stmts): Remove dead PHIs alongside
+       dead stmts.  Delay edge removal until PHIs are removed to
+       make debug-stmt creation not confused by seemingly degenerate
+       PHIs.
+
 2019-03-27  Alan Modra  <amodra@gmail.com>
 
        * config/rs6000/rs6000.h: Rename NON_SPECIAL_REGS to GEN_OR_FLOAT_REGS
index 2048487d876e549c2f0030b9e9502a377119a1ce..ef4a55b0c3c6892a933a15a91f163e6d50c9fa57 100644 (file)
@@ -1,3 +1,8 @@
+2019-03-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/89463
+       * gcc.dg/guality/pr89463.c: New testcase.
+
 2019-03-26  Uroš Bizjak  <ubizjak@gmail.com>
 
        PR target/89827
diff --git a/gcc/testsuite/gcc.dg/guality/pr89463.c b/gcc/testsuite/gcc.dg/guality/pr89463.c
new file mode 100644 (file)
index 0000000..3abd6cd
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+void __attribute__((noinline))
+optimize_me_not ()
+{
+  __asm__ volatile ("" : : : "memory");
+}
+int a;
+int main()
+{
+  int i;
+  for (; a < 10; a++)
+    i = 0;
+  for (; i < 6; i++)
+    ;
+  /* i may very well be optimized out, so we cannot test for i == 6.
+     Instead test i + 1 which will make the test UNSUPPORTED if i
+     is optimized out.  Since the test previously had wrong debug
+     with i == 0 this is acceptable.  Optimally we'd produce a
+     debug stmt for the final value of the loop which would fix
+     the UNSUPPORTED cases.  */
+  optimize_me_not(); /* { dg-final { gdb-test . "i + 1" "7" } } */
+  return 0;
+}
index 7dd8d58539e6473ab9ed0ecad4c9d57a521e8dcd..c0e122722c0dcfa70b455edaef97779f760c4494 100644 (file)
@@ -985,7 +985,8 @@ remove_dead_phis (basic_block bb)
    containing I so that we don't have to look it up.  */
 
 static void
-remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb)
+remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb,
+                 vec<edge> &to_remove_edges)
 {
   gimple *stmt = gsi_stmt (*i);
 
@@ -1045,20 +1046,17 @@ remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb)
       e->flags |= EDGE_FALLTHRU;
 
       /* Remove the remaining outgoing edges.  */
-      for (ei = ei_start (bb->succs); (e2 = ei_safe_edge (ei)); )
+      FOR_EACH_EDGE (e2, ei, bb->succs)
        if (e != e2)
          {
-           cfg_altered = true;
            /* If we made a BB unconditionally exit a loop or removed
               an entry into an irreducible region, then this transform
               alters the set of BBs in the loop.  Schedule a fixup.  */
            if (loop_exit_edge_p (bb->loop_father, e)
                || (e2->dest->flags & BB_IRREDUCIBLE_LOOP))
              loops_state_set (LOOPS_NEED_FIXUP);
-           remove_edge (e2);
+           to_remove_edges.safe_push (e2);
          }
-       else
-         ei_next (&ei);
     }
 
   /* If this is a store into a variable that is being optimized away,
@@ -1201,6 +1199,7 @@ eliminate_unnecessary_stmts (void)
   gimple *stmt;
   tree call;
   vec<basic_block> h;
+  auto_vec<edge> to_remove_edges;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "\nEliminating unnecessary statements:\n");
@@ -1287,7 +1286,7 @@ eliminate_unnecessary_stmts (void)
                }
              if (!is_gimple_debug (stmt))
                something_changed = true;
-             remove_dead_stmt (&gsi, bb);
+             remove_dead_stmt (&gsi, bb, to_remove_edges);
            }
          else if (is_gimple_call (stmt))
            {
@@ -1331,7 +1330,7 @@ eliminate_unnecessary_stmts (void)
                      {
                      case IFN_GOMP_SIMD_LANE:
                      case IFN_ASAN_POISON:
-                       remove_dead_stmt (&gsi, bb);
+                       remove_dead_stmt (&gsi, bb, to_remove_edges);
                        break;
                      default:
                        break;
@@ -1354,6 +1353,9 @@ eliminate_unnecessary_stmts (void)
                  }
            }
        }
+
+      /* Remove dead PHI nodes.  */
+      something_changed |= remove_dead_phis (bb);
     }
 
   h.release ();
@@ -1361,10 +1363,16 @@ eliminate_unnecessary_stmts (void)
   /* Since we don't track liveness of virtual PHI nodes, it is possible that we
      rendered some PHI nodes unreachable while they are still in use.
      Mark them for renaming.  */
-  if (cfg_altered)
+  if (!to_remove_edges.is_empty ())
     {
       basic_block prev_bb;
 
+      /* Remove edges.  We've delayed this to not get bogus debug stmts
+         during PHI node removal.  */
+      for (unsigned i = 0; i < to_remove_edges.length (); ++i)
+       remove_edge (to_remove_edges[i]);
+      cfg_altered = true;
+
       find_unreachable_blocks ();
 
       /* Delete all unreachable basic blocks in reverse dominator order.  */
@@ -1430,11 +1438,6 @@ eliminate_unnecessary_stmts (void)
            }
        }
     }
-  FOR_EACH_BB_FN (bb, cfun)
-    {
-      /* Remove dead PHI nodes.  */
-      something_changed |= remove_dead_phis (bb);
-    }
 
   if (bb_postorder)
     free (bb_postorder);