On Fri, Oct 25, 2024 at 4:39 PM Alexandre Oliva <[email protected]> wrote:
>
>
> Refactor ifcombine_ifandif, moving the common code from the various
> paths that apply the combined condition to a new function.
>
>
> for gcc/ChangeLog
>
> * tree-ssa-ifcombine.cc (ifcombine_replace_cond): Factor out
> of...
> (ifcombine_ifandif): ... this.
> ---
> gcc/tree-ssa-ifcombine.cc | 137
> +++++++++++++++++++++------------------------
> 1 file changed, 65 insertions(+), 72 deletions(-)
>
> diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
> index 0a2ba970548c8..6dcf5e6efe1de 100644
> --- a/gcc/tree-ssa-ifcombine.cc
> +++ b/gcc/tree-ssa-ifcombine.cc
> @@ -399,6 +399,51 @@ update_profile_after_ifcombine (basic_block
> inner_cond_bb,
> outer2->probability = profile_probability::never ();
> }
>
> +/* Replace the conditions in INNER_COND with COND.
> + Replace OUTER_COND with a constant. */
> +
> +static bool
> +ifcombine_replace_cond (gcond *inner_cond, bool inner_inv,
> + gcond *outer_cond, bool outer_inv,
> + tree cond, bool must_canon, tree cond2)
> +{
> + bool result_inv = inner_inv;
> +
> + gcc_checking_assert (!cond2);
> +
> + if (result_inv)
> + cond = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (cond), cond);
> +
> + if (tree tcanon = canonicalize_cond_expr_cond (cond))
> + cond = tcanon;
> + else if (must_canon)
> + return false;
> +
> + {
no need for this brace pair?
OK with it dropped.
Richard.
> + if (!is_gimple_condexpr_for_cond (cond))
> + {
> + gimple_stmt_iterator gsi = gsi_for_stmt (inner_cond);
> + cond = force_gimple_operand_gsi_1 (&gsi, cond,
> + is_gimple_condexpr_for_cond,
> + NULL, true, GSI_SAME_STMT);
> + }
> + gimple_cond_set_condition_from_tree (inner_cond, cond);
> + update_stmt (inner_cond);
> +
> + /* Leave CFG optimization to cfg_cleanup. */
> + gimple_cond_set_condition_from_tree (outer_cond,
> + outer_inv
> + ? boolean_false_node
> + : boolean_true_node);
> + update_stmt (outer_cond);
> + }
> +
> + update_profile_after_ifcombine (gimple_bb (inner_cond),
> + gimple_bb (outer_cond));
> +
> + return true;
> +}
> +
> /* If-convert on a and pattern with a common else block. The inner
> if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
> inner_inv, outer_inv indicate whether the conditions are inverted.
> @@ -408,7 +453,6 @@ static bool
> ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
> basic_block outer_cond_bb, bool outer_inv)
> {
> - bool result_inv = inner_inv;
> gimple_stmt_iterator gsi;
> tree name1, name2, bit1, bit2, bits1, bits2;
>
> @@ -446,26 +490,13 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool
> inner_inv,
> t2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
> t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
> true, GSI_SAME_STMT);
> - t = fold_build2 (result_inv ? NE_EXPR : EQ_EXPR,
> - boolean_type_node, t2, t);
> - t = canonicalize_cond_expr_cond (t);
> - if (!t)
> - return false;
> - if (!is_gimple_condexpr_for_cond (t))
> - {
> - gsi = gsi_for_stmt (inner_cond);
> - t = force_gimple_operand_gsi_1 (&gsi, t,
> is_gimple_condexpr_for_cond,
> - NULL, true, GSI_SAME_STMT);
> - }
> - gimple_cond_set_condition_from_tree (inner_cond, t);
> - update_stmt (inner_cond);
>
> - /* Leave CFG optimization to cfg_cleanup. */
> - gimple_cond_set_condition_from_tree (outer_cond,
> - outer_inv ? boolean_false_node : boolean_true_node);
> - update_stmt (outer_cond);
> + t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
>
> - update_profile_after_ifcombine (inner_cond_bb, outer_cond_bb);
> + if (!ifcombine_replace_cond (inner_cond, inner_inv,
> + outer_cond, outer_inv,
> + t, true, NULL_TREE))
> + return false;
>
> if (dump_file)
> {
> @@ -485,9 +516,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool
> inner_inv,
> In that case remove the outer test and change the inner one to
> test for name & (bits1 | bits2) != 0. */
> else if (recognize_bits_test (inner_cond, &name1, &bits1, !inner_inv)
> - && recognize_bits_test (outer_cond, &name2, &bits2, !outer_inv))
> + && recognize_bits_test (outer_cond, &name2, &bits2, !outer_inv))
> {
> - gimple_stmt_iterator gsi;
> tree t;
>
> if ((TREE_CODE (name1) == SSA_NAME
> @@ -530,33 +560,14 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool
> inner_inv,
> bits1 = fold_convert (TREE_TYPE (bits2), bits1);
> }
>
> - /* Do it. */
> - gsi = gsi_for_stmt (inner_cond);
> t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), bits1, bits2);
> - t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
> - true, GSI_SAME_STMT);
> t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
> - t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
> - true, GSI_SAME_STMT);
> - t = fold_build2 (result_inv ? NE_EXPR : EQ_EXPR, boolean_type_node, t,
> + t = fold_build2 (EQ_EXPR, boolean_type_node, t,
> build_int_cst (TREE_TYPE (t), 0));
> - t = canonicalize_cond_expr_cond (t);
> - if (!t)
> + if (!ifcombine_replace_cond (inner_cond, inner_inv,
> + outer_cond, outer_inv,
> + t, false, NULL_TREE))
> return false;
> - if (!is_gimple_condexpr_for_cond (t))
> - {
> - gsi = gsi_for_stmt (inner_cond);
> - t = force_gimple_operand_gsi_1 (&gsi, t,
> is_gimple_condexpr_for_cond,
> - NULL, true, GSI_SAME_STMT);
> - }
> - gimple_cond_set_condition_from_tree (inner_cond, t);
> - update_stmt (inner_cond);
> -
> - /* Leave CFG optimization to cfg_cleanup. */
> - gimple_cond_set_condition_from_tree (outer_cond,
> - outer_inv ? boolean_false_node : boolean_true_node);
> - update_stmt (outer_cond);
> - update_profile_after_ifcombine (inner_cond_bb, outer_cond_bb);
>
> if (dump_file)
> {
> @@ -576,7 +587,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool
> inner_inv,
> else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
> && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) ==
> tcc_comparison)
> {
> - tree t;
> + tree t, ts = NULL_TREE;
> enum tree_code inner_cond_code = gimple_cond_code (inner_cond);
> enum tree_code outer_cond_code = gimple_cond_code (outer_cond);
>
> @@ -602,7 +613,6 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool
> inner_inv,
> gimple_bb (outer_cond))))
> {
> tree t1, t2;
> - gimple_stmt_iterator gsi;
> bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;
> if (param_logical_op_non_short_circuit != -1)
> logical_op_non_short_circuit
> @@ -624,39 +634,22 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool
> inner_inv,
> gimple_cond_rhs (outer_cond));
> t = fold_build2_loc (gimple_location (inner_cond),
> TRUTH_AND_EXPR, boolean_type_node, t1, t2);
> - if (result_inv)
> - {
> - t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
> - result_inv = false;
> - }
> - gsi = gsi_for_stmt (inner_cond);
> - t = force_gimple_operand_gsi_1 (&gsi, t,
> is_gimple_condexpr_for_cond,
> - NULL, true, GSI_SAME_STMT);
> }
> - if (result_inv)
> - t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
> - t = canonicalize_cond_expr_cond (t);
> - if (!t)
> - return false;
> - if (!is_gimple_condexpr_for_cond (t))
> - {
> - gsi = gsi_for_stmt (inner_cond);
> - t = force_gimple_operand_gsi_1 (&gsi, t,
> is_gimple_condexpr_for_cond,
> - NULL, true, GSI_SAME_STMT);
> - }
> - gimple_cond_set_condition_from_tree (inner_cond, t);
> - update_stmt (inner_cond);
>
> - /* Leave CFG optimization to cfg_cleanup. */
> - gimple_cond_set_condition_from_tree (outer_cond,
> - outer_inv ? boolean_false_node : boolean_true_node);
> - update_stmt (outer_cond);
> - update_profile_after_ifcombine (inner_cond_bb, outer_cond_bb);
> + if (!ifcombine_replace_cond (inner_cond, inner_inv,
> + outer_cond, outer_inv,
> + t, false, ts))
> + return false;
>
> if (dump_file)
> {
> fprintf (dump_file, "optimizing two comparisons to ");
> print_generic_expr (dump_file, t);
> + if (ts)
> + {
> + fprintf (dump_file, " and ");
> + print_generic_expr (dump_file, ts);
> + }
> fprintf (dump_file, "\n");
> }
>
>
> --
> Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/
> Free Software Activist GNU Toolchain Engineer
> More tolerance and less prejudice are key for inclusion and diversity
> Excluding neuro-others for not behaving ""normal"" is *not* inclusive