public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/guojiufu/heads/personal-branch)] Use fast type for loop idx
@ 2021-05-31 6:04 Jiu Fu Guo
0 siblings, 0 replies; only message in thread
From: Jiu Fu Guo @ 2021-05-31 6:04 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:fe3ff943d605b91cd2a32cc770b49117e1c3e19f
commit fe3ff943d605b91cd2a32cc770b49117e1c3e19f
Author: Jiufu Guo <guojiufu@linux.ibm.com>
Date: Thu May 20 14:26:25 2021 +0800
Use fast type for loop idx
Diff:
---
gcc/tree-ssa-loop-split.c | 166 +++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 151 insertions(+), 15 deletions(-)
diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c
index 4a48e27fb8b..43fd709302d 100644
--- a/gcc/tree-ssa-loop-split.c
+++ b/gcc/tree-ssa-loop-split.c
@@ -1599,7 +1599,7 @@ split_loop_on_cond (struct loop *loop)
Return NULL_TREE, if overflow/wrap will not happen. */
static tree
-get_wrap_assumption (class loop *loop, edge *exit)
+get_wrap_assumption (class loop *loop, edge *exit, gphi **idx_phi)
{
int i;
edge e;
@@ -1644,14 +1644,16 @@ get_wrap_assumption (class loop *loop, edge *exit)
if (code != NE_EXPR && code != LT_EXPR && code != LE_EXPR)
continue;
+ /* Check if idx is a valid SSA. */
+ if (TREE_CODE (idx) != SSA_NAME)
+ continue;
+
/* Filter conversion from idx. */
- tree cmp_idx = idx;
+ int inc_cnt = 0;
tree small_type = TREE_TYPE (idx);
tree large_type = small_type;
- gimple *stmt = NULL;
- if (TREE_CODE (idx) == SSA_NAME)
- stmt = SSA_NAME_DEF_STMT (idx);
- while (stmt && is_gimple_assign (stmt)
+ 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);
@@ -1670,7 +1672,14 @@ get_wrap_assumption (class loop *loop, edge *exit)
}
else if (PLUS_EXPR == code
&& integer_onep (gimple_assign_rhs2 (stmt)))
- idx = gimple_assign_rhs1 (stmt);
+ {
+ idx = gimple_assign_rhs1 (stmt);
+
+ /* At most one increament stmt. */
+ inc_cnt++;
+ if (inc_cnt > 1)
+ break;
+ }
else
break;
@@ -1679,6 +1688,11 @@ get_wrap_assumption (class loop *loop, edge *exit)
stmt = SSA_NAME_DEF_STMT (idx);
}
+ /* At last it should a PHI which is iv. */
+ if (gimple_code (stmt) != GIMPLE_PHI)
+ continue;
+ *idx_phi = as_a<gphi *> (stmt);
+
/* Check if idx is iv with base and step. */
affine_iv iv;
tree iv_niters = NULL_TREE;
@@ -1716,6 +1730,121 @@ get_wrap_assumption (class loop *loop, edge *exit)
return NULL_TREE;
}
+/* Update the idx and bnd with faster type for no wrap/oveflow loop. */
+
+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. */
+ gcond *gc = as_a<gcond *> (last);
+ tree bnd = gimple_cond_rhs (gc);
+ tree idx = gimple_cond_lhs (gc);
+ bool inv = false;
+ if (expr_invariant_in_loop_p (loop, idx))
+ {
+ inv = true;
+ std::swap (idx, bnd);
+ }
+
+ gimple *stmt = convert_src (idx);
+ bool cmp_next = stmt == inc_stmt;
+
+ /* Use sizetype as machine fast type, ok for all targets? */
+ tree fast_type = sizetype;
+
+ /* New base and new bound. */
+ edge pre_e = loop_preheader_edge (loop);
+ tree base = PHI_ARG_DEF_FROM_EDGE (idx_phi, pre_e);
+ tree new_base = fold_convert (fast_type, base);
+ tree new_bnd = fold_convert (fast_type, bnd);
+ gimple_seq seq = NULL;
+ new_base = force_gimple_operand (new_base, &seq, true, NULL_TREE);
+ if (seq)
+ gsi_insert_seq_on_edge_immediate (pre_e, seq);
+ seq = NULL;
+ new_bnd = force_gimple_operand (new_bnd, &seq, true, NULL_TREE);
+ if (seq)
+ gsi_insert_seq_on_edge_immediate (pre_e, seq);
+
+ /* new_i = phi (new_b, new_n)
+ new_n = new_i + 1 */
+ basic_block bb = gimple_bb (idx_phi);
+ const char *name = "idx";
+ tree new_idx = make_temp_ssa_name (fast_type, NULL, name);
+ tree new_next = make_temp_ssa_name (fast_type, NULL, name);
+ gphi *newphi = create_phi_node (new_idx, bb);
+ add_phi_arg (newphi, new_base, pre_e, UNKNOWN_LOCATION);
+ add_phi_arg (newphi, new_next, latch_e, UNKNOWN_LOCATION);
+
+ /* New increase stmt. */
+ tree step = gimple_assign_rhs2 (inc_stmt);
+ gcc_assert (TREE_CODE (step) == INTEGER_CST);
+ step = fold_convert (fast_type, step);
+ new_idx = PHI_RESULT (newphi);
+ gimple *new_inc = gimple_build_assign (new_next, PLUS_EXPR, new_idx, step);
+ gimple_stmt_iterator gsi = gsi_for_stmt (inc_stmt);
+ gsi_insert_before (&gsi, new_inc, GSI_SAME_STMT);
+
+ /* Update gcond. */
+ tree cmp_idx = cmp_next ? new_next : new_idx;
+ gimple_cond_set_lhs (gc, inv ? new_bnd : cmp_idx);
+ gimple_cond_set_rhs (gc, inv ? cmp_idx : new_bnd);
+ update_stmt (gc);
+
+ tree type = TREE_TYPE (next);
+ stmt = gimple_build_assign (next, fold_convert (type, new_next));
+ gsi = gsi_for_stmt (inc_stmt);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+
+ gsi = gsi_for_stmt (inc_stmt);
+ gsi_remove (&gsi, true);
+
+ idx = PHI_RESULT (idx_phi);
+ type = TREE_TYPE (idx);
+ stmt = gimple_build_assign (idx, fold_convert (type, new_idx));
+ gsi = gsi_start_bb (bb);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+
+ gsi = gsi_for_stmt (idx_phi);
+ gsi_remove (&gsi, true);
+
+ return true;
+}
+
/* Split out a new loop which would not wrap/overflow,
under the guard that WRAP_ASSUMPTION will not be true. */
@@ -1730,11 +1859,12 @@ split_wrap_boundary (class loop *loop, edge e, tree no_wrap_cond)
/* Version the loop. */
initialize_original_copy_tables ();
basic_block cond_bb;
- loop_version (loop, no_wrap_cond, &cond_bb,
- profile_probability::very_likely (),
- profile_probability::very_unlikely (),
- profile_probability::very_likely (),
- profile_probability::very_unlikely (), true);
+ class loop *loop1
+ = loop_version (loop, no_wrap_cond, &cond_bb,
+ profile_probability::very_likely (),
+ profile_probability::very_unlikely (),
+ profile_probability::very_likely (),
+ profile_probability::very_unlikely (), true);
free_original_copy_tables ();
/* Insert the statements that feed COND. */
@@ -1804,9 +1934,15 @@ split_loop_on_wrap (class loop *loop)
free (bbs);
edge e;
- tree nowrap_assumption = get_wrap_assumption (loop, &e);
- if (nowrap_assumption && split_wrap_boundary (loop, e, nowrap_assumption))
- return true;
+ gphi *idx_phi;
+ tree assumption = get_wrap_assumption (loop, &e, &idx_phi);
+
+ if (assumption && split_wrap_boundary (loop, e, assumption))
+ {
+ // rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
+ update_idx_bnd_type (loop, last_stmt (e->src), idx_phi);
+ return true;
+ }
return false;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-05-31 6:04 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-31 6:04 [gcc(refs/users/guojiufu/heads/personal-branch)] Use fast type for loop idx 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).