re PR tree-optimization/90316 (large compile time increase in opt / alias stmt walkin...
authorRichard Biener <rguenther@suse.de>
Mon, 6 May 2019 08:54:40 +0000 (08:54 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 6 May 2019 08:54:40 +0000 (08:54 +0000)
2019-05-06  Richard Biener  <rguenther@suse.de>

PR tree-optimization/90316
* tree-ssa-alias.c (maybe_skip_until): Pass in target BB,
compute target on demand.
(get_continuation_for_phi): Remove code walking stmts to
get to a target virtual operand which could end up being
quadratic.

From-SVN: r270902

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

index 9db79406e07ad13e7c9fe45040bcdc7165961166..c5ca9cd7b19f28f6fb5d0b3f3a0e57e71f1c373d 100644 (file)
@@ -1,3 +1,12 @@
+2019-05-06  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/90316
+       * tree-ssa-alias.c (maybe_skip_until): Pass in target BB,
+       compute target on demand.
+       (get_continuation_for_phi): Remove code walking stmts to
+       get to a target virtual operand which could end up being
+       quadratic.
+
 2019-05-06  Martin Liska  <mliska@suse.cz>
 
        PR sanitizer/90312
index c0f67d1e17ab209d49f86c8c1780e4b3ebcf7743..4d00d381542c6ddb01f375529244130cb2f144b1 100644 (file)
@@ -2598,8 +2598,8 @@ stmt_kills_ref_p (gimple *stmt, tree ref)
    case false is returned.  The walk starts with VUSE, one argument of PHI.  */
 
 static bool
-maybe_skip_until (gimple *phi, tree target, ao_ref *ref,
-                 tree vuse, unsigned int *cnt, bitmap *visited,
+maybe_skip_until (gimple *phi, tree &target, basic_block target_bb,
+                 ao_ref *ref, tree vuse, unsigned int *cnt, bitmap *visited,
                  bool abort_on_visited,
                  void *(*translate)(ao_ref *, tree, void *, bool *),
                  void *data)
@@ -2615,6 +2615,19 @@ maybe_skip_until (gimple *phi, tree target, ao_ref *ref,
   while (vuse != target)
     {
       gimple *def_stmt = SSA_NAME_DEF_STMT (vuse);
+      /* If we are searching for the target VUSE by walking up to
+         TARGET_BB dominating the original PHI we are finished once
+        we reach a default def or a definition in a block dominating
+        that block.  Update TARGET and return.  */
+      if (!target
+         && (gimple_nop_p (def_stmt)
+             || dominated_by_p (CDI_DOMINATORS,
+                                target_bb, gimple_bb (def_stmt))))
+       {
+         target = vuse;
+         return true;
+       }
+
       /* Recurse for PHI nodes.  */
       if (gimple_code (def_stmt) == GIMPLE_PHI)
        {
@@ -2698,49 +2711,17 @@ get_continuation_for_phi (gimple *phi, ao_ref *ref,
       arg0 = NULL_TREE;
     }
   /* If not, look if we can reach such candidate by walking defs
-     of a PHI arg without crossing other PHIs.  */
-  if (! arg0)
-    for (i = 0; i < nargs; ++i)
-      {
-       arg0 = PHI_ARG_DEF (phi, i);
-       gimple *def = SSA_NAME_DEF_STMT (arg0);
-       /* Backedges can't work.  */
-       if (dominated_by_p (CDI_DOMINATORS,
-                           gimple_bb (def), phi_bb))
-         continue;
-       /* See below.  */
-       if (gimple_code (def) == GIMPLE_PHI)
-         continue;
-       while (! dominated_by_p (CDI_DOMINATORS,
-                                phi_bb, gimple_bb (def)))
-         {
-           arg0 = gimple_vuse (def);
-           if (SSA_NAME_IS_DEFAULT_DEF (arg0))
-             break;
-           def = SSA_NAME_DEF_STMT (arg0);
-           if (gimple_code (def) == GIMPLE_PHI)
-             {
-               /* Do not try to look through arbitrarily complicated
-                  CFGs.  For those looking for the first VUSE starting
-                  from the end of the immediate dominator of phi_bb
-                  is likely faster.  */
-               arg0 = NULL_TREE;
-               goto next;
-             }
-         }
-       break;
-next:;
-      }
-  if (! arg0)
-    return NULL_TREE;
+     until we hit the immediate dominator.  maybe_skip_until will
+     do that for us.  */
+  basic_block dom = get_immediate_dominator (CDI_DOMINATORS, phi_bb);
 
-  /* Then check against the found candidate.  */
+  /* Then check against the (to be) found candidate.  */
   for (i = 0; i < nargs; ++i)
     {
       arg1 = PHI_ARG_DEF (phi, i);
       if (arg1 == arg0)
        ;
-      else if (! maybe_skip_until (phi, arg0, ref, arg1, cnt, visited,
+      else if (! maybe_skip_until (phi, arg0, dom, ref, arg1, cnt, visited,
                                   abort_on_visited,
                                   /* Do not translate when walking over
                                      backedges.  */