diff mbox series

[2/8] ipa: Rationalize IPA-VR computations across pass-through jump functions

Message ID ri6jzdiq6pf.fsf@virgil.suse.cz
State New
Headers show
Series [1/8] ipa: Fix jump function copying | expand

Commit Message

Martin Jambor Nov. 5, 2024, 11:07 a.m. UTC
Hi,

currently ipa_value_range_from_jfunc and
propagate_vr_across_jump_function contain similar but not same code
for dealing with pass-through jump functions.  This patch puts these
common bits into one function which can also handle comparison
operations.

Bootstrapped and tested on x86_64-linux, the whole patch series has
additionally passed LTO and profiled-LTO bootstrap on the same platform
and a bootstrap and testsuite on ppc64-linux.  Aarch64-linux bootstrap
and testing is in progress.  OK for master is that passes too?

Thanks,

Martin


gcc/ChangeLog:

2024-11-01  Martin Jambor  <mjambor@suse.cz>

	PR ipa/114985
	* ipa-cp.cc (ipa_vr_intersect_with_arith_jfunc): New function.
	(ipa_value_range_from_jfunc): Move the common functionality to the
	above new function, adjust the rest so that it works with it well.
	(propagate_vr_across_jump_function): Likewise.
---
 gcc/ipa-cp.cc | 181 +++++++++++++++++++-------------------------------
 1 file changed, 67 insertions(+), 114 deletions(-)

Comments

Aldy Hernandez Nov. 5, 2024, 11:54 a.m. UTC | #1
Martin Jambor <mjambor@suse.cz> writes:

> Hi,
>
> currently ipa_value_range_from_jfunc and
> propagate_vr_across_jump_function contain similar but not same code
> for dealing with pass-through jump functions.  This patch puts these
> common bits into one function which can also handle comparison
> operations.
>
> Bootstrapped and tested on x86_64-linux, the whole patch series has
> additionally passed LTO and profiled-LTO bootstrap on the same platform
> and a bootstrap and testsuite on ppc64-linux.  Aarch64-linux bootstrap
> and testing is in progress.  OK for master is that passes too?

The range bits LGTM.

Aldy
diff mbox series

Patch

diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 212d9ccbbfe..fa4f0feeb8d 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -1682,6 +1682,55 @@  ipa_vr_operation_and_type_effects (vrange &dst_vr,
 					    dst_type, src_type);
 }
 
+/* Given a PASS_THROUGH jump function JFUNC that takes as its source SRC_VR of
+   SRC_TYPE and the result needs to be DST_TYPE, if any value range information
+   can be deduced at all, intersect VR with it.  */
+
+static void
+ipa_vr_intersect_with_arith_jfunc (vrange &vr,
+				   ipa_jump_func *jfunc,
+				   const value_range &src_vr,
+				   tree src_type,
+				   tree dst_type)
+{
+  if (src_vr.undefined_p () || src_vr.varying_p ())
+    return;
+
+  enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
+  if (TREE_CODE_CLASS (operation) == tcc_unary)
+    {
+      value_range tmp_res (dst_type);
+      if (ipa_vr_operation_and_type_effects (tmp_res, src_vr, operation,
+					     dst_type, src_type))
+	vr.intersect (tmp_res);
+      return;
+    }
+
+  tree operand = ipa_get_jf_pass_through_operand (jfunc);
+  range_op_handler handler (operation);
+  if (!handler)
+    return;
+  value_range op_vr (TREE_TYPE (operand));
+  ipa_range_set_and_normalize (op_vr, operand);
+
+  tree operation_type;
+  if (TREE_CODE_CLASS (operation) == tcc_comparison)
+    operation_type = boolean_type_node;
+  else
+    operation_type = src_type;
+
+  value_range op_res (dst_type);
+  if (!ipa_vr_supported_type_p (operation_type)
+      || !handler.operand_check_p (operation_type, src_type, op_vr.type ())
+      || !handler.fold_range (op_res, operation_type, src_vr, op_vr))
+    return;
+
+  value_range tmp_res (dst_type);
+  if (ipa_vr_operation_and_type_effects (tmp_res, op_res, NOP_EXPR, dst_type,
+					 operation_type))
+      vr.intersect (tmp_res);
+}
+
 /* Determine range of JFUNC given that INFO describes the caller node or
    the one it is inlined to, CS is the call graph edge corresponding to JFUNC
    and PARM_TYPE of the parameter.  */
