On 2/26/19 7:48 PM, Richard Biener wrote:
> On February 26, 2019 6:50:13 PM GMT+01:00, "Martin Liška" <mli...@suse.cz> 
> wrote:
>> On 2/26/19 4:02 PM, Richard Biener wrote:
>>> On Tue, Feb 26, 2019 at 3:30 PM Martin Liška <mli...@suse.cz> wrote:
>>>>
>>>> Hi.
>>>>
>>>> I've rewritten bitmap memory statistics which abused unsigned
>>>> type via register_overhead (map, -((int)sizeof (bitmap_head))).
>>>> I come up with a concept that each bitmap has assigned a unique ID
>>>> which is used for stats tracking. It's caused by fact that e.g. DF
>> is
>>>> heavily reallocating bitmaps that then have a different address.
>>>>
>>>> Survives bootstrap with --enable-gather-detailed-mem-stats.
>>>>
>>>> Ready for next stage1?
>>>
>>> +  /* Get bitmap descriptor UID casted to an unsigned integer
>> pointer.  */
>>> +  unsigned *get_descriptor ()
>>> +  {
>>> +    return (unsigned *)(ptrdiff_t)alloc_descriptor;
>>> +  }
>>>
>>> this one is a bit ugly and together with
>>
>> I know it's not perfect.
>>
>>>
>>> template <typename Type>
>>> inline hashval_t
>>> pointer_hash <Type>::hash (const value_type &candidate)
>>> {
>>>   /* This is a really poor hash function, but it is what the current
>> code uses,
>>>      so I am reusing it to avoid an additional axis in testing.  */
>>>   return (hashval_t) ((intptr_t)candidate >> 3);
>>>
>>> will give quite some hash collisions.  So I guess you should shift
>>> the descriptor << 3 at least (and then make it at most 29 bits in
>>> size?).
>>
>> That's easily doable.
>>
>>> Not sure what to do about the descriptor wrapping btw.
>>
>> Question is whether we want to invest in our internal scaffolding more
>> time?
>> Or can we live with the ugly casting?
> 
> I guess we can live with it if we can avoid the hash collisions. 

Great.

Then there's updated version of the patch for next stage1.

Martin

> 
> Richard. 
> 
>> Martin
>>
>>>
>>> Richard.
>>>
>>>> Thanks,
>>>> Martin
>>>>
>>>> gcc/ChangeLog:
>>>>
>>>> 2019-02-26  Martin Liska  <mli...@suse.cz>
>>>>
>>>>         * bitmap.c (bitmap_register): Come up with
>>>>         alloc_descriptor_max_uid and assign it for
>>>>         a new bitmap.
>>>>         (register_overhead): Use get_descriptor as
>>>>         a descriptor.
>>>>         (release_overhead): New.
>>>>         (bitmap_elem_to_freelist): Call it.
>>>>         (bitmap_elt_clear_from): Likewise.
>>>>         (bitmap_obstack_free): Likewise.
>>>>         (bitmap_move): Sensitively release memory.
>>>>         * bitmap.h (struct GTY): Add alloc_descriptor.
>>>>         (bitmap_initialize): Initialize alloc_descriptor to zero.
>>>>         * tree-ssa-pre.c (do_hoist_insertion): Use bitmap_move.
>>>> ---
>>>>  gcc/bitmap.c       | 39 ++++++++++++++++++++++++++++-----------
>>>>  gcc/bitmap.h       | 17 ++++++++++++++---
>>>>  gcc/tree-ssa-pre.c |  2 +-
>>>>  3 files changed, 43 insertions(+), 15 deletions(-)
>>>>
>>>>
> 

>From 52615d17cc7f598855b647a70be5fafff9e56eba Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Tue, 19 Feb 2019 14:59:46 +0100
Subject: [PATCH] Fix bitmap registration of overheads.

gcc/ChangeLog:

2019-02-26  Martin Liska  <mli...@suse.cz>

	* bitmap.c (bitmap_register): Come up with
	alloc_descriptor_max_uid and assign it for
	a new bitmap.
	(register_overhead): Use get_descriptor as
	a descriptor.
	(release_overhead): New.
	(bitmap_elem_to_freelist): Call it.
	(bitmap_elt_clear_from): Likewise.
	(bitmap_obstack_free): Likewise.
	(bitmap_move): Sensitively release memory.
	* bitmap.h (struct GTY): Add alloc_descriptor.
	(bitmap_initialize): Initialize alloc_descriptor to zero.
	* tree-ssa-pre.c (do_hoist_insertion): Use bitmap_move.
---
 gcc/bitmap.c       | 39 ++++++++++++++++++++++++++++-----------
 gcc/bitmap.h       | 17 ++++++++++++++---
 gcc/tree-ssa-pre.c |  2 +-
 3 files changed, 43 insertions(+), 15 deletions(-)

diff --git a/gcc/bitmap.c b/gcc/bitmap.c
index 5a8236de750..894aefa13de 100644
--- a/gcc/bitmap.c
+++ b/gcc/bitmap.c
@@ -36,18 +36,33 @@ static bitmap_element *bitmap_tree_listify_from (bitmap, bitmap_element *);
 void
 bitmap_register (bitmap b MEM_STAT_DECL)
 {
-  bitmap_mem_desc.register_descriptor (b, BITMAP_ORIGIN, false
-				       FINAL_PASS_MEM_STAT);
+  static unsigned alloc_descriptor_max_uid = 1;
+  gcc_assert (b->alloc_descriptor == 0);
+  b->alloc_descriptor = alloc_descriptor_max_uid++;
+
+  bitmap_mem_desc.register_descriptor (b->get_descriptor (), BITMAP_ORIGIN,
+				       false FINAL_PASS_MEM_STAT);
 }
 
 /* Account the overhead.  */
 static void
 register_overhead (bitmap b, size_t amount)
 {
-  if (bitmap_mem_desc.contains_descriptor_for_instance (b))
-    bitmap_mem_desc.register_instance_overhead (amount, b);
+  unsigned *d = b->get_descriptor ();
+  if (bitmap_mem_desc.contains_descriptor_for_instance (d))
+    bitmap_mem_desc.register_instance_overhead (amount, d);
+}
+
+/* Release the overhead.  */
+static void
+release_overhead (bitmap b, size_t amount, bool remove_from_map)
+{
+  unsigned *d = b->get_descriptor ();
+  if (bitmap_mem_desc.contains_descriptor_for_instance (d))
+    bitmap_mem_desc.release_instance_overhead (d, amount, remove_from_map);
 }
 
+
 /* Global data */
 bitmap_element bitmap_zero_bits;  /* An element of all zero bits.  */
 bitmap_obstack bitmap_default_obstack;    /* The default bitmap obstack.  */
@@ -65,7 +80,7 @@ bitmap_elem_to_freelist (bitmap head, bitmap_element *elt)
   bitmap_obstack *bit_obstack = head->obstack;
 
   if (GATHER_STATISTICS)
-    register_overhead (head, -((int)sizeof (bitmap_element)));
+    release_overhead (head, sizeof (bitmap_element), false);
 
   elt->next = NULL;
   elt->indx = -1;
@@ -153,7 +168,7 @@ bitmap_elt_clear_from (bitmap head, bitmap_element *elt)
       int n = 0;
       for (prev = elt; prev; prev = prev->next)
 	n++;
-      register_overhead (head, -sizeof (bitmap_element) * n);
+      release_overhead (head, sizeof (bitmap_element) * n, false);
     }
 
   prev = elt->prev;
