tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): Skip unreachable blocks...
authorRichard Biener <rguenther@suse.de>
Thu, 11 May 2017 09:16:00 +0000 (09:16 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 11 May 2017 09:16:00 +0000 (09:16 +0000)
2017-05-11  Richard Biener  <rguenther@suse.de>

* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
Skip unreachable blocks and destinations.
(eliminate): Move stmt removal and fixup ...
(fini_eliminate): ... here.  Skip inserted exprs.
(pass_pre::execute): Move fini_pre after fini_eliminate.
* tree-ssa-tailmerge.c: Include tree-cfgcleanup.h.
(tail_merge_optimize): Run cleanup_tree_cfg if requested by
PRE to get rid of dead code that has invalid SSA form and
split critical edges again.

From-SVN: r247882

gcc/ChangeLog
gcc/tree-ssa-pre.c
gcc/tree-ssa-tail-merge.c

index 9fe29bd..be20be0 100644 (file)
@@ -1,3 +1,15 @@
+2017-05-11  Richard Biener  <rguenther@suse.de>
+
+       * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
+       Skip unreachable blocks and destinations.
+       (eliminate): Move stmt removal and fixup ...
+       (fini_eliminate): ... here.  Skip inserted exprs.
+       (pass_pre::execute): Move fini_pre after fini_eliminate.
+       * tree-ssa-tailmerge.c: Include tree-cfgcleanup.h.
+       (tail_merge_optimize): Run cleanup_tree_cfg if requested by
+       PRE to get rid of dead code that has invalid SSA form and
+       split critical edges again.
+
 2017-05-11  Bin Cheng  <bin.cheng@arm.com>
 
        * rtlanal.c (rtx_cost): Handle TRUNCATE between tieable modes.
index 65cf523..38723df 100644 (file)
@@ -4196,9 +4196,14 @@ eliminate_dom_walker::before_dom_children (basic_block b)
   /* Mark new bb.  */
   el_avail_stack.safe_push (NULL_TREE);
 
-  /* ???  If we do nothing for unreachable blocks then this will confuse
-     tailmerging.  Eventually we can reduce its reliance on SCCVN now
-     that we fully copy/constant-propagate (most) things.  */
+  /* Skip unreachable blocks marked unreachable during the SCCVN domwalk.  */
+  edge_iterator ei;
+  edge e;
+  FOR_EACH_EDGE (e, ei, b->preds)
+    if (e->flags & EDGE_EXECUTABLE)
+      break;
+  if (! e)
+    return NULL;
 
   for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);)
     {
@@ -4695,10 +4700,8 @@ eliminate_dom_walker::before_dom_children (basic_block b)
     }
 
   /* Replace destination PHI arguments.  */
-  edge_iterator ei;
-  edge e;
   FOR_EACH_EDGE (e, ei, b->succs)
-    {
+    if (e->flags & EDGE_EXECUTABLE)
       for (gphi_iterator gsi = gsi_start_phis (e->dest);
           !gsi_end_p (gsi);
           gsi_next (&gsi))
@@ -4717,7 +4720,6 @@ eliminate_dom_walker::before_dom_children (basic_block b)
                gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true);
            }
        }
-    }
   return NULL;
 }
 
