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  <mjam...@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(-)

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 ();
-- 
2.47.0

Reply via email to