public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-3161] Improve handling of modref params.
@ 2021-08-26 14:58 Jan Hubicka
  0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2021-08-26 14:58 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:e28ac73af20028f829c4ba1ffd38ea84e7419b0d

commit r12-3161-ge28ac73af20028f829c4ba1ffd38ea84e7419b0d
Author: Jan Hubicka <hubicka@ucw.cz>
Date:   Thu Aug 26 16:57:46 2021 +0200

    Improve handling of modref params.
    
    this patch makes insertion to modref access tree smarter when --param
    modref-max-bases and moredref-max-refs are hit.  Instead of giving up
    we either give up on base alias set (make it equal to ref) or turn the
    alias set to 0.  This lets us to track useful info on quite large
    functions, such as ggc_free.
    
    gcc/ChangeLog:
    
            * ipa-modref-tree.c (test_insert_search_collapse): Update test.
            * ipa-modref-tree.h (modref_base_node::insert): Be smarter when
            hiting --param modref-max-refs limit.
            (modref_tree:insert_base): Be smarter when hitting
            --param modref-max-bases limit. Add new parameter REF.
            (modref_tree:insert): Update.
            (modref_tree:merge): Update.
            * ipa-modref.c (read_modref_records): Update.

Diff:
---
 gcc/ipa-modref-tree.c |   2 +-
 gcc/ipa-modref-tree.h | 108 ++++++++++++++++++++++++++++----------------------
 gcc/ipa-modref.c      |   4 +-
 3 files changed, 63 insertions(+), 51 deletions(-)

diff --git a/gcc/ipa-modref-tree.c b/gcc/ipa-modref-tree.c
index 69395b0113c..8d147a18aed 100644
--- a/gcc/ipa-modref-tree.c
+++ b/gcc/ipa-modref-tree.c
@@ -101,7 +101,7 @@ test_insert_search_collapse ()
   ASSERT_TRUE (base_node->every_ref);
 
   /* Insert base to trigger base list collapse.  */
-  t->insert (5, 6, a, false);
+  t->insert (5, 0, a, false);
   ASSERT_TRUE (t->every_base);
   ASSERT_EQ (t->bases, NULL);
   ASSERT_EQ (t->search (1), NULL);
diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index 4edec4efded..97934a91ada 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -463,18 +463,23 @@ struct GTY((user)) modref_base_node
     if (ref_node)
       return ref_node;
 
-    if (changed)
-      *changed = true;
-
-    /* Collapse the node if too full already.  */
-    if (refs && refs->length () >= max_refs)
+    /* We always allow inserting ref 0.  For non-0 refs there is upper
+       limit on number of entries and if exceeded,
+       drop ref conservatively to 0.  */
+    if (ref && refs && refs->length () >= max_refs)
       {
 	if (dump_file)
-	  fprintf (dump_file, "--param param=modref-max-refs limit reached\n");
-	collapse ();
-	return NULL;
+	  fprintf (dump_file, "--param param=modref-max-refs limit reached;"
+		   " using 0\n");
+	ref = 0;
+	ref_node = search (ref);
+	if (ref_node)
+	  return ref_node;
       }
 
+    if (changed)
+      *changed = true;
+
     ref_node = new (ggc_alloc <modref_ref_node <T> > ())modref_ref_node <T>
 								 (ref);
     vec_safe_push (refs, ref_node);
@@ -532,9 +537,10 @@ struct GTY((user)) modref_tree
 
   /* Insert BASE; collapse tree if there are more than MAX_REFS.
      Return inserted base and if CHANGED is non-null set it to true if
-     something changed.  */
+     something changed.
+     If table gets full, try to insert REF instead.  */
 
