2011-10-11 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Oct 2011 11:57:23 +0000 (11:57 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Oct 2011 11:57:23 +0000 (11:57 +0000)
PR tree-optimization/50204
* tree-ssa-alias.c (get_continuation_for_phi_1): Split out
two argument handling from ...
(get_continuation_for_phi): ... here.  Handle arbitrary number
of PHI args.

* gcc.dg/tree-ssa/ssa-fre-36.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179799 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-36.c [new file with mode: 0644]
gcc/tree-ssa-alias.c

index e83c515..8e42253 100644 (file)
@@ -1,3 +1,11 @@
+2011-10-11  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/50204
+       * tree-ssa-alias.c (get_continuation_for_phi_1): Split out
+       two argument handling from ...
+       (get_continuation_for_phi): ... here.  Handle arbitrary number
+       of PHI args.
+
 2011-10-11  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/33067
index 48dcf8f..06a16b0 100644 (file)
@@ -1,3 +1,8 @@
+2011-10-11  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/50204
+       * gcc.dg/tree-ssa/ssa-fre-36.c: New testcase.
+
 2011-10-11  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
        * gcc.target/s390/20090223-1.c: Add -Wno-attributes.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-36.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-36.c
new file mode 100644 (file)
index 0000000..a8a2dba
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1-details" } */
+
+extern int opening;
+extern int middle_game;
+int s;
+extern int d[1];
+void PreEvaluate(int wtm)
+{
+  int i, j;
+  if (opening) {
+      d[0]=1;
+  }
+  else if (middle_game) {
+      d[0]=-1;
+  }
+  if (4 != opening) {
+      return;
+  }
+  s = 1;
+}
+
+/* We should be able to CSE the second load of opening.  */
+
+/* { dg-final { scan-tree-dump "Replaced opening" "fre1" } } */
+/* { dg-final { cleanup-tree-dump "fre1" } } */
index 506e778..c63b5a8 100644 (file)
@@ -1875,6 +1875,60 @@ maybe_skip_until (gimple phi, tree target, ao_ref *ref,
   return true;
 }
 
+/* For two PHI arguments ARG0 and ARG1 try to skip non-aliasing code
+   until we hit the phi argument definition that dominates the other one.
+   Return that, or NULL_TREE if there is no such definition.  */
+
+static tree
+get_continuation_for_phi_1 (gimple phi, tree arg0, tree arg1,
+                           ao_ref *ref, bitmap *visited)
+{
+  gimple def0 = SSA_NAME_DEF_STMT (arg0);
+  gimple def1 = SSA_NAME_DEF_STMT (arg1);
+  tree common_vuse;
+
+  if (arg0 == arg1)
+    return arg0;
+  else if (gimple_nop_p (def0)
+          || (!gimple_nop_p (def1)
+              && dominated_by_p (CDI_DOMINATORS,
+                                 gimple_bb (def1), gimple_bb (def0))))
+    {
+      if (maybe_skip_until (phi, arg0, ref, arg1, visited))
+       return arg0;
+    }
+  else if (gimple_nop_p (def1)
+          || dominated_by_p (CDI_DOMINATORS,
+                             gimple_bb (def0), gimple_bb (def1)))
+    {
+      if (maybe_skip_until (phi, arg1, ref, arg0, visited))
+       return arg1;
+    }
+  /* Special case of a diamond:
+       MEM_1 = ...
+       goto (cond) ? L1 : L2
+       L1: store1 = ...    #MEM_2 = vuse(MEM_1)
+          goto L3
+       L2: store2 = ...    #MEM_3 = vuse(MEM_1)
+       L3: MEM_4 = PHI<MEM_2, MEM_3>
+     We were called with the PHI at L3, MEM_2 and MEM_3 don't
+     dominate each other, but still we can easily skip this PHI node
+     if we recognize that the vuse MEM operand is the same for both,
+     and that we can skip both statements (they don't clobber us).
+     This is still linear.  Don't use maybe_skip_until, that might
+     potentially be slow.  */
+  else if ((common_vuse = gimple_vuse (def0))
+          && common_vuse == gimple_vuse (def1))
+    {
+      if (!stmt_may_clobber_ref_p_1 (def0, ref)
+         && !stmt_may_clobber_ref_p_1 (def1, ref))
+       return common_vuse;
+    }
+
+  return NULL_TREE;
+}
+
+
 /* Starting from a PHI node for the virtual operand of the memory reference
    REF find a continuation virtual operand that allows to continue walking
    statements dominating PHI skipping only statements that cannot possibly
@@ -1890,53 +1944,24 @@ get_continuation_for_phi (gimple phi, ao_ref *ref, bitmap *visited)
   if (nargs == 1)
     return PHI_ARG_DEF (phi, 0);
 
-  /* For two arguments try to skip non-aliasing code until we hit
-     the phi argument definition that dominates the other one.  */
-  if (nargs == 2)
+  /* For two or more arguments try to pairwise skip non-aliasing code
+     until we hit the phi argument definition that dominates the other one.  */
+  else if (nargs >= 2)
     {
       tree arg0 = PHI_ARG_DEF (phi, 0);
-      tree arg1 = PHI_ARG_DEF (phi, 1);
-      gimple def0 = SSA_NAME_DEF_STMT (arg0);
-      gimple def1 = SSA_NAME_DEF_STMT (arg1);
-      tree common_vuse;
-
-      if (arg0 == arg1)
-       return arg0;
-      else if (gimple_nop_p (def0)
-              || (!gimple_nop_p (def1)
-                  && dominated_by_p (CDI_DOMINATORS,
-                                     gimple_bb (def1), gimple_bb (def0))))
-       {
-         if (maybe_skip_until (phi, arg0, ref, arg1, visited))
-           return arg0;
-       }
-      else if (gimple_nop_p (def1)
-              || dominated_by_p (CDI_DOMINATORS,
-                                 gimple_bb (def0), gimple_bb (def1)))
-       {
-         if (maybe_skip_until (phi, arg1, ref, arg0, visited))
-           return arg1;
-       }
-      /* Special case of a diamond:
-          MEM_1 = ...
-          goto (cond) ? L1 : L2
-          L1: store1 = ...    #MEM_2 = vuse(MEM_1)
-              goto L3
-          L2: store2 = ...    #MEM_3 = vuse(MEM_1)
-          L3: MEM_4 = PHI<MEM_2, MEM_3>
-        We were called with the PHI at L3, MEM_2 and MEM_3 don't
-        dominate each other, but still we can easily skip this PHI node
-        if we recognize that the vuse MEM operand is the same for both,
-        and that we can skip both statements (they don't clobber us).
-        This is still linear.  Don't use maybe_skip_until, that might
-        potentially be slow.  */
-      else if ((common_vuse = gimple_vuse (def0))
-              && common_vuse == gimple_vuse (def1))
+      tree arg1;
+      unsigned i = 1;
+      do
        {
-         if (!stmt_may_clobber_ref_p_1 (def0, ref)
-             && !stmt_may_clobber_ref_p_1 (def1, ref))
-           return common_vuse;
+         arg1 = PHI_ARG_DEF (phi, i);
+         arg0 = get_continuation_for_phi_1 (phi, arg0, arg1, ref, visited);
+         if (!arg0)
+           return NULL_TREE;
+
        }
+      while (++i < nargs);
+
+      return arg0;
     }
 
   return NULL_TREE;