]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Provide an API for ipa_vr.
authorAldy Hernandez <aldyh@redhat.com>
Wed, 17 May 2023 09:29:32 +0000 (11:29 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Wed, 24 May 2023 16:03:26 +0000 (18:03 +0200)
This patch encapsulates the ipa_vr internals into an API.  It also
makes it type agnostic, in preparation for upcoming changes to IPA.

Interestingly, there's a 0.44% improvement to IPA-cp, which I'm sure
we'll soak up with future changes in this area :).

gcc/ChangeLog:

* ipa-cp.cc (ipa_value_range_from_jfunc): Use new ipa_vr API.
(ipcp_store_vr_results): Same.
* ipa-prop.cc (ipa_vr::ipa_vr): New.
(ipa_vr::get_vrange): New.
(ipa_vr::set_unknown): New.
(ipa_vr::streamer_read): New.
(ipa_vr::streamer_write): New.
(write_ipcp_transformation_info): Use new ipa_vr API.
(read_ipcp_transformation_info): Same.
(ipa_vr::nonzero_p): Delete.
(ipcp_update_vr): Use new ipa_vr API.
* ipa-prop.h (class ipa_vr): Provide an API and hide internals.
* ipa-sra.cc (zap_useless_ipcp_results): Use new ipa_vr API.

gcc/testsuite/ChangeLog:

* gcc.dg/ipa/pr78121.c: Adjust for vrange::dump use.
* gcc.dg/ipa/vrp1.c: Same.
* gcc.dg/ipa/vrp2.c: Same.
* gcc.dg/ipa/vrp3.c: Same.
* gcc.dg/ipa/vrp4.c: Same.
* gcc.dg/ipa/vrp5.c: Same.
* gcc.dg/ipa/vrp6.c: Same.
* gcc.dg/ipa/vrp7.c: Same.
* gcc.dg/ipa/vrp8.c: Same.

13 files changed:
gcc/ipa-cp.cc
gcc/ipa-prop.cc
gcc/ipa-prop.h
gcc/ipa-sra.cc
gcc/testsuite/gcc.dg/ipa/pr78121.c
gcc/testsuite/gcc.dg/ipa/vrp1.c
gcc/testsuite/gcc.dg/ipa/vrp2.c
gcc/testsuite/gcc.dg/ipa/vrp3.c
gcc/testsuite/gcc.dg/ipa/vrp4.c
gcc/testsuite/gcc.dg/ipa/vrp5.c
gcc/testsuite/gcc.dg/ipa/vrp6.c
gcc/testsuite/gcc.dg/ipa/vrp7.c
gcc/testsuite/gcc.dg/ipa/vrp8.c

index 8cd0fa2cae796cbce0fb9be4121c36f49b08d698..0f37bb5e336041b67db4bfbc9fa6586314ebd090 100644 (file)
@@ -1919,7 +1919,7 @@ ipa_vr_operation_and_type_effects (value_range *dst_vr,
          && !dst_vr->undefined_p ());
 }
 
-/* Determine value_range of JFUNC given that INFO describes the caller node or
+/* 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.  */
 
@@ -1947,13 +1947,11 @@ ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
 
       idx = ipa_get_jf_pass_through_formal_id (jfunc);
 
-      if (!(*sum->m_vr)[idx].known)
+      if (!(*sum->m_vr)[idx].known_p ())
        return vr;
       tree vr_type = ipa_get_type (info, idx);
-      value_range srcvr (vr_type,
-                        (*sum->m_vr)[idx].min,
-                        (*sum->m_vr)[idx].max,
-                        (*sum->m_vr)[idx].type);
+      value_range srcvr;
+      (*sum->m_vr)[idx].get_vrange (srcvr);
 
       enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
 
@@ -6621,25 +6619,19 @@ ipcp_store_vr_results (void)
       for (unsigned i = 0; i < count; i++)
        {
          ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
-         ipa_vr vr;
 
          if (!plats->m_value_range.bottom_p ()
              && !plats->m_value_range.top_p ()
              && dbg_cnt (ipa_cp_vr))
            {
-             tree min, max;
-             vr.known = true;
-             vr.type = get_legacy_range (plats->m_value_range.m_vr, min, max);
-             vr.min = wi::to_wide (min);
-             vr.max = wi::to_wide (max);
+             ipa_vr vr (plats->m_value_range.m_vr);
+             ts->m_vr->quick_push (vr);
            }
          else
            {
-             vr.known = false;
-             vr.type = VR_VARYING;
-             vr.min = vr.max = wi::zero (INT_TYPE_SIZE);
+             ipa_vr vr;
+             ts->m_vr->quick_push (vr);
            }
-         ts->m_vr->quick_push (vr);
        }
     }
 }
