From patchwork Tue Jun 29 08:03:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Optimize statements created by if-conversion Date: Mon, 28 Jun 2010 22:03:21 -0000 From: Ira Rosen X-Patchwork-Id: 57251 Message-Id: To: GCC Patches 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 # i_23 = PHI # limit_24 = PHI 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 ; else goto ; 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. new_stmt = gimple_build_assign (PHI_RESULT (phi), 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); }