@@ -798,7 +813,7 @@ bitmap_obstack_free (bitmap map)
       map->first = (bitmap_element *) map->obstack->heads;
 
       if (GATHER_STATISTICS)
-	register_overhead (map, -((int)sizeof (bitmap_head)));
+	release_overhead (map, sizeof (bitmap_head), true);
 
       map->obstack->heads = map;
     }
@@ -872,16 +887,18 @@ bitmap_move (bitmap to, bitmap from)
 
   bitmap_clear (to);
 
-  *to = *from;
-
+  size_t sz = 0;
   if (GATHER_STATISTICS)
     {
-      size_t sz = 0;
       for (bitmap_element *e = to->first; e; e = e->next)
 	sz += sizeof (bitmap_element);
       register_overhead (to, sz);
-      register_overhead (from, -sz);
     }
+
+  *to = *from;
+
+  if (GATHER_STATISTICS)
+    release_overhead (from, sz, false);
 }
 
 /* Clear a single bit in a bitmap.  Return true if the bit changed.  */
diff --git a/gcc/bitmap.h b/gcc/bitmap.h
index ed25c1ee5da..b0813ebb1c2 100644
--- a/gcc/bitmap.h
+++ b/gcc/bitmap.h
@@ -325,14 +325,16 @@ struct GTY(()) bitmap_head {
   static bitmap_obstack crashme;
   /* Poison obstack to not make it not a valid initialized GC bitmap.  */
   CONSTEXPR bitmap_head()
-    : indx(0), tree_form(false), first(NULL), current(NULL),
-      obstack (&crashme)
+    : indx (0), tree_form (false), alloc_descriptor (0), first (NULL),
+      current (NULL), obstack (&crashme)
   {}
   /* Index of last element looked at.  */
   unsigned int indx;
   /* False if the bitmap is in list form; true if the bitmap is in tree form.
      Bitmap iterators only work on bitmaps in list form.  */
-  bool tree_form;
+  unsigned tree_form: 1;
+  /* Bitmap UID used for memory allocation statistics.  */
+  unsigned alloc_descriptor: 29;
   /* In list form, the first element in the linked list;
      in tree form, the root of the tree.   */
   bitmap_element *first;
@@ -340,7 +342,15 @@ struct GTY(()) bitmap_head {
   bitmap_element * GTY((skip(""))) current;
   /* Obstack to allocate elements from.  If NULL, then use GGC allocation.  */
   bitmap_obstack * GTY((skip(""))) obstack;
+
+  /* Dump bitmap.  */
   void dump ();
+
+  /* Get bitmap descriptor UID casted to an unsigned integer pointer.  */
+  unsigned *get_descriptor ()
+  {
+    return (unsigned *)(ptrdiff_t)(alloc_descriptor << 3);
+  }
 };
 
 /* Global data */
@@ -441,6 +451,7 @@ bitmap_initialize (bitmap head, bitmap_obstack *obstack CXX_MEM_STAT_INFO)
 {
   head->first = head->current = NULL;
   head->indx = head->tree_form = 0;
+  head->alloc_descriptor = 0;
   head->obstack = obstack;
   if (GATHER_STATISTICS)
     bitmap_register (head PASS_MEM_STAT);
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 3f38371cb21..7d6d9dee48a 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3531,7 +3531,7 @@ do_hoist_insertion (basic_block block)
     return false;
 
   /* Hack hoitable_set in-place so we can use sorted_array_from_bitmap_set.  */
-  hoistable_set.values = availout_in_some;
+  bitmap_move (&hoistable_set.values, &availout_in_some);
   hoistable_set.expressions = ANTIC_IN (block)->expressions;
 
   /* Now finally construct the topological-ordered expression set.  */
-- 
2.20.1

Reply via email to