]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Convert ipcp_vr_lattice to type agnostic framework.
authorAldy Hernandez <aldyh@redhat.com>
Wed, 17 May 2023 09:29:34 +0000 (11:29 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Sat, 10 Jun 2023 21:56:46 +0000 (23:56 +0200)
This converts the lattice to store ranges in Value_Range instead of
value_range (*) to make it type agnostic, and adjust all users
accordingly.

I've been careful to make sure Value_Range never ends up on GC, since
it contains an int_range_max and can expand on-demand onto the heap.
Longer term storage for ranges should be done with vrange_storage, as
per the previous patch ("Provide an API for ipa_vr").

gcc/ChangeLog:

* ipa-cp.cc (ipcp_vr_lattice::init): Take type argument.
(ipcp_vr_lattice::print): Call dump method.
(ipcp_vr_lattice::meet_with): Adjust for m_vr being a
Value_Range.
(ipcp_vr_lattice::meet_with_1): Make argument a reference.
(ipcp_vr_lattice::set_to_bottom): Set varying for an unsupported
range.
(initialize_node_lattices): Pass type when appropriate.
(ipa_vr_operation_and_type_effects): Make type agnostic.
(ipa_value_range_from_jfunc): Same.
(propagate_vr_across_jump_function): Same.
* ipa-fnsummary.cc (evaluate_conditions_for_known_args): Same.
(evaluate_properties_for_edge): Same.
* ipa-prop.cc (ipa_vr::get_vrange): Same.
(ipcp_update_vr): Same.
* ipa-prop.h (ipa_value_range_from_jfunc): Same.
(ipa_range_set_and_normalize): Same.

gcc/ipa-cp.cc
gcc/ipa-fnsummary.cc
gcc/ipa-prop.cc
gcc/ipa-prop.h

index 0f37bb5e336041b67db4bfbc9fa6586314ebd090..d77b9eab249508b18a7e8f2986a369e15ae06e10 100644 (file)
@@ -343,20 +343,29 @@ private:
 class ipcp_vr_lattice
 {
 public:
-  value_range m_vr;
+  Value_Range m_vr;
 
   inline bool bottom_p () const;
   inline bool top_p () const;
   inline bool set_to_bottom ();
-  bool meet_with (const value_range *p_vr);
+  bool meet_with (const vrange &p_vr);
   bool meet_with (const ipcp_vr_lattice &other);
-  void init () { gcc_assert (m_vr.undefined_p ()); }
+  void init (tree type);
   void print (FILE * f);
 
 private:
-  bool meet_with_1 (const value_range *other_vr);
+  bool meet_with_1 (const vrange &other_vr);
 };
 
+inline void
+ipcp_vr_lattice::init (tree type)
+{
+  if (type)
+    m_vr.set_type (type);
+
+  // Otherwise m_vr will default to unsupported_range.
+}
+
 /* Structure containing lattices for a parameter itself and for pieces of
    aggregates that are passed in the parameter or by a reference in a parameter
    plus some other useful flags.  */
@@ -585,7 +594,7 @@ ipcp_bits_lattice::print (FILE *f)
 void
 ipcp_vr_lattice::print (FILE * f)
 {
-  dump_value_range (f, &m_vr);
+  m_vr.dump (f);
 }
 
 /* Print all ipcp_lattices of all functions to F.  */
@@ -1016,39 +1025,39 @@ set_agg_lats_contain_variable (class ipcp_param_lattices *plats)
 bool
 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other)
 {
-  return meet_with_1 (&other.m_vr);
+  return meet_with_1 (other.m_vr);
 }
 
-/* Meet the current value of the lattice with value range described by VR
-   lattice.  */
+/* Meet the current value of the lattice with the range described by
+   P_VR.  */
 
 bool
-ipcp_vr_lattice::meet_with (const value_range *p_vr)
+ipcp_vr_lattice::meet_with (const vrange &p_vr)
 {
   return meet_with_1 (p_vr);
 }
 
-/* Meet the current value of the lattice with value range described by
-   OTHER_VR lattice.  Return TRUE if anything changed.  */
+/* Meet the current value of the lattice with the range described by
+   OTHER_VR.  Return TRUE if anything changed.  */
 
 bool
-ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
+ipcp_vr_lattice::meet_with_1 (const vrange &other_vr)
 {
   if (bottom_p ())
     return false;
 
-  if (other_vr->varying_p ())
+  if (other_vr.varying_p ())
     return set_to_bottom ();
 
   bool res;
   if (flag_checking)
     {
-      value_range save (m_vr);
-      res = m_vr.union_ (*other_vr);
+      Value_Range save (m_vr);
+      res = m_vr.union_ (other_vr);
       gcc_assert (res == (m_vr != save));
     }
   else
-    res = m_vr.union_ (*other_vr);
+    res = m_vr.union_ (other_vr);
   return res;
 }
 
