]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ipa-cp: Use the VR and bits lattices for clones of non-local functions too
authorMartin Jambor <mjambor@suse.cz>
Wed, 7 Jan 2026 12:34:45 +0000 (13:34 +0100)
committerMartin Jambor <jamborm@gcc.gnu.org>
Fri, 9 Jan 2026 14:34:58 +0000 (15:34 +0100)
Since the IPA-CP lattices for value ranges cannot hold more values and
don't have any "variable" flag, we initialize them to bottom for
non-local nodes.  However, that means we don't make use of known
information gathered in jump functions when the corresponding node is
cloned for some other reason.  This patch allows collection of the
information and only does not use them for the original non-local
nodes, while making sure that we do not propagate information through
such-non local nodes as there may be unknown calls.

gcc/ChangeLog:

2026-01-06  Martin Jambor  <mjambor@suse.cz>

* ipa-cp.h (class ipcp_bits_lattice): New members set_recipient_only,
recipient_only_p and m_recipient_only.
(class ipcp_vr_lattice): Likewise.
(ipcp_vr_lattice::init): Initialize also m_recipient_only.
* ipa-cp.cc (ipcp_bits_lattice::print): Adjust printting to also
print the new flag.
(ipcp_vr_lattice::print): Likewise.
(ipcp_vr_lattice::set_recipient_only): New function.
(ipcp_bits_lattice::set_recipient_only): Likewise.
(set_all_contains_variable): New parameter MAKE_SIMPLE_RECIPIENTS, set
bits and vr lattices to recibient only insted to bottom when it is
true.
(initialize_node_lattices): Pass true to the second parameter of
set_all_contains_variable.
(propagate_bits_across_jump_function): Treat recipient_only source
lattices like bottom.
(propagate_vr_across_jump_function): Likewise.
(ipcp_store_vr_results): Skip non-local nodes.

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

index 769531db193bc0ce0a5dba1a9e1be77b4e6253dc..54f4e4f543c2ec323f032d6ed17dfafdd18d6b12 100644 (file)
@@ -339,18 +339,25 @@ ipcp_print_widest_int (FILE *f, const widest_int &value)
 void
 ipcp_bits_lattice::print (FILE *f)
 {
+  if (bottom_p ())
+    {
+      fprintf (f, "         Bits unusable (BOTTOM)\n");
+      return;
+    }
+
   if (top_p ())
-    fprintf (f, "         Bits unknown (TOP)\n");
-  else if (bottom_p ())
-    fprintf (f, "         Bits unusable (BOTTOM)\n");
+    fprintf (f, "         Bits unknown (TOP)");
   else
     {
       fprintf (f, "         Bits: value = ");
       ipcp_print_widest_int (f, get_value ());
       fprintf (f, ", mask = ");
       ipcp_print_widest_int (f, get_mask ());
-      fprintf (f, "\n");
     }
+
+  if (m_recipient_only)
+    fprintf (f, " (recipient only)");
+  fprintf (f, "\n");
 }
 
 /* Print value range lattice to F.  */
@@ -358,6 +365,8 @@ ipcp_bits_lattice::print (FILE *f)
 void
 ipcp_vr_lattice::print (FILE * f)
 {
+  if (m_recipient_only)
+    fprintf (f, "(recipient only) ");
   m_vr.dump (f);
 }
 
@@ -888,6 +897,18 @@ ipcp_vr_lattice::set_to_bottom ()
   return true;
 }
 
+/* Set the flag that this lattice is a recipient only, return true if it was
+   not set before.  */
+
+bool
+ipcp_vr_lattice::set_recipient_only ()
+{
+  if (m_recipient_only)
+    return false;
+  m_recipient_only = true;
+  return true;
+}
+
 /* Set lattice value to bottom, if it already isn't the case.  */
 
 bool
@@ -924,6 +945,18 @@ ipcp_bits_lattice::known_nonzero_p () const
   return wi::ne_p (wi::bit_and (wi::bit_not (m_mask), m_value), 0);
 }
 
+/* Set the flag that this lattice is a recipient only, return true if it was not
+   set before.  */
+
+bool
+ipcp_bits_lattice::set_recipient_only ()
+{
+  if (m_recipient_only)
+    return false;
+  m_recipient_only = true;
+  return true;
+}
+
 /* Convert operand to value, mask form.  */
 
 void
@@ -1326,17 +1359,28 @@ intersect_argaggs_with (vec<ipa_argagg_value> &elts,
 }
 
 /* Mark bot aggregate and scalar lattices as containing an unknown variable,
-   return true is any of them has not been marked as such so far.  */
+   return true is any of them has not been marked as such so far.  If if
+   MAKE_SIMPLE_RECIPIENTS is true, set the lattices that can only hold one
+   value to being recipients only, otherwise also set them to bottom.  */
 
 static inline bool