@@ -1691,18 +1740,18 @@  ipa_value_range_from_jfunc (vrange &vr,
 			    ipa_node_params *info, cgraph_edge *cs,
 			    ipa_jump_func *jfunc, tree parm_type)
 {
-  vr.set_undefined ();
+  vr.set_varying (parm_type);
 
-  if (jfunc->m_vr)
+  if (jfunc->m_vr && jfunc->m_vr->known_p ())
     ipa_vr_operation_and_type_effects (vr,
 				       *jfunc->m_vr,
 				       NOP_EXPR, parm_type,
 				       jfunc->m_vr->type ());
   if (vr.singleton_p ())
     return;
+
   if (jfunc->type == IPA_JF_PASS_THROUGH)
     {
-      int idx;
       ipcp_transformation *sum
 	= ipcp_get_transformation_summary (cs->caller->inlined_to
 					   ? cs->caller->inlined_to
@@ -1710,54 +1759,15 @@  ipa_value_range_from_jfunc (vrange &vr,
       if (!sum || !sum->m_vr)
 	return;
 
-      idx = ipa_get_jf_pass_through_formal_id (jfunc);
+      int idx = ipa_get_jf_pass_through_formal_id (jfunc);
 
       if (!(*sum->m_vr)[idx].known_p ())
 	return;
-      tree vr_type = ipa_get_type (info, idx);
+      tree src_type = ipa_get_type (info, idx);
       value_range srcvr;
       (*sum->m_vr)[idx].get_vrange (srcvr);
 
-      enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
-
-      if (TREE_CODE_CLASS (operation) == tcc_unary)
-	{
-	  value_range res (parm_type);
-
-	  if (ipa_vr_operation_and_type_effects (res,
-						 srcvr,
-						 operation, parm_type,
-						 vr_type))
-	    vr.intersect (res);
-	}
-      else
-	{
-	  value_range op_res (vr_type);
-	  value_range res (vr_type);
-	  tree op = ipa_get_jf_pass_through_operand (jfunc);
-	  value_range op_vr (TREE_TYPE (op));
-	  range_op_handler handler (operation);
-
-	  ipa_range_set_and_normalize (op_vr, op);
-
-	  if (!handler
-	      || !op_res.supports_type_p (vr_type)
-	      /* Sometimes we try to fold comparison operators using a
-		 pointer type to hold the result instead of a boolean
-		 type.  Avoid trapping in the sanity check in
-		 fold_range until this is fixed.  */
-	      || srcvr.undefined_p ()
-	      || op_vr.undefined_p ()
-	      || !handler.operand_check_p (vr_type, srcvr.type (), op_vr.type ())
-	      || !handler.fold_range (op_res, vr_type, srcvr, op_vr))
-	    op_res.set_varying (vr_type);
-
-	  if (ipa_vr_operation_and_type_effects (res,
-						 op_res,
-						 NOP_EXPR, parm_type,
-						 vr_type))
-	    vr.intersect (res);
-	}
+      ipa_vr_intersect_with_arith_jfunc (vr, jfunc, srcvr, src_type, parm_type);
     }
 }
 
@@ -2523,9 +2533,15 @@  propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
       || !ipa_vr_supported_type_p (param_type))
     return dest_lat->set_to_bottom ();
 
+  value_range vr (param_type);
+  vr.set_varying (param_type);
+  if (jfunc->m_vr)
+    ipa_vr_operation_and_type_effects (vr, *jfunc->m_vr, NOP_EXPR,
+				       param_type,
+				       jfunc->m_vr->type ());
+
   if (jfunc->type == IPA_JF_PASS_THROUGH)
     {
-      enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
       ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
       int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
       class ipcp_param_lattices *src_lats
@@ -2535,77 +2551,14 @@  propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
       if (src_lats->m_value_range.bottom_p ())
 	return dest_lat->set_to_bottom ();
 
-      value_range vr (param_type);
-      if (TREE_CODE_CLASS (operation) == tcc_unary)
-	ipa_vr_operation_and_type_effects (vr,
+      if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR
+	  || !ipa_edge_within_scc (cs))
+	ipa_vr_intersect_with_arith_jfunc (vr, jfunc,
 					   src_lats->m_value_range.m_vr,
-					   operation, param_type,
-					   operand_type);
-      /* A crude way to prevent unbounded number of value range updates
-	 in SCC components.  We should allow limited number of updates within
-	 SCC, too.  */
-      else if (!ipa_edge_within_scc (cs))
-	{
-	  tree op = ipa_get_jf_pass_through_operand (jfunc);
-	  value_range op_vr (TREE_TYPE (op));
-	  value_range op_res (param_type);
-	  range_op_handler handler (operation);
-
-	  ipa_range_set_and_normalize (op_vr, op);
-
-	  if (!handler
-	      || !ipa_vr_supported_type_p (operand_type)
-	      /* Sometimes we try to fold comparison operators using a
-		 pointer type to hold the result instead of a boolean
-		 type.  Avoid trapping in the sanity check in
-		 fold_range until this is fixed.  */
-	      || src_lats->m_value_range.m_vr.undefined_p ()
-	      || op_vr.undefined_p ()
-	      || !handler.operand_check_p (operand_type,
-					   src_lats->m_value_range.m_vr.type (),
-					   op_vr.type ())
-	      || !handler.fold_range (op_res, operand_type,
-				      src_lats->m_value_range.m_vr, op_vr))
-	    op_res.set_varying (param_type);
-
-	  ipa_vr_operation_and_type_effects (vr,
-					     op_res,
-					     NOP_EXPR, param_type,
-					     operand_type);
-	}
-      if (!vr.undefined_p () && !vr.varying_p ())
-	{
-	  if (jfunc->m_vr)
-	    {
-	      value_range jvr (param_type);
-	      if (ipa_vr_operation_and_type_effects (jvr, *jfunc->m_vr,
-						     NOP_EXPR,
-						     param_type,
-						     jfunc->m_vr->type ()))
-		vr.intersect (jvr);
-	    }
-	  return dest_lat->meet_with (vr);
-	}
-    }
-  else if (jfunc->type == IPA_JF_CONST)
-    {
-      tree val = ipa_get_jf_constant (jfunc);
-      if (TREE_CODE (val) == INTEGER_CST)
-	{
-	  val = fold_convert (param_type, val);
-	  if (TREE_OVERFLOW_P (val))
-	    val = drop_tree_overflow (val);
-
-	  value_range tmpvr (val, val);
-	  return dest_lat->meet_with (tmpvr);
-	}
+					   operand_type, param_type);
     }
 
-  value_range vr (param_type);
-  if (jfunc->m_vr
-      && ipa_vr_operation_and_type_effects (vr, *jfunc->m_vr, NOP_EXPR,
-					    param_type,
-					    jfunc->m_vr->type ()))
+  if (!vr.undefined_p () && !vr.varying_p ())
     return dest_lat->meet_with (vr);
   else
     return dest_lat->set_to_bottom ();