re PR tree-optimization/79725 (Sinking opportunity missed if blocked by dead stmt)
authorRichard Biener <rguenther@suse.de>
Mon, 24 Apr 2017 07:48:47 +0000 (07:48 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 24 Apr 2017 07:48:47 +0000 (07:48 +0000)
2017-04-24  Richard Biener  <rguenther@suse.de>

PR tree-optimization/79725
* tree-ssa-sink.c (statement_sink_location): Return whether
failure reason was zero uses.  Move that check later.
(sink_code_in_bb): Deal with zero uses by removing the stmt
if possible.

* gcc.dg/tree-ssa/ssa-sink-15.c: New testcase.

From-SVN: r247091

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-15.c [new file with mode: 0644]
gcc/tree-ssa-sink.c

index a9c9a3698e625db5e09238347abade2c4cb231d8..1facf361a774e2befc50b18138a7fc057ca24e05 100644 (file)
@@ -1,3 +1,11 @@
+2017-04-24  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/79725
+       * tree-ssa-sink.c (statement_sink_location): Return whether
+       failure reason was zero uses.  Move that check later.
+       (sink_code_in_bb): Deal with zero uses by removing the stmt
+       if possible.
+
 2017-04-24  Richard Biener  <rguenther@suse.de>
 
        PR c++/2972
index 148901463f44a17cb873cb1363e782c7b10425dc..08ad07d3cd76d08cd27b58c4e016a3e8036ce481 100644 (file)
@@ -1,3 +1,8 @@
+2017-04-24  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/79725
+       * gcc.dg/tree-ssa/ssa-sink-15.c: New testcase.
+
 2017-04-24  Richard Biener  <rguenther@suse.de>
 
        PR c++/2972
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-15.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-15.c
new file mode 100644 (file)
index 0000000..66ddc4e
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR79725 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+_Complex double f(_Complex double x[])
+{
+  _Complex float p = 1.0;
+  for (int i = 0; i < 1000000; i++)
+    p = x[i];
+  return p;
+}
+
+/* Verify we end up with a single BB and no loop.  */
+/* { dg-final { scan-tree-dump-times "goto" 0 "optimized" } } */
index 7a9fcde4f9421cbc12f2c7c99812a5da5688ce7e..bb8d2ca97327dae726badfcb84fba000751b85a1 100644 (file)
@@ -244,7 +244,7 @@ select_best_block (basic_block early_bb,
 
 static bool
 statement_sink_location (gimple *stmt, basic_block frombb,
-                        gimple_stmt_iterator *togsi)
+                        gimple_stmt_iterator *togsi, bool *zero_uses_p)
 {
   gimple *use;
   use_operand_p one_use = NULL_USE_OPERAND_P;
@@ -254,6 +254,8 @@ statement_sink_location (gimple *stmt, basic_block frombb,
   ssa_op_iter iter;
   imm_use_iterator imm_iter;
 
+  *zero_uses_p = false;
+
   /* We only can sink assignments.  */
   if (!is_gimple_assign (stmt))
     return false;
@@ -263,10 +265,6 @@ statement_sink_location (gimple *stmt, basic_block frombb,
   if (def_p == NULL_DEF_OPERAND_P)
     return false;
 
-  /* Return if there are no immediate uses of this stmt.  */
-  if (has_zero_uses (DEF_FROM_PTR (def_p)))
-    return false;
-
   /* There are a few classes of things we can't or don't move, some because we
      don't have code to handle it, some because it's not profitable and some
      because it's not legal.
@@ -292,11 +290,17 @@ statement_sink_location (gimple *stmt, basic_block frombb,
   */
   if (stmt_ends_bb_p (stmt)
       || gimple_has_side_effects (stmt)
-      || gimple_has_volatile_ops (stmt)
       || (cfun->has_local_explicit_reg_vars
          && TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt))) == BLKmode))
     return false;
 
+  /* Return if there are no immediate uses of this stmt.  */
+  if (has_zero_uses (DEF_FROM_PTR (def_p)))
+    {
+      *zero_uses_p = true;
+      return false;
+    }
+
   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (DEF_FROM_PTR (def_p)))
     return false;
 
@@ -483,12 +487,23 @@ sink_code_in_bb (basic_block bb)
     {
       gimple *stmt = gsi_stmt (gsi);
       gimple_stmt_iterator togsi;
+      bool zero_uses_p;
 
-      if (!statement_sink_location (stmt, bb, &togsi))
+      if (!statement_sink_location (stmt, bb, &togsi, &zero_uses_p))
        {
+         gimple_stmt_iterator saved = gsi;
          if (!gsi_end_p (gsi))
            gsi_prev (&gsi);
-         last = false;
+         /* If we face a dead stmt remove it as it possibly blocks
+            sinking of uses.  */
+         if (zero_uses_p
+             && ! gimple_vdef (stmt))
+           {
+             gsi_remove (&saved, true);
+             release_defs (stmt);
+           }
+         else
+           last = false;
          continue;
        }
       if (dump_file)