From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2066) id 21AC93848019; Thu, 20 May 2021 06:27:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 21AC93848019 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Jiu Fu Guo To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/guojiufu/heads/guojiufu-branch)] prepare code X-Act-Checkin: gcc X-Git-Author: Jiufu Guo X-Git-Refname: refs/users/guojiufu/heads/guojiufu-branch X-Git-Oldrev: 1ba3f0ef546ec83fe28fef7f34e0ee9e52c6477f X-Git-Newrev: 109832c1d67184bfe3e3f6c80d7d122497844b66 Message-Id: <20210520062757.21AC93848019@sourceware.org> Date: Thu, 20 May 2021 06:27:57 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 May 2021 06:27:57 -0000 https://gcc.gnu.org/g:109832c1d67184bfe3e3f6c80d7d122497844b66 commit 109832c1d67184bfe3e3f6c80d7d122497844b66 Author: Jiufu Guo 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 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;