@@ -4743,9 +4745,6 @@ eliminate_dom_walker::after_dom_children (basic_block)
 static unsigned int
 eliminate (bool do_pre)
 {
-  gimple_stmt_iterator gsi;
-  gimple *stmt;
-
   need_eh_cleanup = BITMAP_ALLOC (NULL);
   need_ab_cleanup = BITMAP_ALLOC (NULL);
 
@@ -4761,6 +4760,18 @@ eliminate (bool do_pre)
   el_avail.release ();
   el_avail_stack.release ();
 
+  return el_todo;
+}
+
+/* Perform CFG cleanups made necessary by elimination.  */
+
+static unsigned 
+fini_eliminate (void)
+{
+  gimple_stmt_iterator gsi;
+  gimple *stmt;
+  unsigned todo = 0;
+
   /* We cannot remove stmts during BB walk, especially not release SSA
      names there as this confuses the VN machinery.  The stmts ending
      up in el_to_remove are either stores or simple copies.
@@ -4769,12 +4780,6 @@ eliminate (bool do_pre)
     {
       stmt = el_to_remove.pop ();
 
-      if (dump_file && (dump_flags & TDF_DETAILS))
-       {
-         fprintf (dump_file, "Removing dead stmt ");
-         print_gimple_stmt (dump_file, stmt, 0, 0);
-       }
-
       tree lhs;
       if (gimple_code (stmt) == GIMPLE_PHI)
        lhs = gimple_phi_result (stmt);
@@ -4782,8 +4787,15 @@ eliminate (bool do_pre)
        lhs = gimple_get_lhs (stmt);
 
       if (inserted_exprs
-         && TREE_CODE (lhs) == SSA_NAME)
-       bitmap_clear_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
+         && TREE_CODE (lhs) == SSA_NAME
+         && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (lhs)))
+       continue;
+
+      if (dump_file && (dump_flags & TDF_DETAILS))
+       {
+         fprintf (dump_file, "Removing dead stmt ");
+         print_gimple_stmt (dump_file, stmt, 0, 0);
+       }
 
       gsi = gsi_for_stmt (stmt);
       if (gimple_code (stmt) == GIMPLE_PHI)
@@ -4800,7 +4812,7 @@ eliminate (bool do_pre)
        }
 
       /* Removing a stmt may expose a forwarder block.  */
-      el_todo |= TODO_cleanup_cfg;
+      todo |= TODO_cleanup_cfg;
     }
   el_to_remove.release ();
 
@@ -4819,18 +4831,10 @@ eliminate (bool do_pre)
        }
 
       if (fixup_noreturn_call (stmt))
-       el_todo |= TODO_cleanup_cfg;
+       todo |= TODO_cleanup_cfg;
     }
   el_to_fixup.release ();
 
-  return el_todo;
-}
-
-/* Perform CFG cleanups made necessary by elimination.  */
-
-static unsigned 
-fini_eliminate (void)
-{
   bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup);
   bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup);
 
@@ -4844,8 +4848,8 @@ fini_eliminate (void)
   BITMAP_FREE (need_ab_cleanup);
 
   if (do_eh_cleanup || do_ab_cleanup)
-    return TODO_cleanup_cfg;
-  return 0;
+    todo |= TODO_cleanup_cfg;
+  return todo;
 }
 
 /* Borrow a bit of tree-ssa-dce.c for the moment.
@@ -5110,8 +5114,8 @@ pass_pre::execute (function *fun)
   remove_dead_inserted_code ();
 
   scev_finalize ();
-  fini_pre ();
   todo |= fini_eliminate ();
+  fini_pre ();
   loop_optimizer_finalize ();
 
   /* Restore SSA info before tail-merging as that resets it as well.  */
index 71f874d..8765fdd 100644 (file)
@@ -205,6 +205,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-sccvn.h"
 #include "cfgloop.h"
 #include "tree-eh.h"
+#include "tree-cfgcleanup.h"
 
 /* Describes a group of bbs with the same successors.  The successor bbs are
    cached in succs, and the successor edge flags are cached in succ_flags.
@@ -1717,6 +1718,16 @@ tail_merge_optimize (unsigned int todo)
 
   timevar_push (TV_TREE_TAIL_MERGE);
 
+  /* We enter from PRE which has critical edges split.  Elimination
+     does not process trivially dead code so cleanup the CFG if we
+     are told so.  And re-split critical edges then.  */
+  if (todo & TODO_cleanup_cfg)
+    {
+      cleanup_tree_cfg ();
+      todo &= ~TODO_cleanup_cfg;
+      split_critical_edges ();
+    }
+
   if (!dom_info_available_p (CDI_DOMINATORS))
     {
       /* PRE can leave us with unreachable blocks, remove them now.  */