public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/guojiufu/heads/guojiufu-branch)] prepare code
@ 2021-05-31 5:55 Jiu Fu Guo
0 siblings, 0 replies; 2+ messages in thread
From: Jiu Fu Guo @ 2021-05-31 5:55 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:af3824d29806e59b0f58eea465e96da68cb2fc86
commit af3824d29806e59b0f58eea465e96da68cb2fc86
Author: Jiufu Guo <guojiufu@linux.ibm.com>
Date: Mon May 17 16:38:57 2021 +0800
prepare code
Diff:
---
gcc/testsuite/g++.dg/vect/pr98064.cc | 4 +-
gcc/testsuite/gcc.dg/loop-split1.c | 158 +++++++++++++++++++++++++++++++++++
gcc/tree-ssa-loop-split.c | 86 ++++++++++++++++++-
3 files changed, 244 insertions(+), 4 deletions(-)
diff --git a/gcc/testsuite/g++.dg/vect/pr98064.cc b/gcc/testsuite/g++.dg/vect/pr98064.cc
index 74043ce7725..dcb2985d05a 100644
--- a/gcc/testsuite/g++.dg/vect/pr98064.cc
+++ b/gcc/testsuite/g++.dg/vect/pr98064.cc
@@ -1,5 +1,7 @@
// { dg-do compile }
-// { dg-additional-options "-O3" }
+// { dg-additional-options "-O3 -Wno-stringop-overflow" }
+/* There is warning message when "short g = var_8; g; g++"
+ is optimized/analyzed as string operation,e.g. memset. */
const long long &min(const long long &__a, long long &__b) {
if (__b < __a)
diff --git a/gcc/testsuite/gcc.dg/loop-split1.c b/gcc/testsuite/gcc.dg/loop-split1.c
new file mode 100644
index 00000000000..12abfa2938b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/loop-split1.c
@@ -0,0 +1,158 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fsplit-loops -fdump-tree-lsplit-details" } */
+
+int foo_short_sgn (int *p, unsigned short u_n, signed short i)
+{
+ int x = 0;
+ for (; i != u_n; i++) {
+ x = x + p[i];
+ }
+ return x;
+}
+
+int foo_short (int *p, unsigned short u_n, unsigned short i)
+{
+ int x = 0;
+ for (; i != u_n; i++) {
+ x = x + p[i];
+ }
+ return x;
+}
+
+int foo_short_sgn_1 (int *p, unsigned short u_n, signed short i)
+{
+ int x = 0;
+ for (; i != u_n; i++) {
+ x = x + *p++;
+ }
+ return x;
+}
+
+int foo_int (int *p, unsigned int u_n, unsigned int i)
+{
+ int x = 0;
+ for (; i != u_n; i++)
+ x = x + p[i];
+ return x;
+}
+
+void
+bar (int *a, int *b, unsigned l, unsigned u_n)
+{
+ while (++l != u_n)
+ a[l] = b[l] + 1;
+}
+
+void
+bar_long_bnd (int *a, int *b, unsigned l, long l_n)
+{
+ while (++l != l_n)
+ a[l] = b[l] + 1;
+}
+
+void
+bar_long_bnd_1 (int *a, int *b, unsigned l, long l_n)
+{
+ while (++l < l_n)
+ a[l] = b[l] + 1;
+}
+
+void
+bar_1 (int *a, int *b, unsigned n)
+{
+ unsigned l = 0;
+ while (++l != n)
+ a[l] = b[l] + 1;
+}
+
+void
+bar_2 (int *a, int *b, unsigned l, unsigned n)
+{
+ while (l++ != n)
+ a[l] = b[l] + 1;
+}
+
+/* No wrap. */
+void
+bar_3 (int *a, int *b, unsigned n)
+{
+ unsigned l = 0;
+ while (l++ != n)
+ a[l] = b[l] + 1;
+}
+
+unsigned
+func (char *a, char *b, unsigned l, unsigned n)
+{
+ while (++l != n)
+ if (a[l] != b[l])
+ break;
+
+ return l;
+}
+
+unsigned
+func_1 (char *a, char *b, unsigned l, unsigned n)
+{
+ l = 0;
+ while (++l != n)
+ if (a[l] != b[l])
+ break;
+
+ return l;
+}
+
+unsigned
+func_2 (char *a, char *b, unsigned l, unsigned n)
+{
+ while (l++ != n)
+ if (a[l] != b[l])
+ break;
+
+ return l;
+}
+
+/* No wrap. */
+unsigned
+func_3 (char *a, char *b, unsigned l, unsigned n)
+{
+ l = 0;
+ while (l++ != n)
+ if (a[l] != b[l])
+ break;
+
+ return l;
+}
+
+void callee();
+void func_eq(unsigned n, unsigned i)
+{
+ do
+ {
+ if (i == n)
+ return;
+ callee ();
+ ++i;
+ }
+ while (1);
+}
+
+unsigned
+skip (double *a, unsigned n, unsigned i)
+{
+ while (a[i] > 0 && i != n)
+ i++;
+
+ return i;
+}
+
+unsigned
+find_skip_diff (char *p, char *q, unsigned n, unsigned i)
+{
+ while (p[i] == q[i] && ++i != n)
+ p++,q++;
+
+ return i;
+}
+
+/* { dg-final { scan-tree-dump-times "Loop split" 9 "lsplit" } } */
diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c
index 3a09bbc39e5..30e717c3004 100644
--- a/gcc/tree-ssa-loop-split.c
+++ b/gcc/tree-ssa-loop-split.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfghooks.h"
#include "gimple-fold.h"
#include "gimplify-me.h"
+#include "tree-ssa-loop-ivopts.h"
/* This file implements two kinds of loop splitting.
@@ -233,7 +234,8 @@ easy_exit_values (class loop *loop)
this. The loops need to fulfill easy_exit_values(). */
static void
-connect_loop_phis (class loop *loop1, class loop *loop2, edge new_e)
+connect_loop_phis (class loop *loop1, class loop *loop2, edge new_e,
+ bool use_prev = false)
{
basic_block rest = loop_preheader_edge (loop2)->src;
gcc_assert (new_e->dest == rest);
@@ -279,7 +281,8 @@ connect_loop_phis (class loop *loop1, class loop *loop2, edge new_e)
gphi * newphi = create_phi_node (new_init, rest);
add_phi_arg (newphi, init, skip_first, UNKNOWN_LOCATION);
- add_phi_arg (newphi, next, new_e, UNKNOWN_LOCATION);
+ add_phi_arg (newphi, use_prev ? PHI_RESULT (phi_first) : next, new_e,
+ UNKNOWN_LOCATION);
SET_USE (op, new_init);
}
}
@@ -1593,6 +1596,82 @@ split_loop_on_cond (struct loop *loop)
return do_split;
}
+/* Check if the loop is possible to wrap at index.
+ Return the assumption under which the wrap would happen.
+ Return NULL_TREE, if overflow/wrap will not happen. */
+
+static tree
+get_wrap_assumption (class loop *loop)
+{
+ int i;
+ edge e;
+ auto_vec<edge> edges = get_loop_exit_edges (loop);
+ FOR_EACH_VEC_ELT (edges, i, e)
+ {
+
+ }
+
+ return NULL_TREE;
+}
+
+/* Split out a new loop which would not wrap/overflow,
+ under the guard that WRAP_ASSUMPTION will not be true. */
+
+static bool
+split_wrap_boundary (class loop *loop, tree wrap_assumption)
+{
+
+ return false;
+}
+
+/* Split loop if there is possible wrap.
+ For example: transform
+
+ void
+ foo (int *a, int *b, unsigned l, unsigned u_n)
+ {
+ while (++l != u_n)
+ a[l] = b[l] + 1;
+ }
+
+ to:
+ if (l < u_n)
+ {
+ int li = l;
+ int n = u_n;
+ while (++li < n)
+ a[li] = b[li] + 1;
+ l = li;
+ }
+ else
+ while (++l != n)
+ a[l] = b[l] + 1;
+ */
+static bool
+split_loop_on_wrap (class loop *loop)
+{
+ basic_block *bbs = get_loop_body (loop);
+
+ if (!can_copy_bbs_p (bbs, loop->num_nodes))
+ {
+ free (bbs);
+ return false;
+ }
+
+ int num = 0;
+ for (unsigned i = 0; i < loop->num_nodes; i++)
+ num += estimate_num_insns_seq (bb_seq (bbs[i]), &eni_size_weights);
+
+ if (num > param_max_peeled_insns)
+ {
+ free (bbs);
+ return false;
+ }
+
+ free (bbs);
+ return false;
+}
+
/* Main entry point. Perform loop splitting on all suitable loops. */
static unsigned int
@@ -1622,7 +1701,8 @@ tree_ssa_split_loops (void)
if (optimize_loop_for_size_p (loop))
continue;
- if (split_loop (loop) || split_loop_on_cond (loop))
+ if (split_loop (loop) || split_loop_on_cond (loop)
+ || split_loop_on_wrap (loop))
{
/* Mark our containing loop as having had some split inner loops. */
loop_outer (loop)->aux = loop;
^ permalink raw reply [flat|nested] 2+ messages in thread
* [gcc(refs/users/guojiufu/heads/guojiufu-branch)] prepare code
@ 2021-05-20 6:27 Jiu Fu Guo
0 siblings, 0 replies; 2+ messages in thread
From: Jiu Fu Guo @ 2021-05-20 6:27 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:109832c1d67184bfe3e3f6c80d7d122497844b66
commit 109832c1d67184bfe3e3f6c80d7d122497844b66
Author: Jiufu Guo <guojiufu@linux.ibm.com>
Date: Mon May 17 16:38:57 2021 +0800
prepare code
Diff:
---
gcc/testsuite/g++.dg/vect/pr98064.cc | 4 +-
gcc/testsuite/gcc.dg/loop-split1.c | 158 +++++++++++++++++++++++++++++++++++
gcc/tree-ssa-loop-split.c | 86 ++++++++++++++++++-
3 files changed, 244 insertions(+), 4 deletions(-)
diff --git a/gcc/testsuite/g++.dg/vect/pr98064.cc b/gcc/testsuite/g++.dg/vect/pr98064.cc
index 74043ce7725..dcb2985d05a 100644
--- a/gcc/testsuite/g++.dg/vect/pr98064.cc
+++ b/gcc/testsuite/g++.dg/vect/pr98064.cc
@@ -1,5 +1,7 @@
// { dg-do compile }
-// { dg-additional-options "-O3" }
+// { dg-additional-options "-O3 -Wno-stringop-overflow" }
+/* There is warning message when "short g = var_8; g; g++"
+ is optimized/analyzed as string operation,e.g. memset. */
const long long &min(const long long &__a, long long &__b) {
if (__b < __a)
diff --git a/gcc/testsuite/gcc.dg/loop-split1.c b/gcc/testsuite/gcc.dg/loop-split1.c
new file mode 100644
index 00000000000..12abfa2938b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/loop-split1.c
@@ -0,0 +1,158 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fsplit-loops -fdump-tree-lsplit-details" } */
+
+int foo_short_sgn (int *p, unsigned short u_n, signed short i)
+{
+ int x = 0;
+ for (; i != u_n; i++) {
+ x = x + p[i];
+ }
+ return x;
+}
+
+int foo_short (int *p, unsigned short u_n, unsigned short i)
+{
+ int x = 0;
+ for (; i != u_n; i++) {
+ x = x + p[i];
+ }
+ return x;
+}
+
+int foo_short_sgn_1 (int *p, unsigned short u_n, signed short i)
+{
+ int x = 0;
+ for (; i != u_n; i++) {
+ x = x + *p++;
+ }
+ return x;
+}
+
+int foo_int (int *p, unsigned int u_n, unsigned int i)
+{
+ int x = 0;
+ for (; i != u_n; i++)
+ x = x + p[i];
+ return x;
+}
+
+void
+bar (int *a, int *b, unsigned l, unsigned u_n)
+{
+ while (++l != u_n)
+ a[l] = b[l] + 1;
+}
+
+void
+bar_long_bnd (int *a, int *b, unsigned l, long l_n)
+{
+ while (++l != l_n)
+ a[l] = b[l] + 1;
+}
+
+void
+bar_long_bnd_1 (int *a, int *b, unsigned l, long l_n)
+{
+ while (++l < l_n)
+ a[l] = b[l] + 1;
+}
+
+void
+bar_1 (int *a, int *b, unsigned n)
+{
+ unsigned l = 0;
+ while (++l != n)
+ a[l] = b[l] + 1;
+}
+
+void
+bar_2 (int *a, int *b, unsigned l, unsigned n)
+{
+ while (l++ != n)
+ a[l] = b[l] + 1;
+}
+
+/* No wrap. */
+void
+bar_3 (int *a, int *b, unsigned n)
+{
+ unsigned l = 0;
+ while (l++ != n)
+ a[l] = b[l] + 1;
+}
+
+unsigned
+func (char *a, char *b, unsigned l, unsigned n)
+{
+ while (++l != n)
+ if (a[l] != b[l])
+ break;
+
+ return l;
+}
+
+unsigned
+func_1 (char *a, char *b, unsigned l, unsigned n)
+{
+ l = 0;
+ while (++l != n)
+ if (a[l] != b[l])
+ break;
+
+ return l;
+}
+
+unsigned
+func_2 (char *a, char *b, unsigned l, unsigned n)
+{
+ while (l++ != n)
+ if (a[l] != b[l])
+ break;
+
+ return l;
+}
+
+/* No wrap. */
+unsigned
+func_3 (char *a, char *b, unsigned l, unsigned n)
+{
+ l = 0;
+ while (l++ != n)
+ if (a[l] != b[l])
+ break;
+
+ return l;
+}
+
+void callee();
+void func_eq(unsigned n, unsigned i)
+{
+ do
+ {
+ if (i == n)
+ return;
+ callee ();
+ ++i;
+ }
+ while (1);
+}
+
+unsigned
+skip (double *a, unsigned n, unsigned i)
+{
+ while (a[i] > 0 && i != n)
+ i++;
+
+ return i;
+}
+
+unsigned
+find_skip_diff (char *p, char *q, unsigned n, unsigned i)
+{
+ while (p[i] == q[i] && ++i != n)
+ p++,q++;
+
+ return i;
+}
+
+/* { dg-final { scan-tree-dump-times "Loop split" 9 "lsplit" } } */
diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c
index 3a09bbc39e5..30e717c3004 100644
--- a/gcc/tree-ssa-loop-split.c
+++ b/gcc/tree-ssa-loop-split.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfghooks.h"
#include "gimple-fold.h"
#include "gimplify-me.h"
+#include "tree-ssa-loop-ivopts.h"
/* This file implements two kinds of loop splitting.
@@ -233,7 +234,8 @@ easy_exit_values (class loop *loop)
this. The loops need to fulfill easy_exit_values(). */
static void
-connect_loop_phis (class loop *loop1, class loop *loop2, edge new_e)
+connect_loop_phis (class loop *loop1, class loop *loop2, edge new_e,
+ bool use_prev = false)
{
basic_block rest = loop_preheader_edge (loop2)->src;
gcc_assert (new_e->dest == rest);
@@ -279,7 +281,8 @@ connect_loop_phis (class loop *loop1, class loop *loop2, edge new_e)
gphi * newphi = create_phi_node (new_init, rest);
add_phi_arg (newphi, init, skip_first, UNKNOWN_LOCATION);
- add_phi_arg (newphi, next, new_e, UNKNOWN_LOCATION);
+ add_phi_arg (newphi, use_prev ? PHI_RESULT (phi_first) : next, new_e,
+ UNKNOWN_LOCATION);
SET_USE (op, new_init);
}
}
@@ -1593,6 +1596,82 @@ split_loop_on_cond (struct loop *loop)
return do_split;
}
+/* Check if the loop is possible to wrap at index.
+ Return the assumption under which the wrap would happen.
+ Return NULL_TREE, if overflow/wrap will not happen. */
+
+static tree
+get_wrap_assumption (class loop *loop)
+{
+ int i;
+ edge e;
+ auto_vec<edge> edges = get_loop_exit_edges (loop);
+ FOR_EACH_VEC_ELT (edges, i, e)
+ {
+
+ }
+
+ return NULL_TREE;
+}
+
+/* Split out a new loop which would not wrap/overflow,
+ under the guard that WRAP_ASSUMPTION will not be true. */
+
+static bool
+split_wrap_boundary (class loop *loop, tree wrap_assumption)
+{
+
+ return false;
+}
+
+/* Split loop if there is possible wrap.
+ For example: transform
+
+ void
+ foo (int *a, int *b, unsigned l, unsigned u_n)
+ {
+ while (++l != u_n)
+ a[l] = b[l] + 1;
+ }
+
+ to:
+ if (l < u_n)
+ {
+ int li = l;
+ int n = u_n;
+ while (++li < n)
+ a[li] = b[li] + 1;
+ l = li;
+ }
+ else
+ while (++l != n)
+ a[l] = b[l] + 1;
+ */
+static bool
+split_loop_on_wrap (class loop *loop)
+{
+ basic_block *bbs = get_loop_body (loop);
+
+ if (!can_copy_bbs_p (bbs, loop->num_nodes))
+ {
+ free (bbs);
+ return false;
+ }
+
+ int num = 0;
+ for (unsigned i = 0; i < loop->num_nodes; i++)
+ num += estimate_num_insns_seq (bb_seq (bbs[i]), &eni_size_weights);
+
+ if (num > param_max_peeled_insns)
+ {
+ free (bbs);
+ return false;
+ }
+
+ free (bbs);
+ return false;
+}
+
/* Main entry point. Perform loop splitting on all suitable loops. */
static unsigned int
@@ -1622,7 +1701,8 @@ tree_ssa_split_loops (void)
if (optimize_loop_for_size_p (loop))
continue;
- if (split_loop (loop) || split_loop_on_cond (loop))
+ if (split_loop (loop) || split_loop_on_cond (loop)
+ || split_loop_on_wrap (loop))
{
/* Mark our containing loop as having had some split inner loops. */
loop_outer (loop)->aux = loop;
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-05-31 5:55 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-31 5:55 [gcc(refs/users/guojiufu/heads/guojiufu-branch)] prepare code Jiu Fu Guo
-- strict thread matches above, loose matches on Subject: below --
2021-05-20 6:27 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).