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;
+
+ {
+ 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