public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Jiu Fu Guo <guojiufu@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/guojiufu/heads/personal-branch)] only 1 phi in header, test cases, no INV set Date: Thu, 20 May 2021 06:28:22 +0000 (GMT) [thread overview] Message-ID: <20210520062822.84759394FC15@sourceware.org> (raw) https://gcc.gnu.org/g:6ae9a719928f681b7bfd91c505cb7343f10b8d56 commit 6ae9a719928f681b7bfd91c505cb7343f10b8d56 Author: Jiufu Guo <guojiufu@linux.ibm.com> Date: Fri May 14 22:29:05 2021 +0800 only 1 phi in header, test cases, no INV set Diff: --- gcc/testsuite/gcc.dg/loop-split1.c | 82 +++++++++++++++++++++++++++++++++++++- gcc/tree-ssa-loop-split.c | 59 +++++++++++++++------------ 2 files changed, 115 insertions(+), 26 deletions(-) diff --git a/gcc/testsuite/gcc.dg/loop-split1.c b/gcc/testsuite/gcc.dg/loop-split1.c index 4c466aa9f54..59c866e4b68 100644 --- a/gcc/testsuite/gcc.dg/loop-split1.c +++ b/gcc/testsuite/gcc.dg/loop-split1.c @@ -7,6 +7,13 @@ foo (int *a, int *b, unsigned l, unsigned n) while (++l != n) a[l] = b[l] + 1; } +void +foo_1 (int *a, int *b, unsigned n) +{ + unsigned l = 0; + while (++l != n) + a[l] = b[l] + 1; +} void foo1 (int *a, int *b, unsigned l, unsigned n) @@ -15,6 +22,15 @@ foo1 (int *a, int *b, unsigned l, unsigned n) a[l] = b[l] + 1; } +/* No wrap. */ +void +foo1_1 (int *a, int *b, unsigned n) +{ + unsigned l = 0; + while (l++ != n) + a[l] = b[l] + 1; +} + unsigned foo2 (char *a, char *b, unsigned l, unsigned n) { @@ -25,4 +41,68 @@ foo2 (char *a, char *b, unsigned l, unsigned n) return l; } -/* { dg-final { scan-tree-dump-times "Loop split" 3 "lsplit" } } */ +unsigned +foo2_1 (char *a, char *b, unsigned l, unsigned n) +{ + l = 0; + while (++l != n) + if (a[l] != b[l]) + break; + + return l; +} + +unsigned +foo3 (char *a, char *b, unsigned l, unsigned n) +{ + while (l++ != n) + if (a[l] != b[l]) + break; + + return l; +} + +/* No wrap. */ +unsigned +foo3_1 (char *a, char *b, unsigned l, unsigned n) +{ + l = 0; + while (l++ != n) + if (a[l] != b[l]) + break; + + return l; +} + +void bar(); +void foo4(unsigned n, unsigned i) +{ + do + { + if (i == n) + return; + bar(); + ++i; + } + while (1); +} + +unsigned +foo5 (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" 7 "lsplit" } } */ diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c index bd388f0dcc8..11d3582dd3d 100644 --- a/gcc/tree-ssa-loop-split.c +++ b/gcc/tree-ssa-loop-split.c @@ -1597,12 +1597,11 @@ split_loop_on_cond (struct loop *loop) } /* Check if the LOOP exit branch likes "if (idx != bound)", - and if overflow/wrap may happen on "idx". - If INV is not NULL and the branch is "if (bound != idx)", set *INV to true. - Return the branch edge which exit loop. */ + Return the branch edge which exit loop, if overflow/wrap + may happen on "idx". */ static edge -get_ne_cond_branch (struct loop *loop, bool *inv) +get_ne_cond_branch (struct loop *loop) { int i; edge e; @@ -1622,21 +1621,15 @@ get_ne_cond_branch (struct loop *loop, bool *inv) || (code == EQ_EXPR && (e->flags & EDGE_TRUE_VALUE)))) continue; - /* Make sure bound is invarant. */ + /* Check if bound is invarant. */ tree idx = gimple_cond_lhs (cond); tree bnd = gimple_cond_rhs (cond); if (expr_invariant_in_loop_p (loop, idx)) - { - std::swap (idx, bnd); - if (inv) - *inv = true; - } + std::swap (idx, bnd); else if (!expr_invariant_in_loop_p (loop, bnd)) continue; - - /* There is type conversion on idx(or rhs of idx's def). - And there is converting shorter to longer type. */ + /* By default, unsigned type conversion could cause overflow. */ tree type = TREE_TYPE (idx); if (!INTEGRAL_TYPE_P (type) || TREE_CODE (idx) != SSA_NAME || !TYPE_UNSIGNED (type) @@ -1673,23 +1666,39 @@ get_ne_cond_branch (struct loop *loop, bool *inv) if (TREE_CODE (iv.base) == INTEGER_CST) continue; + /* If no overflow/wrap happen, no need to split. */ + class tree_niter_desc niter; + if (!number_of_iterations_exit (loop, e, &niter, false, false, NULL)) + continue; + if (niter.control.no_overflow) + return NULL; + /* Check loop is simple to split. */ gcc_assert (bb != loop->latch); if (single_pred_p (loop->latch) && single_pred_edge (loop->latch)->src == bb - && empty_block_p (loop->latch)) + && (gsi_end_p (gsi_start_nondebug_bb (loop->latch)))) return e; - /* Splitting is cheap for idx increase header (only i++ or ++I). */ + /* Cheap header. */ if (bb == loop->header) { - if (get_virtual_phi (loop->header)) + if (get_virtual_phi (bb)) + continue; + + /* Only one phi. */ + gphi_iterator psi = gsi_start_phis (bb); + if (gsi_end_p (psi)) + continue; + gsi_next (&psi); + if (!gsi_end_p (psi)) continue; + /* ++i or ++i */ gimple_stmt_iterator gsi = gsi_start_bb (bb); if (gsi_end_p (gsi)) - return e; + continue; gimple *s1 = gsi_stmt (gsi); if (!(is_gimple_assign (s1) @@ -1725,22 +1734,22 @@ split_ne_loop (struct loop *loop, edge cond_e) basic_block loop2_cond_exit_bb = get_bb_copy (cond_e->src); free_original_copy_tables (); + gcond *gc = as_a<gcond *> (last_stmt (cond_e->src)); + gcond *dup_gc = as_a<gcond *> (last_stmt (loop2_cond_exit_bb)); + /* Change if (i != n) to LOOP1:if (i > n) and LOOP2:if (i < n) */ - bool inv = false; + bool inv = expr_invariant_in_loop_p (loop, gimple_cond_lhs (gc)); enum tree_code up_code = inv ? LT_EXPR : GT_EXPR; enum tree_code down_code = inv ? GT_EXPR : LT_EXPR; - gcond *gc = as_a<gcond *> (last_stmt (cond_e->src)); gimple_cond_set_code (gc, up_code); - - gcond *dup_gc = as_a<gcond *> (last_stmt (loop2_cond_exit_bb)); gimple_cond_set_code (dup_gc, down_code); /* Link the exit cond edge to new loop. */ gcond *break_cond = as_a<gcond *> (gimple_copy (gc)); edge pred_e = single_pred_edge (loop->latch); - gcc_assert (pred_e); - bool simple_loop = pred_e->src == cond_e->src && empty_block_p (loop->latch); + bool simple_loop = pred_e && pred_e->src == cond_e->src + && (gsi_end_p (gsi_start_nondebug_bb (loop->latch))); if (simple_loop) gimple_cond_set_code (break_cond, down_code); else @@ -1764,7 +1773,7 @@ split_ne_loop (struct loop *loop, edge cond_e) rewrite_into_loop_closed_ssa_1 (NULL, 0, SSA_OP_USE, loop); if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, ";; Loop split on wrap.\n"); + fprintf (dump_file, ";; Loop split on wrap index.\n"); return true; } @@ -1810,7 +1819,7 @@ split_loop_on_ne_cond (class loop *loop) if (num > param_max_peeled_insns) return false; - edge branch_edge = get_ne_cond_branch (loop, NULL); + edge branch_edge = get_ne_cond_branch (loop); if (branch_edge && split_ne_loop (loop, branch_edge)) return true;
next reply other threads:[~2021-05-20 6:28 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-05-20 6:28 Jiu Fu Guo [this message] 2021-05-31 5:56 Jiu Fu Guo
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210520062822.84759394FC15@sourceware.org \ --to=guojiufu@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).