index 60b7f09214f7ed469652722979ee146cbee0a55d..ab6de9f10da9f5d1b687da12f6eb4b936e894728 100644 (file)
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "symtab-clones.h"
 #include "attr-fnspec.h"
 #include "gimple-range.h"
+#include "value-range-storage.h"
 
 /* Function summary where the parameter infos are actually stored. */
 ipa_node_params_t *ipa_node_params_sum = NULL;
@@ -177,6 +178,92 @@ struct ipa_cst_ref_desc
 static object_allocator<ipa_cst_ref_desc> ipa_refdesc_pool
   ("IPA-PROP ref descriptions");
 
+ipa_vr::ipa_vr ()
+  : m_storage (NULL),
+    m_type (NULL)
+{
+}
+
+ipa_vr::ipa_vr (const vrange &r)
+  : m_storage (ggc_alloc_vrange_storage (r)),
+    m_type (r.type ())
+{
+}
+
+bool
+ipa_vr::equal_p (const vrange &r) const
+{
+  gcc_checking_assert (!r.undefined_p ());
+  return (types_compatible_p (m_type, r.type ()) && m_storage->equal_p (r));
+}
+
+void
+ipa_vr::get_vrange (vrange &r) const
+{
+  m_storage->get_vrange (r, m_type);
+}
+
+void
+ipa_vr::set_unknown ()
+{
+  if (m_storage)
+    ggc_free (m_storage);
+
+  m_storage = NULL;
+}
+
+void
+ipa_vr::streamer_read (lto_input_block *ib, data_in *data_in)
+{
+  struct bitpack_d bp = streamer_read_bitpack (ib);
+  bool known = bp_unpack_value (&bp, 1);
+  if (known)
+    {
+      Value_Range vr;
+      streamer_read_value_range (ib, data_in, vr);
+      if (!m_storage || !m_storage->fits_p (vr))
+       {
+         if (m_storage)
+           ggc_free (m_storage);
+         m_storage = ggc_alloc_vrange_storage (vr);
+       }
+      m_storage->set_vrange (vr);
+      m_type = vr.type ();
+    }
+  else
+    {
+      m_storage = NULL;
+      m_type = NULL;
+    }
+}
+
+void
+ipa_vr::streamer_write (output_block *ob) const
+{
+  struct bitpack_d bp = bitpack_create (ob->main_stream);
+  bp_pack_value (&bp, !!m_storage, 1);
+  streamer_write_bitpack (&bp);
+  if (m_storage)
+    {
+      Value_Range vr (m_type);
+      m_storage->get_vrange (vr, m_type);
+      streamer_write_vrange (ob, vr);
+    }
+}
+
+void
+ipa_vr::dump (FILE *out) const
+{
+  if (known_p ())
+    {
+      Value_Range vr (m_type);
+      m_storage->get_vrange (vr, m_type);
+      vr.dump (out);
+    }
+  else
+    fprintf (out, "NO RANGE");
+}
+
 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
    with NODE should prevent us from analyzing it for the purposes of IPA-CP.  */
 
@@ -5337,19 +5424,7 @@ write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
 
   streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
   for (const ipa_vr &parm_vr : ts->m_vr)
-    {
-      struct bitpack_d bp;
-      bp = bitpack_create (ob->main_stream);
-      bp_pack_value (&bp, parm_vr.known, 1);
-      streamer_write_bitpack (&bp);
-      if (parm_vr.known)
-       {
-         streamer_write_enum (ob->main_stream, value_rang_type,
-                              VR_LAST, parm_vr.type);
-         streamer_write_wide_int (ob, parm_vr.min);
-         streamer_write_wide_int (ob, parm_vr.max);
-       }
-    }
+    parm_vr.streamer_write (ob);
 
   streamer_write_uhwi (ob, vec_safe_length (ts->bits));
   for (const ipa_bits *bits_jfunc : ts->bits)
