Changes for DOM to use the new capability in the dom walker.

Jeff
commit 88806f8996419d50d00f33f5d9924a1638316e3b
Author: Jeff Law <l...@redhat.com>
Date:   Mon Dec 7 22:43:06 2015 -0700

        PR tree-optimization/68619
        * tree-ssa-dom.c (dom_opt_dom_walker::before_dom_children): Propgate
        return value from optimize_stmt.
        (dom_opt_dom_walker): Add new argument to dom_walker constructor.
        (pass_dominator:execute): If a block has an unreachable edge,
        remove all jump threads through any successor of the affected block.
        (record_equivalences_from_phis): Ignore alternative if the edge
        does not have EDGE_EXECUTABLE set.
        (single_incoming_edge_ignoring_loop_edges): Similarly.
        (optimize_stmt): If a gimple_code has a compile-time constant
        condition, return the edge taken for that constant value.  Also
        change the condition to true/false as necessary.

diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index aeb726c..88fc517 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -99,7 +99,7 @@ struct opt_stats_d
 static struct opt_stats_d opt_stats;
 
 /* Local functions.  */
-static void optimize_stmt (basic_block, gimple_stmt_iterator,
+static edge optimize_stmt (basic_block, gimple_stmt_iterator,
                           class const_and_copies *,
                           class avail_exprs_stack *);
 static tree lookup_avail_expr (gimple *, bool, class avail_exprs_stack *);
@@ -493,12 +493,12 @@ public:
   dom_opt_dom_walker (cdi_direction direction,
                      class const_and_copies *const_and_copies,
                      class avail_exprs_stack *avail_exprs_stack)
-    : dom_walker (direction),
+    : dom_walker (direction, true),
       m_const_and_copies (const_and_copies),
       m_avail_exprs_stack (avail_exprs_stack),
       m_dummy_cond (NULL) {}
 
-  virtual void before_dom_children (basic_block);
+  virtual edge before_dom_children (basic_block);
   virtual void after_dom_children (basic_block);
 
 private:
@@ -611,6 +611,36 @@ pass_dominator::execute (function *fun)
                             avail_exprs_stack);
   walker.walk (fun->cfg->x_entry_block_ptr);
 
+  /* Look for blocks where we cleared EDGE_EXECUTABLE on an outgoing
+     edge.  When found, remove jump threads which contain any outgoing
+     edge from the affected block.  */
+  if (cfg_altered)
+    {
+      FOR_EACH_BB_FN (bb, fun)
+       {
+         edge_iterator ei;
+         edge e;
+
+         /* First see if there are any edges without EDGE_EXECUTABLE
+            set.  */
+         bool found = false;
+         FOR_EACH_EDGE (e, ei, bb->succs)
+           {
+             if ((e->flags & EDGE_EXECUTABLE) == 0)
+               {
+                 found = true;
+                 break;
+               }
+           }
+
+         /* If there were any such edges found, then remove jump threads
+            containing any edge leaving BB.  */
+         if (found)
+           FOR_EACH_EDGE (e, ei, bb->succs)
+             remove_jump_threads_including (e);
+       }
+    }
+
   {
     gimple_stmt_iterator gsi;
     basic_block bb;
@@ -951,6 +981,11 @@ record_equivalences_from_phis (basic_block bb)
          if (lhs == t)
            continue;
 
+         /* If the associated edge is not marked as executable, then it
+            can be ignored.  */
+         if ((gimple_phi_arg_edge (phi, i)->flags & EDGE_EXECUTABLE) == 0)
+           continue;
+
          t = dom_valueize (t);
 
          /* If we have not processed an alternative yet, then set
@@ -997,6 +1032,10 @@ single_incoming_edge_ignoring_loop_edges (basic_block bb)
       if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
        continue;
 
+      /* We can safely ignore edges that are not executable.  */
+      if ((e->flags & EDGE_EXECUTABLE) == 0)
+       continue;
+
       /* If we have already seen a non-loop edge, then we must have
         multiple incoming non-loop edges and thus we return NULL.  */
       if (retval)
@@ -1294,7 +1333,7 @@ cprop_into_successor_phis (basic_block bb,
     }
 }
 
-void
+edge
 dom_opt_dom_walker::before_dom_children (basic_block bb)
 {
   gimple_stmt_iterator gsi;
@@ -1322,12 +1361,15 @@ dom_opt_dom_walker::before_dom_children (basic_block bb)
                                      m_avail_exprs_stack);
   m_avail_exprs_stack->pop_to_marker ();
 
+  edge taken_edge = NULL;
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-    optimize_stmt (bb, gsi, m_const_and_copies, m_avail_exprs_stack);
+    taken_edge
+      = optimize_stmt (bb, gsi, m_const_and_copies, m_avail_exprs_stack);
 
   /* Now prepare to process dominated blocks.  */
   record_edge_info (bb);
   cprop_into_successor_phis (bb, m_const_and_copies);
+  return taken_edge;
 }
 
 /* We have finished processing the dominator children of BB, perform
@@ -1694,7 +1736,7 @@ cprop_into_stmt (gimple *stmt)
       assignment is found, we map the value on the RHS of the assignment to
       the variable in the LHS in the CONST_AND_COPIES table.  */
 
-static void
+static edge
 optimize_stmt (basic_block bb, gimple_stmt_iterator si,
               class const_and_copies *const_and_copies,
               class avail_exprs_stack *avail_exprs_stack)
@@ -1703,6 +1745,7 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si,
   bool may_optimize_p;
   bool modified_p = false;
   bool was_noreturn;
+  edge retval = NULL;
 
   old_stmt = stmt = gsi_stmt (si);
   was_noreturn = is_gimple_call (stmt) && gimple_call_noreturn_p (stmt);
@@ -1823,7 +1866,7 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si,
                    fprintf (dump_file, "  Flagged to clear EH edges.\n");
                }
              release_defs (stmt);
-             return;
+             return retval;
            }
        }
     }
@@ -1849,25 +1892,19 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si,
 
       if (val && TREE_CODE (val) == INTEGER_CST)
        {
-         edge taken_edge = find_taken_edge (bb, val);
-         if (taken_edge)
+         retval = find_taken_edge (bb, val);
+         if (retval)
            {
-
-             /* We need to remove any queued jump threads that
-                reference outgoing edges from this block.  */
-             edge_iterator ei;
-             edge e;
-             FOR_EACH_EDGE (e, ei, bb->succs)
-               remove_jump_threads_including (e);
-
-             /* Now clean up the control statement at the end of
-                BB and remove unexecutable edges.  */
-             remove_ctrl_stmt_and_useless_edges (bb, taken_edge->dest);
-
-             /* Fixup the flags on the single remaining edge.  */
-             taken_edge->flags
-               &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE | EDGE_ABNORMAL);
-             taken_edge->flags |= EDGE_FALLTHRU;
+             /* Fix the condition to be either true or false.  */
+             if (gimple_code (stmt) == GIMPLE_COND)
+               {
+                 if (integer_zerop (val))
+                   gimple_cond_make_false (as_a <gcond *> (stmt));
+                 else if (integer_onep (val))
+                   gimple_cond_make_true (as_a <gcond *> (stmt));
+                 else
+                   gcc_unreachable ();
+               }
 
              /* Further simplifications may be possible.  */
              cfg_altered = true;
@@ -1887,6 +1924,7 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si,
          && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
        need_noreturn_fixup.safe_push (stmt);
     }
+  return retval;
 }
 
 /* Helper for walk_non_aliased_vuses.  Determine if we arrived at

Reply via email to