public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/guojiufu/heads/guojiufu-branch)] Update according Richi comments
@ 2021-06-02  4:14 Jiu Fu Guo
  0 siblings, 0 replies; only message in thread
From: Jiu Fu Guo @ 2021-06-02  4:14 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:252fee171793af1406fe4a44e6800cd53ff9fcbd

commit 252fee171793af1406fe4a44e6800cd53ff9fcbd
Author: Jiufu Guo <guojiufu@linux.ibm.com>
Date:   Mon May 31 17:19:10 2021 +0800

    Update according Richi comments

Diff:
---
 gcc/testsuite/gcc.dg/loop-split2.c | 54 ++++++++++++++++++++++++++++++++++++
 gcc/tree-ssa-loop-split.c          | 57 +++++++++++++++++++++++++-------------
 2 files changed, 91 insertions(+), 20 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/loop-split2.c b/gcc/testsuite/gcc.dg/loop-split2.c
new file mode 100644
index 00000000000..a10d0ebbf2d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/loop-split2.c
@@ -0,0 +1,54 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fdump-tree-lsplit-details" } */
+
+extern void abort (void);
+extern void exit (int);
+
+#define NI __attribute__ ((noinline))
+
+void NI
+foo (int *a, int *b, unsigned char l, unsigned char n)
+{
+  while (++l != n)
+    a[l] = b[l] + 1;
+}
+
+unsigned NI
+bar (int *a, int *b, unsigned char l, unsigned char n)
+{
+  while (l++ != n)
+    if (a[l] != b[l])
+      break;
+
+  return l;
+}
+
+int a[258];
+int b[258];
+
+int main()
+{
+  __builtin_memcpy (b, a, sizeof (a));
+
+  if (bar (a, b, 3, 8) != 9)
+    abort ();
+
+  if (bar (a, b, 8, 3) != 4)
+    abort ();
+
+  b[100] += 1;
+  if (bar (a, b, 90, 110) != 100)
+    abort ();
+
+  if (bar (a, b, 110, 105) != 100)
+    abort ();
+
+  foo (a, b, 99, 99);
+  a[99] = b[99] + 1;
+  for (int i = 0; i < 127; i++)
+    if (a[i] != b[i] + 1)
+      abort();
+
+  exit (0);
+}
+
diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c
index 5c1742b5ff4..0428b0abea6 100644
--- a/gcc/tree-ssa-loop-split.c
+++ b/gcc/tree-ssa-loop-split.c
@@ -230,8 +230,10 @@ easy_exit_values (class loop *loop)
    conditional).  I.e. the second loop can now be entered either
    via the original entry or via NEW_E, so the entry values of LOOP2
    phi nodes are either the original ones or those at the exit
-   of LOOP1.  Insert new phi nodes in LOOP2 pre-header reflecting
-   this.  The loops need to fulfill easy_exit_values().  */
+   of LOOP1.  Selecting the previous value instead next value as the
+   exit value of LOOP1 if USE_PREV is true.  Insert new phi nodes in
+   LOOP2 pre-header reflecting this.  The loops need to fulfill
+   easy_exit_values().  */
 
 static void
 connect_loop_phis (class loop *loop1, class loop *loop2, edge new_e,
@@ -1596,9 +1598,8 @@ split_loop_on_cond (struct loop *loop)
   return do_split;
 }
 
-/* Check if the LOOP exit branch likes "if (idx != bound)",
-   Return the branch edge which exit loop, if overflow/wrap
-   may happen on "idx".  */
+/* Check if the LOOP exit branch is like "if (idx != bound)",
+   Return the branch edge which exit loop, if wrap may happen on "idx".  */
 
 static edge
 get_ne_cond_branch (struct loop *loop)
@@ -1609,7 +1610,7 @@ get_ne_cond_branch (struct loop *loop)
   auto_vec<edge> edges = get_loop_exit_edges (loop);
   FOR_EACH_VEC_ELT (edges, i, e)
     {
-      /* Check if there is possible wrap/overflow.  */
+      /* Check if there is possible wrap.  */
       class tree_niter_desc niter;
       if (!number_of_iterations_exit (loop, e, &niter, false, false))
 	continue;
@@ -1618,40 +1619,50 @@ get_ne_cond_branch (struct loop *loop)
       if (niter.cmp != NE_EXPR)
 	continue;
 
-      /* Check loop is simple to split.  */
+      /* If exit edge is just before the empty latch, it is easy to link
+	 the split loops: just jump from the exit edge of one loop to the
+	 header of new loop.  */
       if (single_pred_p (loop->latch)
 	  && single_pred_edge (loop->latch)->src == e->src
-	  && (gsi_end_p (gsi_start_nondebug_bb (loop->latch))))
+	  && empty_block_p (loop->latch))
 	return e;
 
-      /* Simple header.  */
+      /* If exit edge is at end of header, and header contains i++ or ++i,
+	 only, it is simple to link the split loops:  jump from the end of
+	 one loop header to the new loop header, and use unchanged PHI
+	 result of first loop as the entry PHI value of the second loop.  */
       if (e->src == loop->header)
 	{
-	  if (get_virtual_phi (e->src))
-	    continue;
-
 	  /* Only one phi.  */
 	  gphi_iterator psi = gsi_start_phis (e->src);
 	  if (gsi_end_p (psi))
 	    continue;
+	  gphi *phi = psi.phi ();
 	  gsi_next (&psi);
 	  if (!gsi_end_p (psi))
 	    continue;
 
-	  /* ++i or ++i */
-	  gimple_stmt_iterator gsi = gsi_start_bb (e->src);
-	  if (gsi_end_p (gsi))
-	    continue;
-
+	  /* Get the idx from last stmt (the gcond) of e->src.  */
 	  gimple *gc = last_stmt (e->src);
+	  gcc_assert (gimple_code (gc) == GIMPLE_COND);
 	  tree idx = gimple_cond_lhs (gc);
 	  if (expr_invariant_in_loop_p (loop, idx))
 	    idx = gimple_cond_rhs (gc);
 
+	  tree next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
+	  tree prev = PHI_RESULT (phi);
+	  if (idx != prev && idx != next)
+	    continue;
+
+	  /* ++i or ++i */
+	  gimple_stmt_iterator gsi
+	    = gsi_start_nondebug_after_labels_bb (e->src);
+	  if (gsi_end_p (gsi))
+	    continue;
+
 	  gimple *s1 = gsi_stmt (gsi);
-	  if (!(is_gimple_assign (s1) && idx
-		&& (idx == gimple_assign_lhs (s1)
-		    || idx == gimple_assign_rhs1 (s1))))
+	  if (!is_gimple_assign (s1) || gimple_assign_lhs (s1) != next
+	      || gimple_assign_rhs1 (s1) != prev)
 	    continue;
 
 	  gsi_next (&gsi);
@@ -1730,6 +1741,8 @@ split_ne_loop (struct loop *loop, edge cond_e)
 L_H:
  if (i!=N)
    S;
+ else
+   goto EXIT;
  i++;
  goto L_H;
 
@@ -1738,11 +1751,15 @@ The "i!=N" is like "i>N || i<N", then it could be transform to:
 L_H:
  if (i>N)
    S;
+ else
+   goto EXIT;
  i++;
  goto L_H;
 L1_H:
  if (i<N)
    S;
+ else
+   goto EXIT;
  i++;
  goto L1_H;


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-06-02  4:14 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-02  4:14 [gcc(refs/users/guojiufu/heads/guojiufu-branch)] Update according Richi comments Jiu Fu Guo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).