@@ -1077,12 +1086,15 @@ ipcp_vr_lattice::set_to_bottom ()
 {
   if (m_vr.varying_p ())
     return false;
-  /* ?? We create all sorts of VARYING ranges for floats, structures,
-     and other types which we cannot handle as ranges.  We should
-     probably avoid handling them throughout the pass, but it's easier
-     to create a sensible VARYING here and let the lattice
-     propagate.  */
-  m_vr.set_varying (integer_type_node);
+
+  /* Setting an unsupported type here forces the temporary to default
+     to unsupported_range, which can handle VARYING/DEFINED ranges,
+     but nothing else (union, intersect, etc).  This allows us to set
+     bottoms on any ranges, and is safe as all users of the lattice
+     check for bottom first.  */
+  m_vr.set_type (void_type_node);
+  m_vr.set_varying (void_type_node);
+
   return true;
 }
 
@@ -1653,6 +1665,7 @@ initialize_node_lattices (struct cgraph_node *node)
   for (i = 0; i < ipa_get_param_count (info); i++)
     {
       ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+      tree type = ipa_get_type (info, i);
       if (disable
          || !ipa_get_type (info, i)
          || (pre_modified && (surviving_params.length () <= (unsigned) i
@@ -1662,12 +1675,12 @@ initialize_node_lattices (struct cgraph_node *node)
          plats->ctxlat.set_to_bottom ();
          set_agg_lats_to_bottom (plats);
          plats->bits_lattice.set_to_bottom ();
-         plats->m_value_range.m_vr = value_range ();
+         plats->m_value_range.init (type);
          plats->m_value_range.set_to_bottom ();
        }
       else
        {
-         plats->m_value_range.init ();
+         plats->m_value_range.init (type);
          if (variable)
            set_all_contains_variable (plats);
        }
@@ -1900,11 +1913,11 @@ ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
 
 /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
    DST_TYPE on value range in SRC_VR and store it to DST_VR.  Return true if
-   the result is a range or an anti-range.  */
+   the result is a range that is not VARYING nor UNDEFINED.  */
 
 static bool
-ipa_vr_operation_and_type_effects (value_range *dst_vr,
-                                  value_range *src_vr,
+ipa_vr_operation_and_type_effects (vrange &dst_vr,
+                                  const vrange &src_vr,
                                   enum tree_code operation,
                                   tree dst_type, tree src_type)
 {
@@ -1912,29 +1925,35 @@ ipa_vr_operation_and_type_effects (value_range *dst_vr,
     return false;
 
   range_op_handler handler (operation, dst_type);
-  return (handler
-         && handler.fold_range (*dst_vr, dst_type,
-                                *src_vr, value_range (dst_type))
-         && !dst_vr->varying_p ()
-         && !dst_vr->undefined_p ());
+  if (!handler)
+    return false;
+
+  Value_Range varying (dst_type);
+  varying.set_varying (dst_type);
+
+  return (handler.fold_range (dst_vr, dst_type, src_vr, varying)
+         && !dst_vr.varying_p ()
+         && !dst_vr.undefined_p ());
 }
 
 /* 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.  */
 
-value_range
-ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
+void
+ipa_value_range_from_jfunc (vrange &vr,
+                           ipa_node_params *info, cgraph_edge *cs,
                            ipa_jump_func *jfunc, tree parm_type)
 {
-  value_range vr;
+  vr.set_undefined ();
+
   if (jfunc->m_vr)
-    ipa_vr_operation_and_type_effects (&vr,
-                                      jfunc->m_vr,
+    ipa_vr_operation_and_type_effects (vr,
+                                      *jfunc->m_vr,
                                       NOP_EXPR, parm_type,
                                       jfunc->m_vr->type ());
   if (vr.singleton_p ())
-    return vr;
+    return;
   if (jfunc->type == IPA_JF_PASS_THROUGH)
     {
       int idx;
@@ -1943,33 +1962,34 @@ ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
                                           ? cs->caller->inlined_to
                                           : cs->caller);
       if (!sum || !sum->m_vr)
-       return vr;
+       return;
 
       idx = ipa_get_jf_pass_through_formal_id (jfunc);
 
       if (!(*sum->m_vr)[idx].known_p ())
-       return vr;
+       return;
       tree vr_type = ipa_get_type (info, idx);
-      value_range srcvr;
+      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;
+         Value_Range res (vr_type);
 
-         if (ipa_vr_operation_and_type_effects (&res,
-                                                &srcvr,
+         if (ipa_vr_operation_and_type_effects (res,
+                                                srcvr,
                                                 operation, parm_type,
                                                 vr_type))
            vr.intersect (res);
        }
       else
        {
-         value_range op_res, res;
+         Value_Range op_res (vr_type);
+         Value_Range res (vr_type);
          tree op = ipa_get_jf_pass_through_operand (jfunc);
-         value_range op_vr;
+         Value_Range op_vr (vr_type);
          range_op_handler handler (operation, vr_type);
 
          ipa_range_set_and_normalize (op_vr, op);
@@ -1979,14 +1999,13 @@ ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
              || !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,
+         if (ipa_vr_operation_and_type_effects (res,
+                                                op_res,
                                                 NOP_EXPR, parm_type,
                                                 vr_type))
            vr.intersect (res);
        }
     }
-  return vr;
 }
 
 /* Determine whether ITEM, jump function for an aggregate part, evaluates to a
@@ -2753,10 +2772,10 @@ 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;
+      Value_Range vr (operand_type);
       if (TREE_CODE_CLASS (operation) == tcc_unary)
-       ipa_vr_operation_and_type_effects (&vr,
-                                          &src_lats->m_value_range.m_vr,
+       ipa_vr_operation_and_type_effects (vr,
+                                          src_lats->m_value_range.m_vr,
                                           operation, param_type,
                                           operand_type);
       /* A crude way to prevent unbounded number of value range updates
@@ -2765,8 +2784,8 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
       else if (!ipa_edge_within_scc (cs))
        {
          tree op = ipa_get_jf_pass_through_operand (jfunc);
-         value_range op_vr;
-         value_range op_res,res;
+         Value_Range op_vr (TREE_TYPE (op));
+         Value_Range op_res (operand_type);
          range_op_handler handler (operation, operand_type);
 
          ipa_range_set_and_normalize (op_vr, op);
@@ -2777,8 +2796,8 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
                                      src_lats->m_value_range.m_vr, op_vr))
            op_res.set_varying (operand_type);
 
-         ipa_vr_operation_and_type_effects (&vr,
-                                            &op_res,
+         ipa_vr_operation_and_type_effects (vr,
+                                            op_res,
                                             NOP_EXPR, param_type,
                                             operand_type);
        }
@@ -2786,14 +2805,14 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
        {
          if (jfunc->m_vr)
            {
-             value_range jvr;
-             if (ipa_vr_operation_and_type_effects (&jvr, 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);
+         return dest_lat->meet_with (vr);
        }
     }
   else if (jfunc->type == IPA_JF_CONST)
@@ -2805,18 +2824,17 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
          if (TREE_OVERFLOW_P (val))
            val = drop_tree_overflow (val);
 
-         value_range tmpvr (TREE_TYPE (val),
-                            wi::to_wide (val), wi::to_wide (val));
-         return dest_lat->meet_with (&tmpvr);
+         Value_Range tmpvr (val, val);
+         return dest_lat->meet_with (tmpvr);
        }
     }
 
-  value_range vr;
+  Value_Range vr (param_type);
   if (jfunc->m_vr
-      && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
+      && ipa_vr_operation_and_type_effects (vr, *jfunc->m_vr, NOP_EXPR,
                                            param_type,
                                            jfunc->m_vr->type ()))
-    return dest_lat->meet_with (&vr);
+    return dest_lat->meet_with (vr);
   else
     return dest_lat->set_to_bottom ();
 }
index b328bb8ce14b0725f6e5607da9d1e2f61e9baf62..cf41620292001c0752ec7903c7edd76ee883e484 100644 (file)
@@ -475,7 +475,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
          && !c->agg_contents
          && (!val || TREE_CODE (val) != INTEGER_CST))
        {
-         value_range vr = avals->m_known_value_ranges[c->operand_num];
+         Value_Range vr (avals->m_known_value_ranges[c->operand_num]);
          if (!vr.undefined_p ()
              && !vr.varying_p ()
              && (TYPE_SIZE (c->type) == TYPE_SIZE (vr.type ())))
@@ -630,8 +630,8 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
                || ipa_is_param_used_by_ipa_predicates (callee_pi, i))
              {
                /* Determine if we know constant value of the parameter.  */
-               tree cst = ipa_value_from_jfunc (caller_parms_info, jf,
-                                                ipa_get_type (callee_pi, i));
+               tree type = ipa_get_type (callee_pi, i);
+               tree cst = ipa_value_from_jfunc (caller_parms_info, jf, type);
 
                if (!cst && e->call_stmt
                    && i < (int)gimple_call_num_args (e->call_stmt))
@@ -659,10 +659,9 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
                    && vrp_will_run_p (caller)
                    && ipa_is_param_used_by_ipa_predicates (callee_pi, i))
                  {
-                   value_range vr
-                      = ipa_value_range_from_jfunc (caller_parms_info, e, jf,
-                                                    ipa_get_type (callee_pi,
-                                                                  i));
+                   Value_Range vr (type);
+
+                   ipa_value_range_from_jfunc (vr, caller_parms_info, e, jf, type);
                    if (!vr.undefined_p () && !vr.varying_p ())
                      {
                        if (!avals->m_known_value_ranges.length ())
@@ -670,7 +669,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
                            avals->m_known_value_ranges.safe_grow (count, true);
                            for (int i = 0; i < count; ++i)
                              new (&avals->m_known_value_ranges[i])
-                               value_range ();
+                               Value_Range ();
                          }
                        avals->m_known_value_ranges[i] = vr;
                      }
index 4e9a307ad4dd9d26af67c4131df18777518a5d11..eea811768648d3746274076150562feaf5a54145 100644 (file)
@@ -198,8 +198,9 @@ ipa_vr::equal_p (const vrange &r) const
 }
 
 void
-ipa_vr::get_vrange (vrange &r) const
+ipa_vr::get_vrange (Value_Range &r) const
 {
+  r.set_type (m_type);
   m_storage->get_vrange (r, m_type);
 }
 
@@ -5964,7 +5965,7 @@ ipcp_update_vr (struct cgraph_node *node)
 
       if (vr[i].known_p ())
        {
-         value_range tmp;
+         Value_Range tmp;
          vr[i].get_vrange (tmp);
 
          if (!tmp.undefined_p () && !tmp.varying_p ())
index f306f8a377e1e274c0ee9db3926c46719ad3be08..3a591a8f44d16e1ea06e53291062789585df7ae3 100644 (file)
@@ -314,7 +314,7 @@ public:
   void set_unknown ();
   bool known_p () const { return m_storage != NULL; }
   tree type () const { return m_type; }
-  void get_vrange (vrange &) const;
+  void get_vrange (Value_Range &) const;
   bool equal_p (const vrange &) const;
   const vrange_storage *storage () const { return m_storage; }
   void streamer_read (lto_input_block *, data_in *);
@@ -530,7 +530,7 @@ public:
   auto_vec<ipa_argagg_value, 32> m_known_aggs;
 
   /* Vector describing known value ranges of arguments.  */
-  auto_vec<value_range, 32> m_known_value_ranges;
+  auto_vec<Value_Range, 32> m_known_value_ranges;
 };
 
 inline
@@ -582,7 +582,7 @@ public:
   vec<ipa_argagg_value> m_known_aggs = vNULL;
 
   /* Vector describing known value ranges of arguments.  */
-  vec<value_range> m_known_value_ranges = vNULL;
+  vec<Value_Range> m_known_value_ranges = vNULL;
 };
 
 inline
@@ -1194,8 +1194,8 @@ ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *,
                                                     cgraph_edge *,
                                                     int,
                                                     ipa_jump_func *);
-value_range ipa_value_range_from_jfunc (ipa_node_params *, cgraph_edge *,
-                                       ipa_jump_func *, tree);
+void ipa_value_range_from_jfunc (vrange &, ipa_node_params *, cgraph_edge *,
+                                ipa_jump_func *, tree);
 void ipa_push_agg_values_from_jfunc (ipa_node_params *info, cgraph_node *node,
                                     ipa_agg_jump_function *agg_jfunc,
                                     unsigned dst_index,
@@ -1218,17 +1218,12 @@ void ipa_cp_cc_finalize (void);
    non-zero.  */
 
 inline void
-ipa_range_set_and_normalize (irange &r, tree val)
+ipa_range_set_and_normalize (vrange &r, tree val)
 {
-  if (TREE_CODE (val) == INTEGER_CST)
-    {
-      wide_int w = wi::to_wide (val);
-      r.set (TREE_TYPE (val), w, w);
-    }
-  else if (TREE_CODE (val) == ADDR_EXPR)
+  if (TREE_CODE (val) == ADDR_EXPR)
     r.set_nonzero (TREE_TYPE (val));
   else
-    r.set_varying (TREE_TYPE (val));
+    r.set (val, val);
 }
 
 #endif /* IPA_PROP_H */