[PATCH #3/7] introduce ifcombine_replace_cond (was: Re: [PATCH] fold fold_truth_andor field merging into ifcombine)

Alexandre Oliva oliva@adacore.com
Fri Oct 25 11:52:47 GMT 2024


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


More information about the Gcc-patches mailing list