@@ -5400,16 +5475,7 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
        {
          ipa_vr *parm_vr;
          parm_vr = &(*ts->m_vr)[i];
-         struct bitpack_d bp;
-         bp = streamer_read_bitpack (ib);
-         parm_vr->known = bp_unpack_value (&bp, 1);
-         if (parm_vr->known)
-           {
-             parm_vr->type = streamer_read_enum (ib, value_range_kind,
-                                                 VR_LAST);
-             parm_vr->min = streamer_read_wide_int (ib);
-             parm_vr->max = streamer_read_wide_int (ib);
-           }
+         parm_vr->streamer_read (ib, data_in);
        }
     }
   count = streamer_read_uhwi (ib);
@@ -5847,19 +5913,6 @@ ipcp_update_bits (struct cgraph_node *node)
     }
 }
 
-bool
-ipa_vr::nonzero_p (tree expr_type) const
-{
-  if (type == VR_ANTI_RANGE && wi::eq_p (min, 0) && wi::eq_p (max, 0))
-    return true;
-
-  unsigned prec = TYPE_PRECISION (expr_type);
-  return (type == VR_RANGE
-         && TYPE_UNSIGNED (expr_type)
-         && wi::eq_p (min, wi::one (prec))
-         && wi::eq_p (max, wi::max_value (prec, TYPE_SIGN (expr_type))));
-}
-
 /* Update value range of formal parameters as described in
    ipcp_transformation.  */
 
@@ -5908,38 +5961,21 @@ ipcp_update_vr (struct cgraph_node *node)
       if (!ddef || !is_gimple_reg (parm))
        continue;
 
-      if (vr[i].known
-         && (vr[i].type == VR_RANGE || vr[i].type == VR_ANTI_RANGE))
+      if (vr[i].known_p ())
        {
-         tree type = TREE_TYPE (ddef);
-         unsigned prec = TYPE_PRECISION (type);
-         if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
+         value_range tmp;
+         vr[i].get_vrange (tmp);
+
+         if (!tmp.undefined_p () && !tmp.varying_p ())
            {
              if (dump_file)
                {
                  fprintf (dump_file, "Setting value range of param %u "
                           "(now %i) ", i, remapped_idx);
-                 fprintf (dump_file, "%s[",
-                          (vr[i].type == VR_ANTI_RANGE) ? "~" : "");
-                 print_decs (vr[i].min, dump_file);
-                 fprintf (dump_file, ", ");
-                 print_decs (vr[i].max, dump_file);
+                 tmp.dump (dump_file);
                  fprintf (dump_file, "]\n");
                }
-             value_range v (type,
-                            wide_int_storage::from (vr[i].min, prec,
-                                                    TYPE_SIGN (type)),
-                            wide_int_storage::from (vr[i].max, prec,
-                                                    TYPE_SIGN (type)),
-                            vr[i].type);
-             set_range_info (ddef, v);
-           }
-         else if (POINTER_TYPE_P (TREE_TYPE (ddef))
-                  && vr[i].nonzero_p (TREE_TYPE (ddef)))
-           {
-             if (dump_file)
-               fprintf (dump_file, "Setting nonnull for %u\n", i);
-             set_ptr_nonnull (ddef);
+             set_range_info (ddef, tmp);
            }
        }
     }