-  modref_base_node <T> *insert_base (T base, bool *changed = NULL)
+  modref_base_node <T> *insert_base (T base, T ref, bool *changed = NULL)
   {
     modref_base_node <T> *base_node;
 
@@ -547,18 +553,31 @@ struct GTY((user)) modref_tree
     if (base_node)
       return base_node;
 
-    if (changed)
-      *changed = true;
-
-    /* Collapse the node if too full already.  */
-    if (bases && bases->length () >= max_bases)
+    /* We always allow inserting base 0.  For non-0 base there is upper
+       limit on number of entries and if exceeded,
+       drop base conservatively to ref and if it still does not fit to 0.  */
+    if (base && bases && bases->length () >= max_bases)
       {
+	base_node = search (ref);
+	if (base_node)
+	  {
+	    if (dump_file)
+	      fprintf (dump_file, "--param param=modref-max-bases"
+		       " limit reached; using ref\n");
+	    return base_node;
+	  }
 	if (dump_file)
-	  fprintf (dump_file, "--param param=modref-max-bases limit reached\n");
-	collapse ();
-	return NULL;
+	  fprintf (dump_file, "--param param=modref-max-bases"
+		   " limit reached; using 0\n");
+	base = 0;
+	base_node = search (base);
+	if (base_node)
+	  return base_node;
       }
 
+    if (changed)
+      *changed = true;
+
     base_node = new (ggc_alloc <modref_base_node <T> > ())
 			 modref_base_node <T> (base);
     vec_safe_push (bases, base_node);
@@ -582,8 +601,15 @@ struct GTY((user)) modref_tree
 	return true;
       }
 
-    modref_base_node <T> *base_node = insert_base (base, &changed);
-    if (!base_node || base_node->every_ref)
+    modref_base_node <T> *base_node = insert_base (base, ref, &changed);
+    base = base_node->base;
+    /* If table got full we may end up with useless base.  */
+    if (!base && !ref && !a.useful_p ())
+      {
+	collapse ();
+	return true;
+      }
+    if (base_node->every_ref)
       return changed;
     gcc_checking_assert (search (base) != NULL);
 
@@ -596,40 +622,26 @@ struct GTY((user)) modref_tree
 
     modref_ref_node <T> *ref_node = base_node->insert_ref (ref, max_refs,
 							   &changed);
+    ref = ref_node->ref;
 
-    /* If we failed to insert ref, just see if there is a cleanup possible.  */
-    if (!ref_node)
+    if (ref_node->every_access)
+      return changed;
+    changed |= ref_node->insert_access (a, max_accesses,
+					record_adjustments);
+    /* See if we failed to add useful access.  */
+    if (ref_node->every_access)
       {
-	/* No useful ref information and no useful base; collapse everything.  */
-	if (!base && base_node->every_ref)
+	/* Collapse everything if there is no useful base and ref.  */
+	if (!base && !ref)
 	  {
 	    collapse ();
 	    gcc_checking_assert (changed);
 	  }
-	else if (changed)
-	  cleanup ();
-      }
-    else
-      {
-	if (ref_node->every_access)
-	  return changed;
-	changed |= ref_node->insert_access (a, max_accesses,
-					    record_adjustments);
-	/* See if we failed to add useful access.  */
-	if (ref_node->every_access)
+	/* Collapse base if there is no useful ref.  */
+	else if (!ref)
 	  {
-	    /* Collapse everything if there is no useful base and ref.  */
-	    if (!base && !ref)
-	      {
-		collapse ();
-		gcc_checking_assert (changed);
-	      }
-	    /* Collapse base if there is no useful ref.  */
-	    else if (!ref)
-	      {
-		base_node->collapse ();
-		gcc_checking_assert (changed);
-	      }
+	    base_node->collapse ();
+	    gcc_checking_assert (changed);
 	  }
       }
     return changed;
@@ -714,7 +726,7 @@ struct GTY((user)) modref_tree
       {
 	if (base_node->every_ref)
 	  {
-	    my_base_node = insert_base (base_node->base, &changed);
+	    my_base_node = insert_base (base_node->base, 0, &changed);
 	    if (my_base_node && !my_base_node->every_ref)
 	      {
 		my_base_node->collapse ();
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 0d5ab9c0561..6e7788efb01 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -2445,9 +2445,9 @@ read_modref_records (lto_input_block *ib, struct data_in *data_in,
       if (nolto_ret)
 	nolto_base_node = (*nolto_ret)->insert_base (base_tree
 						     ? get_alias_set (base_tree)
-						     : 0);
+						     : 0, 0);
       if (lto_ret)
-	lto_base_node = (*lto_ret)->insert_base (base_tree);
+	lto_base_node = (*lto_ret)->insert_base (base_tree, 0);
       size_t every_ref = streamer_read_uhwi (ib);
       size_t nref = streamer_read_uhwi (ib);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-08-26 14:58 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-26 14:58 [gcc r12-3161] Improve handling of modref params Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).