public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/guojiufu/heads/personal-branch)] code clean up
@ 2021-06-02 7:39 Jiu Fu Guo
0 siblings, 0 replies; only message in thread
From: Jiu Fu Guo @ 2021-06-02 7:39 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:f2d41ac14f081bfaa3812185beaf1f146e80fd75
commit f2d41ac14f081bfaa3812185beaf1f146e80fd75
Author: guojiufu <guojiufu@linux.ibm.com>
Date: Wed Jun 2 15:39:06 2021 +0800
code clean up
Diff:
---
gcc/tree-ssa-loop-split.c | 225 ++++++++++++++++++++++++++--------------------
1 file changed, 126 insertions(+), 99 deletions(-)
diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c
index 43fd709302d..283c6fc6d90 100644
--- a/gcc/tree-ssa-loop-split.c
+++ b/gcc/tree-ssa-loop-split.c
@@ -1594,9 +1594,63 @@ split_loop_on_cond (struct loop *loop)
return do_split;
}
+/* Filter out type conversions on IDX.
+
+ i = phi (b, n)
+ ...
+ n0 = ik + 1
+ n1 = (type)n0
+ ...
+ if (i != bnd) or if (n != bnd)
+ ...
+ n = ()nl
+
+ IDX is the i' or n'.
+
+ Store the shortest type during conversion to SMALL_TYPE.
+ Store the longest type during conversion to LARGE_TYPE. */
+
+static gimple *
+filter_conversions (class loop *loop, tree idx, tree *small_type = NULL,
+ tree *large_type = NULL)
+{
+ gimple *stmt = SSA_NAME_DEF_STMT (idx);
+ while (is_gimple_assign (stmt)
+ && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
+ {
+ if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
+ {
+ idx = gimple_assign_rhs1 (stmt);
+ if (small_type)
+ {
+ tree type = TREE_TYPE (idx);
+ if (TYPE_PRECISION (*small_type) > TYPE_PRECISION (type)
+ || (TYPE_PRECISION (*small_type) == TYPE_PRECISION (type)
+ && TYPE_UNSIGNED (*small_type) && !TYPE_UNSIGNED (type)))
+ *small_type = type;
+ }
+ if (large_type)
+ {
+ tree type = TREE_TYPE (idx);
+ if (TYPE_PRECISION (*large_type) < TYPE_PRECISION (type)
+ || (TYPE_PRECISION (*large_type) == TYPE_PRECISION (type)
+ && !TYPE_UNSIGNED (*large_type) && TYPE_UNSIGNED (type)))
+ *large_type = type;
+ }
+ }
+ else
+ break;
+
+ if (TREE_CODE (idx) != SSA_NAME)
+ break;
+ stmt = SSA_NAME_DEF_STMT (idx);
+ }
+ return stmt;
+}
+
/* Check if the loop is possible to wrap at index.
Return the assumption under which the wrap will not happen.
- Return NULL_TREE, if overflow/wrap will not happen. */
+ Return NULL_TREE, if wrap will not happen. */
static tree
get_wrap_assumption (class loop *loop, edge *exit, gphi **idx_phi)
@@ -1648,60 +1702,38 @@ get_wrap_assumption (class loop *loop, edge *exit, gphi **idx_phi)
if (TREE_CODE (idx) != SSA_NAME)
continue;
- /* Filter conversion from idx. */
- int inc_cnt = 0;
- tree small_type = TREE_TYPE (idx);
- tree large_type = small_type;
- gimple *stmt = SSA_NAME_DEF_STMT (idx);
- while (is_gimple_assign (stmt)
- && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
- {
- enum tree_code code = gimple_assign_rhs_code (stmt);
- if (CONVERT_EXPR_CODE_P (code))
- {
- idx = gimple_assign_rhs1 (stmt);
- tree type = TREE_TYPE (idx);
- if (TYPE_PRECISION (small_type) > TYPE_PRECISION (type)
- || (TYPE_PRECISION (small_type) == TYPE_PRECISION (type)
- && TYPE_UNSIGNED (small_type) && !TYPE_UNSIGNED (type)))
- small_type = type;
- if (TYPE_PRECISION (large_type) < TYPE_PRECISION (type)
- || (TYPE_PRECISION (large_type) == TYPE_PRECISION (type)
- && !TYPE_UNSIGNED (large_type) && TYPE_UNSIGNED (type)))
- large_type = type;
- }
- else if (PLUS_EXPR == code
- && integer_onep (gimple_assign_rhs2 (stmt)))
- {
- idx = gimple_assign_rhs1 (stmt);
-
- /* At most one increament stmt. */
- inc_cnt++;
- if (inc_cnt > 1)
- break;
- }
- else
- break;
-
- if (TREE_CODE (idx) != SSA_NAME)
- break;
- stmt = SSA_NAME_DEF_STMT (idx);
- }
-
- /* At last it should a PHI which is iv. */
+ /* Get the phi for idx. */
+ gimple *stmt = filter_conversions (loop, idx);
+ if (is_gimple_assign (stmt))
+ stmt = filter_conversions (loop, gimple_assign_rhs1 (stmt));
if (gimple_code (stmt) != GIMPLE_PHI)
continue;
- *idx_phi = as_a<gphi *> (stmt);
+ *idx_phi = as_a <gphi *> (stmt);
/* Check if idx is iv with base and step. */
affine_iv iv;
tree iv_niters = NULL_TREE;
+ idx = PHI_RESULT (*idx_phi);
if (!simple_iv_with_niters (loop, loop_containing_stmt (gc), idx, &iv,
&iv_niters, false))
continue;
if (!iv.base || !iv.step || !integer_onep (iv.step))
continue;
+ /* If there is conversions on idx,
+ Get the longest and shortest type during converting. */
+ tree next = PHI_ARG_DEF_FROM_EDGE (*idx_phi, loop_latch_edge (loop));
+ tree small_type = TREE_TYPE (next);
+ tree large_type = small_type;
+ stmt = filter_conversions (loop, next, &small_type, &large_type);
+ if (!is_gimple_assign (stmt)
+ || gimple_assign_rhs_code (stmt) != PLUS_EXPR
+ || !flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
+ continue;
+ tree prev = gimple_assign_rhs1 (stmt);
+ stmt = filter_conversions (loop, prev, &small_type, &large_type);
+
+ /* Update the type of bae, bound and the max value of boundary. */
tree base = iv.base;
tree maxv = TYPE_MAX_VALUE (small_type);
if (large_type != TREE_TYPE (base))
@@ -1711,20 +1743,22 @@ get_wrap_assumption (class loop *loop, edge *exit, gphi **idx_phi)
if (large_type != small_type)
maxv = fold_convert (large_type, maxv);
- /* for "< or <=", only check if bnd <= max value of idx type. */
- tree no_wrap = fold_build2 (LE_EXPR, boolean_type_node, bnd, maxv);
- /* for "!=", and check if base <= bnd. */
+ /* for "< or <=", there is no wrap if bnd <= max value. */
+ tree no_wrap_assump = fold_build2 (LE_EXPR, boolean_type_node, bnd, maxv);
+
+ /* for "!=", to make sure there is no wrap, beside bnd <= max,
+ base <= bnd is also required. */
if (code == NE_EXPR)
- no_wrap
- = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, no_wrap,
+ no_wrap_assump
+ = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, no_wrap_assump,
fold_build2 (LE_EXPR, boolean_type_node, base, bnd));
- /* Check if it is sure wrap or no wrap. */
- if (integer_zerop (no_wrap) || integer_onep (no_wrap))
+ /* Check if 100% sure wrap or no wrap. */
+ if (integer_zerop (no_wrap_assump) || integer_onep (no_wrap_assump))
continue;
*exit = e;
- return no_wrap;
+ return no_wrap_assump;
}
return NULL_TREE;
@@ -1735,41 +1769,7 @@ get_wrap_assumption (class loop *loop, edge *exit, gphi **idx_phi)
static bool
update_idx_bnd_type (class loop *loop, gimple *last, gphi *idx_phi)
{
- /* Filter type conversion
- i = phi (b, n)
- ..
- n0 = ik + 1
- n1 = (type)n0
- if (i != bnd) or if (n != bnd)
- ..
- n = ()nl */
- auto convert_src = [&loop](tree idx) -> gimple * {
- gimple *stmt = SSA_NAME_DEF_STMT (idx);
- while (is_gimple_assign (stmt)
- && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
- {
- if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
- idx = gimple_assign_rhs1 (stmt);
- else
- break;
-
- if (TREE_CODE (idx) != SSA_NAME)
- break;
- stmt = SSA_NAME_DEF_STMT (idx);
- }
- return stmt;
- };
-
- /* Get increase statement. */
- edge latch_e = loop_latch_edge (loop);
- tree next = PHI_ARG_DEF_FROM_EDGE (idx_phi, latch_e);
- gimple *inc_stmt = convert_src (next);
- if (!is_gimple_assign (inc_stmt)
- || gimple_assign_rhs_code (inc_stmt) != PLUS_EXPR
- || !flow_bb_inside_loop_p (loop, gimple_bb (inc_stmt)))
- return false;
-
- /* Check gcond stmt for bnd and idx/next. */
+ /* Get bnd and idx from gcond. */
gcond *gc = as_a<gcond *> (last);
tree bnd = gimple_cond_rhs (gc);
tree idx = gimple_cond_lhs (gc);
@@ -1780,10 +1780,32 @@ update_idx_bnd_type (class loop *loop, gimple *last, gphi *idx_phi)
std::swap (idx, bnd);
}
- gimple *stmt = convert_src (idx);
- bool cmp_next = stmt == inc_stmt;
+ edge latch_e = loop_latch_edge (loop);
+ tree next = PHI_ARG_DEF_FROM_EDGE (idx_phi, latch_e);
+
+ /* Get increasement stmt: next = prev + 1.
+ And check the exit gcond is comparing on the prev or next. */
+ gimple *inc_stmt = NULL;
+ bool cmp_next = false;
+ gimple *stmt = filter_conversions (loop, idx);
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ {
+ inc_stmt = filter_conversions (loop, next);
+ cmp_next = false;
+ }
+ else
+ {
+ inc_stmt = stmt;
+ cmp_next = true;
+ }
+
+ if (!is_gimple_assign (inc_stmt)
+ || gimple_assign_rhs_code (inc_stmt) != PLUS_EXPR
+ || !flow_bb_inside_loop_p (loop, gimple_bb (inc_stmt)))
+ return false;
+
- /* Use sizetype as machine fast type, ok for all targets? */
+ /* Use sizetype as machine fast type, ok for most targets? */
tree fast_type = sizetype;
/* New base and new bound. */
@@ -1825,6 +1847,8 @@ update_idx_bnd_type (class loop *loop, gimple *last, gphi *idx_phi)
gimple_cond_set_rhs (gc, inv ? cmp_idx : new_bnd);
update_stmt (gc);
+ /* next = (next type)new_next
+ And remove next = prev + 1. */
tree type = TREE_TYPE (next);
stmt = gimple_build_assign (next, fold_convert (type, new_next));
gsi = gsi_for_stmt (inc_stmt);
@@ -1833,6 +1857,8 @@ update_idx_bnd_type (class loop *loop, gimple *last, gphi *idx_phi)
gsi = gsi_for_stmt (inc_stmt);
gsi_remove (&gsi, true);
+ /* prev = (prev type)new_prev
+ And remove prev = phi. */
idx = PHI_RESULT (idx_phi);
type = TREE_TYPE (idx);
stmt = gimple_build_assign (idx, fold_convert (type, new_idx));
@@ -1845,8 +1871,8 @@ update_idx_bnd_type (class loop *loop, gimple *last, gphi *idx_phi)
return true;
}
-/* Split out a new loop which would not wrap/overflow,
- under the guard that WRAP_ASSUMPTION will not be true. */
+/* Split out a new loop which would not wrap,
+ under the guard that NO_WRAP_COND will not be true. */
static bool
split_wrap_boundary (class loop *loop, edge e, tree no_wrap_cond)
@@ -1889,16 +1915,17 @@ split_wrap_boundary (class loop *loop, edge e, tree no_wrap_cond)
}
/* Split loop if there is possible wrap.
- For example: transform
+ For example:
+ transform
- void
- foo (int *a, int *b, unsigned l, unsigned u_n)
- {
- while (++l != u_n)
- a[l] = b[l] + 1;
- }
+ void
+ foo (int *a, int *b, unsigned l, unsigned u_n)
+ {
+ while (++l != u_n)
+ a[l] = b[l] + 1;
+ }
- to:
+ to:
if (l < u_n)
{
int li = l;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-06-02 7:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-02 7:39 [gcc(refs/users/guojiufu/heads/personal-branch)] code clean up 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).