index d4936d4eaffe1557ba62c85bc40224dad7cad168..f306f8a377e1e274c0ee9db3926c46719ad3be08 100644 (file)
@@ -309,12 +309,25 @@ public:
 class GTY(()) ipa_vr
 {
 public:
-  /* The data fields below are valid only if known is true.  */
-  bool known;
-  enum value_range_kind type;
-  wide_int min;
-  wide_int max;
-  bool nonzero_p (tree) const;
+  ipa_vr ();
+  ipa_vr (const vrange &);
+  void set_unknown ();
+  bool known_p () const { return m_storage != NULL; }
+  tree type () const { return m_type; }
+  void get_vrange (vrange &) const;
+  bool equal_p (const vrange &) const;
+  const vrange_storage *storage () const { return m_storage; }
+  void streamer_read (lto_input_block *, data_in *);
+  void streamer_write (output_block *) const;
+  void dump (FILE *) const;
+
+private:
+  friend void gt_pch_nx (struct ipa_vr &);
+  friend void gt_ggc_mx (struct ipa_vr &);
+  friend void gt_pch_nx (struct ipa_vr *, gt_pointer_operator, void *);
+
+  vrange_storage *m_storage;
+  tree m_type;
 };
 
 /* A jump function for a callsite represents the values passed as actual
index 7230522526f81ee2df318874893f49f06261b5da..3fee8fb22ce752e25b5919f0e2ae33f1f72ee5e3 100644 (file)
@@ -4081,11 +4081,11 @@ zap_useless_ipcp_results (const isra_func_summary *ifs, ipcp_transformation *ts)
   bool useful_vr = false;
   count = vec_safe_length (ts->m_vr);
   for (unsigned i = 0; i < count; i++)
-    if ((*ts->m_vr)[i].known)
+    if ((*ts->m_vr)[i].known_p ())
       {
        const isra_param_desc *desc = &(*ifs->m_parameters)[i];
        if (desc->locally_unused)
-         (*ts->m_vr)[i].known = false;
+         (*ts->m_vr)[i].set_unknown ();
        else
          useful_vr = true;
       }
index 19d6eda22f83c411c248dd08d6c01f348fa30f88..7e30834e645eb51f43fdc280ba9538d76a17adda 100644 (file)
@@ -13,4 +13,4 @@ static void fn1(c) unsigned char c;
 
 void fn3() { fn1 (267); }
 
-/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\) \\\[11, 35\\\]" "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\).* \\\[11, .*35\\\]" "cp" } } */
index e32a13c3d6afb7754bddd29a4c26f4404d1fdadb..42b8ec7785ddee2f2466f0d801000aaf2ca1df29 100644 (file)
@@ -28,5 +28,5 @@ int main ()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\) \\\[6," "cp" } } */
-/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\) \\\[0, 999\\\]" "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\).* \\\[6," "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\).* \\\[0, 999\\\]" "cp" } } */
index 31909bdbf2409566b0949bcda7fb58d46bcbffbc..b3ef9273891e14472da7ce4b7233e9cb6ef64cb2 100644 (file)
@@ -31,5 +31,5 @@ int main ()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\) \\\[4," "cp" } } */
-/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\) \\\[0, 11\\\]" "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\).* \\\[4," "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\).* \\\[0, 11\\\]" "cp" } } */
index 9b1dcf98b259649a86f4a9ea10330afe181c53c2..171f0341e18c497d7dffb080b5f248db3e3f74d3 100644 (file)
@@ -27,4 +27,4 @@ int main ()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\(now 0\\) \\\[0, 9\\\]" 2 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\(now 0\\) .irange. int \\\[0, 9\\\]" 2 "cp" } } */
index 941f80e00b23e702ee63c8006e6c9fb28a1c106e..d02b09f2c84d60b67421e9db9b95f45e86b90852 100644 (file)
@@ -24,5 +24,5 @@ int bar (struct st *s)
   foo (&s->b);
 }
 
-/* { dg-final { scan-ipa-dump "Setting nonnull for 0" "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range.* \\\[1, \\+INF\\\]" "cp" } } */
 /* { dg-final { scan-tree-dump-times "if" 1 "vrp1" } } */
index 571798dab511f5400881b45b6ee1770e8d0b8967..6bbd3f164393c9a3867d38777e06a57bc332ecd0 100644 (file)
@@ -30,5 +30,5 @@ int bar (struct st *s)
   foo (&arr2[1]);
 }
 
-/* { dg-final { scan-ipa-dump "Setting nonnull for 0" "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range.* \\\[1, \\+INF\\\]" "cp" } } */
 /* { dg-final { scan-tree-dump-times "if" 1 "vrp1" } } */
index 971db44344207576426f91fa92f4941306063f8f..03e7ab933636b9770599a6efd951d171a071b8d9 100644 (file)
@@ -30,5 +30,5 @@ int bar (struct st *s)
   foo (&b);
 }
 
-/* { dg-final { scan-ipa-dump "Setting nonnull for 0" "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range.* \\\[1, \\+INF\\\]" "cp" } } */
 /* { dg-final { scan-tree-dump-times "if" 1 "vrp1" } } */
index ca5aa29e975c500ccced5b7b10e98a00437bd2cb..471c622a53723c10fdc713d4e287ab0e8b3aafb5 100644 (file)
@@ -29,4 +29,4 @@ int main ()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\(now 0\\) \\\[-10, 9\\\]" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\(now 0\\) .irange. int \\\[-10, 9\\\]" 1 "cp" } } */
index 0ac5fb5277d2c8a6b7821ecba3852963d8b84d6b..a01ffbcc757997a4779d3e552f3e5f6e0182dc99 100644 (file)
@@ -39,4 +39,4 @@ main ()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\(now 0\\) \\\[-10, 9\\\]" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\(now 0\\) .irange. int \\\[-10, 9\\\]" 1 "cp" } } */