Alexandre Oliva <ol...@adacore.com> writes:

> Refactor ifcombine_ifandif, moving the common code from the various
> paths that apply the combined condition to a new function.

BTW, forgive the possibly silly question, but I don't see any testcases
for the series. Would it be possible to add any?

>
>
> 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;
> +
> +    {
> +      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");
>       }

Reply via email to