re PR tree-optimization/69347 (excessive compile time with -O2)
authorJeff Law <law@redhat.com>
Fri, 22 Jan 2016 20:18:59 +0000 (13:18 -0700)
committerJeff Law <law@gcc.gnu.org>
Fri, 22 Jan 2016 20:18:59 +0000 (13:18 -0700)
PR middle-end/69347
* tree-ssa-dom.c (back_propagate_equivalences): Factored out of
record_temporary_equivalences.  Rewritten to avoid unnecessary calls
into dominated_by_p.
(cprop_into_successor_phis): Avoid unnecessary tests.

From-SVN: r232745

gcc/ChangeLog
gcc/tree-ssa-dom.c

index 414d8ec80de86ee2e50624af9d801d9b6553503f..5dfdfc59ba24b6b5da62fd19e9a22332db3b1089 100644 (file)
@@ -1,3 +1,11 @@
+2016-01-21  Jeff Law  <law@redhat.com>
+
+       PR middle-end/69347
+       * tree-ssa-dom.c (back_propagate_equivalences): Factored out of
+       record_temporary_equivalences.  Rewritten to avoid unnecessary calls
+       into dominated_by_p.
+       (cprop_into_successor_phis): Avoid unnecessary tests.
+
 2016-01-22  Richard Henderson  <rth@redhat.com>
 
        PR target/69416
index 84c9a6a09f366047763b7be1ce73fb0498209c8d..b690d927b6cc728bab2dd3a7e053b0c78837e366 100644 (file)
@@ -819,6 +819,74 @@ dom_valueize (tree t)
   return t;
 }
 
+/* We have just found an equivalence for LHS on an edge E.
+   Look backwards to other uses of LHS and see if we can derive
+   additional equivalences that are valid on edge E.  */
+static void
+back_propagate_equivalences (tree lhs, edge e,
+                            class const_and_copies *const_and_copies)
+{
+  use_operand_p use_p;
+  imm_use_iterator iter;
+  bitmap domby = NULL;
+  basic_block dest = e->dest;
+
+  /* Iterate over the uses of LHS to see if any dominate E->dest.
+     If so, they may create useful equivalences too.
+
+     ???  If the code gets re-organized to a worklist to catch more
+     indirect opportunities and it is made to handle PHIs then this
+     should only consider use_stmts in basic-blocks we have already visited.  */
+  FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
+    {
+      gimple *use_stmt = USE_STMT (use_p);
+
+      /* Often the use is in DEST, which we trivially know we can't use.
+        This is cheaper than the dominator set tests below.  */
+      if (dest == gimple_bb (use_stmt))
+       continue;
+
+      /* Filter out statements that can never produce a useful
+        equivalence.  */
+      tree lhs2 = gimple_get_lhs (use_stmt);
+      if (!lhs2 || TREE_CODE (lhs2) != SSA_NAME)
+       continue;
+
+      /* Profiling has shown the domination tests here can be fairly
+        expensive.  We get significant improvements by building the
+        set of blocks that dominate BB.  We can then just test
+        for set membership below.
+
+        We also initialize the set lazily since often the only uses
+        are going to be in the same block as DEST.  */
+      if (!domby)
+       {
+         domby = BITMAP_ALLOC (NULL);
+         basic_block bb = get_immediate_dominator (CDI_DOMINATORS, dest);
+         while (bb)
+           {
+             bitmap_set_bit (domby, bb->index);
+             bb = get_immediate_dominator (CDI_DOMINATORS, bb);
+           }
+       }
+
+      /* This tests if USE_STMT does not dominate DEST.  */
+      if (!bitmap_bit_p (domby, gimple_bb (use_stmt)->index))
+       continue;
+
+      /* At this point USE_STMT dominates DEST and may result in a
+        useful equivalence.  Try to simplify its RHS to a constant
+        or SSA_NAME.  */
+      tree res = gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize,
+                                                no_follow_ssa_edges);
+      if (res && (TREE_CODE (res) == SSA_NAME || is_gimple_min_invariant (res)))
+       record_equality (lhs2, res, const_and_copies);
+    }
+
+  if (domby)
+    BITMAP_FREE (domby);
+}
+
 /* Record into CONST_AND_COPIES and AVAIL_EXPRS_STACK any equivalences implied
    by traversing edge E (which are cached in E->aux).
 
@@ -836,19 +904,23 @@ record_temporary_equivalences (edge e,
   if (edge_info)
     {
       cond_equivalence *eq;
+      /* If we have 0 = COND or 1 = COND equivalences, record them
+        into our expression hash tables.  */
+      for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
+       record_cond (eq, avail_exprs_stack);
+
       tree lhs = edge_info->lhs;
