https://gcc.gnu.org/g:3e47b273d7c0ebe66a739e2e73c98d99b14cff2a
commit 3e47b273d7c0ebe66a739e2e73c98d99b14cff2a Author: Alexandre Oliva <ol...@gnu.org> Date: Thu Oct 24 05:25:26 2024 -0300 introduce ifcombine_replace_cond Diff: --- gcc/tree-ssa-ifcombine.cc | 130 +++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 71 deletions(-) diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc index eae32e1e1999..d2be5e81c671 100644 --- a/gcc/tree-ssa-ifcombine.cc +++ b/gcc/tree-ssa-ifcombine.cc @@ -399,6 +399,50 @@ 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 tree +ifcombine_replace_cond (gcond *inner_cond, bool inner_inv, + gcond *outer_cond, bool outer_inv, + tree cond, bool must_canon, tree) +{ + tree ret = cond; + bool result_inv = inner_inv; + + 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 NULL_TREE; + + { + 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 ret; +} + /* 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. @@ -445,26 +489,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) { @@ -484,9 +515,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 @@ -529,33 +559,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) { @@ -575,7 +586,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); @@ -601,7 +612,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 @@ -623,34 +633,12 @@ 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 (!(t = ifcombine_replace_cond (inner_cond, inner_inv, + outer_cond, outer_inv, + t, false, ts))) + return false; if (dump_file) {