This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Optimize statements created by if-conversion
- From: Ira Rosen <IRAR at il dot ibm dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 29 Jun 2010 11:03:21 +0300
- Subject: [patch] Optimize statements created by if-conversion
Hi,
For the following minloc loop (which I am trying to vectorize):
for (i = 0; i < N; i++)
if (arr[i] < limit)
{
pos = i + 1;
limit = arr[i];
}
if-conversion generates
# pos_22 = PHI <pos_1(8), 1(3)>
# i_23 = PHI <prephitmp.8_2(8), 0(3)>
# limit_24 = PHI <limit_4(8), 1.28e+2(3)>
limit_10 = arr[i_23];
pos_11 = i_23 + 1;
pretmp.7_3 = i_23 + 1;
pos_1 = [cond_expr] limit_10 >= limit_24 ? pos_22 : pos_11;
limit_4 = [cond_expr] limit_10 >= limit_24 ? limit_24 : limit_10;
prephitmp.8_2 = [cond_expr] limit_10 >= limit_24 ? pretmp.7_3 : pos_11;
if (prephitmp.8_2 < n_9(D))
goto <bb 8>;
else
goto <bb 9>;
For
prephitmp.8_2 = [cond_expr] limit_10 >= limit_24 ? pretmp.7_3 : pos_11;
then and else clauses are equivalent, so
prephitmp.8_2 = pretmp.7_3;
should be enough.
Does the following patch make sense? (Meanwhile, I only tested it with
vectorizer testsuite).
Thanks,
Ira
ChangeLog:
* tree-if-conv.c (replace_phi_with_cond_gimple_assign_stmt):
If then and else clauses are equivalent, use one of them as a
rhs.
Index: tree-if-conv.c
===================================================================
--- tree-if-conv.c (revision 161484)
+++ tree-if-conv.c (working copy)
@@ -925,6 +925,8 @@ replace_phi_with_cond_gimple_assign_stmt
basic_block bb;
tree rhs;
tree arg;
+ gimple def_stmt0, def_stmt1;
+ enum tree_code code;
gcc_assert (gimple_code (phi) == GIMPLE_PHI
&& gimple_phi_num_args (phi) == 2);
@@ -949,9 +951,35 @@ replace_phi_with_cond_gimple_assign_stmt
arg_1 = gimple_phi_arg_def (phi, 1);
}
- /* Build new RHS using selected condition and arguments. */
- rhs = build3 (COND_EXPR, TREE_TYPE (PHI_RESULT (phi)),
- unshare_expr (cond), arg_0, arg_1);
+ if (TREE_CODE (arg_0) == SSA_NAME && TREE_CODE (arg_1) == SSA_NAME
+ && (def_stmt0 = SSA_NAME_DEF_STMT (arg_0))
+ && (def_stmt1 = SSA_NAME_DEF_STMT (arg_1))
+ && is_gimple_assign (def_stmt0)
+ && is_gimple_assign (def_stmt1)
+ && (code = gimple_assign_rhs_code (def_stmt0))
+ == gimple_assign_rhs_code (def_stmt1)
+ && ((get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS
+ && operand_equal_p (gimple_assign_rhs1 (def_stmt0),
+ gimple_assign_rhs1 (def_stmt1), 0))
+ || (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS
+ && operand_equal_p (gimple_assign_rhs1 (def_stmt0),
+ gimple_assign_rhs1 (def_stmt1), 0)
+ && operand_equal_p (gimple_assign_rhs2 (def_stmt0),
+ gimple_assign_rhs2 (def_stmt1), 0))
+ || (get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS
+ && operand_equal_p (gimple_assign_rhs1 (def_stmt0),
+ gimple_assign_rhs1 (def_stmt1), 0)
+ && operand_equal_p (gimple_assign_rhs2 (def_stmt0),
+ gimple_assign_rhs2 (def_stmt1), 0)
+ && operand_equal_p (gimple_assign_rhs3 (def_stmt0),
+ gimple_assign_rhs3 (def_stmt1),
0))))
+ /* Since then and else parts are equivalent, make RHS to be one of
+ them. */
+ rhs = arg_0;
+ else
+ /* Build new RHS using selected condition and arguments. */
+ rhs = build3 (COND_EXPR, TREE_TYPE (PHI_RESULT (phi)),
+ unshare_expr (cond), arg_0, arg_1);
}
new_stmt = gimple_build_assign (PHI_RESULT (phi), rhs);