-      tree rhs = edge_info->rhs;
+      if (!lhs || TREE_CODE (lhs) != SSA_NAME)
+       return;
 
-      /* If we have a simple NAME = VALUE equivalence, record it.  */
-      if (lhs)
-       record_equality (lhs, rhs, const_and_copies);
+      /* Record the simple NAME = VALUE equivalence.  */
+      tree rhs = edge_info->rhs;
+      record_equality (lhs, rhs, const_and_copies);
 
       /* If LHS is an SSA_NAME and RHS is a constant integer and LHS was
         set via a widening type conversion, then we may be able to record
         additional equivalences.  */
-      if (lhs
-         && TREE_CODE (lhs) == SSA_NAME
-         && TREE_CODE (rhs) == INTEGER_CST)
+      if (TREE_CODE (rhs) == INTEGER_CST)
        {
          gimple *defstmt = SSA_NAME_DEF_STMT (lhs);
 
@@ -875,45 +947,10 @@ record_temporary_equivalences (edge e,
            }
        }
 
-      /* If LHS is an SSA_NAME with a new equivalency then try if
-         stmts with uses of that LHS that dominate the edge destination
-        simplify and allow further equivalences to be recorded.  */
-      if (lhs && TREE_CODE (lhs) == SSA_NAME)
-       {
-         use_operand_p use_p;
-         imm_use_iterator iter;
-         FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
-           {
-             gimple *use_stmt = USE_STMT (use_p);
-
-             /* Only bother to record more equivalences for lhs that
-                can be directly used by e->dest.
-                ???  If the code gets re-organized to a worklist to
-                catch more indirect opportunities and it is made to
-                handle PHIs then this should only consider use_stmts
-                in basic-blocks we have already visited.  */
-             if (e->dest == gimple_bb (use_stmt)
-                 || !dominated_by_p (CDI_DOMINATORS,
-                                     e->dest, gimple_bb (use_stmt)))
-               continue;
-             tree lhs2 = gimple_get_lhs (use_stmt);
-             if (lhs2 && TREE_CODE (lhs2) == SSA_NAME)
-               {
-                 tree res
-                   = gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize,
-                                                     no_follow_ssa_edges);
-                 if (res
-                     && (TREE_CODE (res) == SSA_NAME
-                         || is_gimple_min_invariant (res)))
-                   record_equality (lhs2, res, const_and_copies);
-               }
-           }
-       }
-
-      /* If we have 0 = COND or 1 = COND equivalences, record them
-        into our expression hash tables.  */
-      for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
-       record_cond (eq, avail_exprs_stack);
+      /* Any equivalence found for LHS may result in additional
+        equivalences for other uses of LHS that we have already
+        processed.  */
+      back_propagate_equivalences (lhs, e, const_and_copies);
     }
 }
 
@@ -1321,8 +1358,6 @@ cprop_into_successor_phis (basic_block bb,
          new_val = SSA_NAME_VALUE (orig_val);
          if (new_val
              && new_val != orig_val
-             && (TREE_CODE (new_val) == SSA_NAME
-                 || is_gimple_min_invariant (new_val))
              && may_propagate_copy (orig_val, new_val))
            propagate_value (orig_p, new_val);
        }