-set_all_contains_variable (class ipcp_param_lattices *plats)
+set_all_contains_variable (class ipcp_param_lattices *plats,
+                          bool make_simple_recipients = false)
 {
   bool ret;
   ret = plats->itself.set_contains_variable ();
   ret |= plats->ctxlat.set_contains_variable ();
   ret |= set_agg_lats_contain_variable (plats);
-  ret |= plats->bits_lattice.set_to_bottom ();
-  ret |= plats->m_value_range.set_to_bottom ();
+  if (make_simple_recipients)
+    {
+      ret |= plats->bits_lattice.set_recipient_only ();
+      ret |= plats->m_value_range.set_recipient_only ();
+    }
+  else
+    {
+      ret |= plats->bits_lattice.set_to_bottom ();
+      ret |= plats->m_value_range.set_to_bottom ();
+    }
   return ret;
 }
 
@@ -1481,7 +1525,7 @@ initialize_node_lattices (struct cgraph_node *node)
        {
          plats->m_value_range.init (type);
          if (variable)
-           set_all_contains_variable (plats);
+           set_all_contains_variable (plats, true);
        }
     }
 
@@ -2573,7 +2617,8 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
         result of x & 0xff == 0xff, which gets computed during ccp1 pass
         and we store it in jump function during analysis stage.  */
 
-      if (!src_lats->bits_lattice.bottom_p ())
+      if (!src_lats->bits_lattice.bottom_p ()
+         || src_lats->bits_lattice.recipient_only_p ())
        {
          if (!op_type)
            op_type = ipa_get_type (caller_info, src_idx);
@@ -2639,7 +2684,8 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
        = ipa_get_parm_lattices (caller_info, src_idx);
       tree operand_type = ipa_get_type (caller_info, src_idx);
 
-      if (src_lats->m_value_range.bottom_p ())
+      if (src_lats->m_value_range.bottom_p ()
+         || src_lats->m_value_range.recipient_only_p ())
        return dest_lat->set_to_bottom ();
 
       if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR
@@ -6530,6 +6576,11 @@ ipcp_store_vr_results (void)
       bool do_vr = true;
       bool do_bits = true;
 
+      /* If the function is not local, the gathered information is only useful
+        for clones.  */
+      if (!node->local)
+       continue;
+
       if (!info || !opt_for_fn (node->decl, flag_ipa_vrp))
        {
          if (dump_file)
index 521983d9ad91b4bb447a7c8e41e398908c219019..45da483e9abb22a3a3aa1eeb6da12703f4769bf1 100644 (file)
@@ -201,6 +201,8 @@ public:
   bool set_to_bottom ();
   bool set_to_constant (widest_int, widest_int);
   bool known_nonzero_p () const;
+  bool set_recipient_only ();
+  bool recipient_only_p () const {return m_recipient_only; }
 
   widest_int get_value () const { return m_value; }
   widest_int get_mask () const { return m_mask; }
@@ -216,6 +218,11 @@ private:
   enum { IPA_BITS_UNDEFINED, IPA_BITS_CONSTANT, IPA_BITS_VARYING }
     m_lattice_val = IPA_BITS_UNDEFINED;
 
+  /* Set to true if the lattice is valid only as a recipient of propagatad
+     values but cannot be used as source of propagation because there may be
+     unknown callers.  */
+  bool m_recipient_only;
+
   /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
      If a bit in mask is set to 0, then the corresponding bit in
      value is known to be constant.  */
@@ -231,10 +238,16 @@ class ipcp_vr_lattice
 {
 public:
   value_range m_vr;
+  /* Set to true if the lattice is valid only as a recipient of propagatad
+     values but cannot be used as source of propagation because there may be
+     unknown callers.  */
+  bool m_recipient_only;
 
   inline bool bottom_p () const;
   inline bool top_p () const;
   inline bool set_to_bottom ();
+  bool set_recipient_only ();
+  bool recipient_only_p () const {return m_recipient_only; }
   bool meet_with (const vrange &p_vr);
   bool meet_with (const ipcp_vr_lattice &other);
   void init (tree type);
@@ -251,6 +264,7 @@ ipcp_vr_lattice::init (tree type)
     m_vr.set_type (type);
 
   // Otherwise m_vr will default to unsupported_range.
+  m_recipient_only = false;
 }
 
 /* Structure containing lattices for a parameter itself and for pieces of