On Wed, 19 Jun 2013, Richard Biener wrote:

> 
> This templates the pointer-map implementation (actually it copies
> the implementation, leaving the old interface unchanged) providing
> a templated value type.  That's suitable to replace the various
> users requesting a pointer-to-integer-type map, like I noticed
> for the two LTO tree recording mechanisms.  Which in turn saves
> memory on 64bit hosts (and should be less heavy-weight on the cache).
> Not very much, but a quarter of the old pointer-map memory usage.
> 
> LTO bootstrap and regtest running on x86_64-unknown-linux-gnu.
> 
> In theory we can typedef pointer_map<void *> pointer_map_t, but
> that requires touching all pointer_map_t users to drop the
> leading 'struct' and eventually include pointer-set.h.
> 
> I changed the insert () interface to get another output as to
> whether the slot was present to avoid the need to have a special
> "not present" value.  That also makes it unnecessary to zero
> the values array.
>
> Any comments?
> 
> If not then I'll comb over existing pointer -> integer type map
> users and convert them.

Added the dominance.c one and changed the implementation to
"inherit" from pointer-set instead, sharing a bit more code.

The pointer-map template is also type-safe for the value array
so converting all pointer-map users will make the code a tiny
bit prettier.

The remaining integer type cases seem to store integer types
as large as pointer types so they fall in the same category
(but eventually they chose that large type for no good reason).

Old patch LTO bootstrapped and tested on x86_64-unknown-linux-gnu.

Any objections?

Thanks,
Richard.

2013-06-19  Richard Biener  <rguent...@suse.de>

        * pointer-set.h (struct pointer_set_t): Move here from
        pointer-set.c.
        (pointer_set_lookup): Declare.
        (class pointer_map): New template class implementing a
        generic pointer to T map.
        (pointer_map<T>::pointer_map, pointer_map<T>::~pointer_map,
        pointer_map<T>::contains, pointer_map<T>::insert,
        pointer_map<T>::traverse): New functions.
        * pointer-set.c (struct pointer_set_t): Moved to pointer-set.h.
        (pointer_set_lookup): New function.
        (pointer_set_contains): Use pointer_set_lookup.
        (pointer_set_insert): Likewise.
        (insert_aux): Remove.
        (struct pointer_map_t): Embed a pointer_set_t.
        (pointer_map_create): Adjust.
        (pointer_map_destroy): Likewise.
        (pointer_map_contains): Likewise.
        (pointer_map_insert): Likewise.
        (pointer_map_traverse): Likewise.
        * tree-streamer.h (struct streamer_tree_cache_d): Use a
        pointer_map<unsigned> instead of a pointer_map_t.
        * tree-streamer.c (streamer_tree_cache_insert_1): Adjust.
        (streamer_tree_cache_lookup): Likewise.
        (streamer_tree_cache_create): Likewise.
        (streamer_tree_cache_delete): Likewise.
        * lto-streamer.h (struct lto_tree_ref_encoder): Use a
        pointer_map<unsigned> instead of a pointer_map_t.
        (lto_init_tree_ref_encoder): Adjust.
        (lto_destroy_tree_ref_encoder): Likewise.
        * lto-section-out.c (lto_output_decl_index): Likewise.
        (lto_record_function_out_decl_state): Likewise.
        * dominance.c (iterate_fix_dominators): Use pointer_map<int>.

Index: gcc/pointer-set.c
===================================================================
*** gcc/pointer-set.c.orig      2013-06-19 12:28:49.000000000 +0200
--- gcc/pointer-set.c   2013-06-19 13:52:49.172792131 +0200
*************** along with GCC; see the file COPYING3.
*** 21,41 ****
  #include "system.h"
  #include "pointer-set.h"
  
- /* A pointer set is represented as a simple open-addressing hash
-    table.  Simplifications: The hash code is based on the value of the
-    pointer, not what it points to.  The number of buckets is always a
-    power of 2.  Null pointers are a reserved value.  Deletion is not
-    supported (yet).  There is no mechanism for user control of hash
-    function, equality comparison, initial size, or resizing policy.  */
- 
- struct pointer_set_t
- {
-   size_t log_slots;
-   size_t n_slots;             /* n_slots = 2^log_slots */
-   size_t n_elements;
- 
-   const void **slots;
- };
  
  /* Use the multiplicative method, as described in Knuth 6.4, to obtain
     a hash code for P in the range [0, MAX).  MAX == 2^LOGMAX.
--- 21,26 ----
*************** hash1 (const void *p, unsigned long max,
*** 67,72 ****
--- 52,58 ----
    return ((A * (uintptr_t) p) >> shift) & (max - 1);
  }
  
+ 
  /* Allocate an empty pointer set.  */
  struct pointer_set_t *
  pointer_set_create (void)
*************** pointer_set_destroy (struct pointer_set_
*** 89,108 ****
    XDELETE (pset);
  }
  
- /* Returns nonzero if PSET contains P.  P must be nonnull.
  
!    Collisions are resolved by linear probing.  */
! int
! pointer_set_contains (const struct pointer_set_t *pset, const void *p)
  {
    size_t n = hash1 (p, pset->n_slots, pset->log_slots);
  
    while (true)
      {
        if (pset->slots[n] == p)
!        return 1;
        else if (pset->slots[n] == 0)
!        return 0;
        else
         {
           ++n;
--- 75,102 ----
    XDELETE (pset);
  }
  
  
! /* Lookup the slot for the pointer P and return true if it exists,
!    otherwise return false in which case *IX points to the slot that
!    would be used on insertion.  */
! 
! bool
! pointer_set_lookup (const pointer_set_t *pset, const void *p, size_t *ix)
  {
    size_t n = hash1 (p, pset->n_slots, pset->log_slots);
  
    while (true)
      {
        if (pset->slots[n] == p)
!       {
!         *ix = n;
!         return true;
!       }
        else if (pset->slots[n] == 0)
!       {
!         *ix = n;
!         return false;
!       }
        else
         {
           ++n;
*************** pointer_set_contains (const struct point
*** 112,134 ****
      }
  }
  
! /* Subroutine of pointer_set_insert.  Return the insertion slot for P into
!    an empty element of SLOTS, an array of length N_SLOTS.  */
! static inline size_t
! insert_aux (const void *p, const void **slots, size_t n_slots, size_t 
log_slots)
  {
!   size_t n = hash1 (p, n_slots, log_slots);
!   while (true)
!     {
!       if (slots[n] == p || slots[n] == 0)
!       return n;
!       else
!       {
!         ++n;
!         if (n == n_slots)
!           n = 0;
!       }
!     }
  }
  
  /* Inserts P into PSET if it wasn't already there.  Returns nonzero
--- 106,119 ----
      }
  }
  
! /* Returns nonzero if PSET contains P.  P must be nonnull.
! 
!    Collisions are resolved by linear probing.  */
! int
! pointer_set_contains (const struct pointer_set_t *pset, const void *p)
  {
!   size_t n;
!   return pointer_set_lookup (pset, p, &n);
  }
  
  /* Inserts P into PSET if it wasn't already there.  Returns nonzero
*************** pointer_set_insert (struct pointer_set_t
*** 142,167 ****
       superfluous but can happen at most once.  */
    if (pset->n_elements > pset->n_slots / 4)
      {
!       size_t new_log_slots = pset->log_slots + 1;
!       size_t new_n_slots = pset->n_slots * 2;
!       const void **new_slots = XCNEWVEC (const void *, new_n_slots);
        size_t i;
  
!       for (i = 0; i < pset->n_slots; ++i)
          {
!         const void *value = pset->slots[i];
!         n = insert_aux (value, new_slots, new_n_slots, new_log_slots);
!         new_slots[n] = value;
        }
  
!       XDELETEVEC (pset->slots);
!       pset->n_slots = new_n_slots;
!       pset->log_slots = new_log_slots;
!       pset->slots = new_slots;
      }
  
!   n = insert_aux (p, pset->slots, pset->n_slots, pset->log_slots);
!   if (pset->slots[n])
      return 1;
  
    pset->slots[n] = p;
--- 127,150 ----
       superfluous but can happen at most once.  */
    if (pset->n_elements > pset->n_slots / 4)
      {
!       size_t old_n_slots = pset->n_slots;
!       const void **old_slots = pset->slots;
!       pset->log_slots = pset->log_slots + 1;
!       pset->n_slots = pset->n_slots * 2;
!       pset->slots = XCNEWVEC (const void *, pset->n_slots);
        size_t i;
  
!       for (i = 0; i < old_n_slots; ++i)
          {
!         const void *value = old_slots[i];
!         pointer_set_lookup (pset, value, &n);
!         pset->slots[n] = value;
        }
  
!       XDELETEVEC (old_slots);
      }
  
!   if (pointer_set_lookup (pset, p, &n))
      return 1;
  
    pset->slots[n] = p;
*************** void pointer_set_traverse (const struct
*** 190,200 ****
  
  struct pointer_map_t
  {
!   size_t log_slots;
!   size_t n_slots;             /* n_slots = 2^log_slots */
!   size_t n_elements;
! 
!   const void **keys;
    void **values;
  };
  
--- 173,179 ----
  
  struct pointer_map_t
  {
!   pointer_set_t pset;
    void **values;
  };
  
*************** pointer_map_create (void)
*** 204,222 ****
  {
    struct pointer_map_t *result = XNEW (struct pointer_map_t);
  
!   result->n_elements = 0;
!   result->log_slots = 8;
!   result->n_slots = (size_t) 1 << result->log_slots;
  
!   result->keys = XCNEWVEC (const void *, result->n_slots);
!   result->values = XCNEWVEC (void *, result->n_slots);
    return result;
  }
  
  /* Reclaims all memory associated with PMAP.  */
  void pointer_map_destroy (struct pointer_map_t *pmap)
  {
!   XDELETEVEC (pmap->keys);
    XDELETEVEC (pmap->values);
    XDELETE (pmap);
  }
--- 183,201 ----
  {
    struct pointer_map_t *result = XNEW (struct pointer_map_t);
  
!   result->pset.n_elements = 0;
!   result->pset.log_slots = 8;
!   result->pset.n_slots = (size_t) 1 << result->pset.log_slots;
  
!   result->pset.slots = XCNEWVEC (const void *, result->pset.n_slots);
!   result->values = XCNEWVEC (void *, result->pset.n_slots);
    return result;
  }
  
  /* Reclaims all memory associated with PMAP.  */
  void pointer_map_destroy (struct pointer_map_t *pmap)
  {
!   XDELETEVEC (pmap->pset.slots);
    XDELETEVEC (pmap->values);
    XDELETE (pmap);
  }
*************** void pointer_map_destroy (struct pointer
*** 228,248 ****
  void **
  pointer_map_contains (const struct pointer_map_t *pmap, const void *p)
  {
!   size_t n = hash1 (p, pmap->n_slots, pmap->log_slots);
! 
!   while (true)
!     {
!       if (pmap->keys[n] == p)
!       return &pmap->values[n];
!       else if (pmap->keys[n] == 0)
!       return NULL;
!       else
!        {
!          ++n;
!          if (n == pmap->n_slots)
!            n = 0;
!        }
!     }
  }
  
  /* Inserts P into PMAP if it wasn't already there.  Returns a pointer
--- 207,217 ----
  void **
  pointer_map_contains (const struct pointer_map_t *pmap, const void *p)
  {
!   size_t n;
!   if (pointer_set_lookup (&pmap->pset, p, &n))
!     return &pmap->values[n];
!   else
!     return NULL;
  }
  
  /* Inserts P into PMAP if it wasn't already there.  Returns a pointer
*************** pointer_map_insert (struct pointer_map_t
*** 254,289 ****
  
    /* For simplicity, expand the map even if P is already there.  This can be
       superfluous but can happen at most once.  */
!   if (pmap->n_elements > pmap->n_slots / 4)
      {
!       size_t new_log_slots = pmap->log_slots + 1;
!       size_t new_n_slots = pmap->n_slots * 2;
!       const void **new_keys = XCNEWVEC (const void *, new_n_slots);
!       void **new_values = XCNEWVEC (void *, new_n_slots);
        size_t i;
  
!       for (i = 0; i < pmap->n_slots; ++i)
!       if (pmap->keys[i])
          {
!           const void *key = pmap->keys[i];
!           n = insert_aux (key, new_keys, new_n_slots, new_log_slots);
!           new_keys[n] = key;
!           new_values[n] = pmap->values[i];
          }
  
!       XDELETEVEC (pmap->keys);
!       XDELETEVEC (pmap->values);
!       pmap->n_slots = new_n_slots;
!       pmap->log_slots = new_log_slots;
!       pmap->keys = new_keys;
!       pmap->values = new_values;
      }
  
!   n = insert_aux (p, pmap->keys, pmap->n_slots, pmap->log_slots);
!   if (!pmap->keys[n])
      {
!       ++pmap->n_elements;
!       pmap->keys[n] = p;
      }
  
    return &pmap->values[n];
--- 223,256 ----
  
    /* For simplicity, expand the map even if P is already there.  This can be
       superfluous but can happen at most once.  */
!   if (pmap->pset.n_elements > pmap->pset.n_slots / 4)
      {
!       size_t old_n_slots = pmap->pset.n_slots;
!       const void **old_keys = pmap->pset.slots;
!       void **old_values = pmap->values;
!       pmap->pset.log_slots = pmap->pset.log_slots + 1;
!       pmap->pset.n_slots = pmap->pset.n_slots * 2;
!       pmap->pset.slots = XCNEWVEC (const void *, pmap->pset.n_slots);
!       pmap->values = XCNEWVEC (void *, pmap->pset.n_slots);
        size_t i;
  
!       for (i = 0; i < old_n_slots; ++i)
!       if (old_keys[i])
          {
!           const void *key = old_keys[i];
!           pointer_set_lookup (&pmap->pset, key, &n);
!           pmap->pset.slots[n] = key;
!           pmap->values[n] = old_values[i];
          }
  
!       XDELETEVEC (old_keys);
!       XDELETEVEC (old_values);
      }
  
!   if (!pointer_set_lookup (&pmap->pset, p, &n))
      {
!       ++pmap->pset.n_elements;
!       pmap->pset.slots[n] = p;
      }
  
    return &pmap->values[n];
*************** void pointer_map_traverse (const struct
*** 297,303 ****
                           bool (*fn) (const void *, void **, void *), void 
*data)
  {
    size_t i;
!   for (i = 0; i < pmap->n_slots; ++i)
!     if (pmap->keys[i] && !fn (pmap->keys[i], &pmap->values[i], data))
        break;
  }
--- 264,271 ----
                           bool (*fn) (const void *, void **, void *), void 
*data)
  {
    size_t i;
!   for (i = 0; i < pmap->pset.n_slots; ++i)
!     if (pmap->pset.slots[i]
!       && !fn (pmap->pset.slots[i], &pmap->values[i], data))
        break;
  }
Index: gcc/pointer-set.h
===================================================================
*** gcc/pointer-set.h.orig      2013-06-19 12:28:49.000000000 +0200
--- gcc/pointer-set.h   2013-06-19 13:51:20.208731227 +0200
*************** along with GCC; see the file COPYING3.
*** 20,42 ****
  #ifndef POINTER_SET_H
  #define POINTER_SET_H
  
! struct pointer_set_t;
  struct pointer_set_t *pointer_set_create (void);
  void pointer_set_destroy (struct pointer_set_t *pset);
- 
  int pointer_set_contains (const struct pointer_set_t *pset, const void *p);
  int pointer_set_insert (struct pointer_set_t *pset, const void *p);
  void pointer_set_traverse (const struct pointer_set_t *,
                           bool (*) (const void *, void *),
                           void *);
  
  struct pointer_map_t;
! struct pointer_map_t *pointer_map_create (void);
! void pointer_map_destroy (struct pointer_map_t *pmap);
  
! void **pointer_map_contains (const struct pointer_map_t *pmap, const void *p);
! void **pointer_map_insert (struct pointer_map_t *pmap, const void *p);
! void pointer_map_traverse (const struct pointer_map_t *,
                           bool (*) (const void *, void **, void *), void *);
  
  #endif  /* POINTER_SET_H  */
--- 20,170 ----
  #ifndef POINTER_SET_H
  #define POINTER_SET_H
  
! 
! /* A pointer set is represented as a simple open-addressing hash
!    table.  Simplifications: The hash code is based on the value of the
!    pointer, not what it points to.  The number of buckets is always a
!    power of 2.  Null pointers are a reserved value.  Deletion is not
!    supported (yet).  There is no mechanism for user control of hash
!    function, equality comparison, initial size, or resizing policy.  */
! 
! struct pointer_set_t
! {
!   size_t log_slots;
!   size_t n_slots;             /* n_slots = 2^log_slots */
!   size_t n_elements;
!   const void **slots;
! };
! 
  struct pointer_set_t *pointer_set_create (void);
  void pointer_set_destroy (struct pointer_set_t *pset);
  int pointer_set_contains (const struct pointer_set_t *pset, const void *p);
  int pointer_set_insert (struct pointer_set_t *pset, const void *p);
  void pointer_set_traverse (const struct pointer_set_t *,
                           bool (*) (const void *, void *),
                           void *);
+ bool pointer_set_lookup (const pointer_set_t *, const void *, size_t *);
+ 
+ /* A pointer map is represented the same way as a pointer_set, so
+    the hash code is based on the address of the key, rather than
+    its contents.  Null keys are a reserved value.  Deletion is not
+    supported (yet).  There is no mechanism for user control of hash
+    function, equality comparison, initial size, or resizing policy.  */
+ 
+ template <typename T>
+ class pointer_map : protected pointer_set_t
+ {
+   T *values;
+ 
+ public:
+   pointer_map ();
+   ~pointer_map ();
+   T *contains (const void *p);
+   T *insert (const void *p, bool *existed_p = NULL);
+   void traverse (bool (*fn) (const void *, T *, void *), void *data);
+ };
+ 
+ /* Allocate an empty pointer map.  */
+ template <typename T>
+ pointer_map<T>::pointer_map (void)
+ {
+   n_elements = 0;
+   log_slots = 8;
+   n_slots = (size_t) 1 << log_slots;
+ 
+   slots = XCNEWVEC (const void *, n_slots);
+   values = XNEWVEC (T, n_slots);
+ }
+ 
+ /* Reclaims all memory associated with PMAP.  */
+ template <typename T>
+ pointer_map<T>::~pointer_map (void)
+ {
+   XDELETEVEC (slots);
+   XDELETEVEC (values);
+ }
+ 
+ /* Returns a pointer to the value to which P maps, if PMAP contains P.  P
+    must be nonnull.  Return NULL if PMAP does not contain P.
+ 
+    Collisions are resolved by linear probing.  */
+ template <typename T>
+ T *
+ pointer_map<T>::contains (const void *p)
+ {
+   size_t n;
+   if (!pointer_set_lookup (this, p, &n))
+     return NULL;
+   return &values[n];
+ }
+ 
+ /* Inserts P into PMAP if it wasn't already there.  Returns a pointer
+    to the value.  P must be nonnull.  */
+ template <typename T>
+ T *
+ pointer_map<T>::insert (const void *p, bool *existed_p)
+ {
+   size_t n;
+ 
+   /* For simplicity, expand the map even if P is already there.  This can be
+      superfluous but can happen at most once.  */
+   /* ???  Fugly that we have to inline that here.  */
+   if (n_elements > n_slots / 4)
+     {
+       size_t old_n_slots = n_slots;
+       const void **old_keys = slots;
+       T *old_values = values;
+       log_slots = log_slots + 1;
+       n_slots = n_slots * 2;
+       slots = XCNEWVEC (const void *, n_slots);
+       values = XNEWVEC (T, n_slots);
+       for (size_t i = 0; i < old_n_slots; ++i)
+       if (old_keys[i])
+         {
+           const void *key = old_keys[i];
+           pointer_set_lookup (this, key, &n);
+           slots[n] = key;
+           values[n] = old_values[i];
+         }
+       XDELETEVEC (old_keys);
+       XDELETEVEC (old_values);
+     }
+ 
+   if (!pointer_set_lookup (this, p, &n))
+     {
+       ++n_elements;
+       slots[n] = p;
+       if (existed_p)
+       *existed_p = false;
+     }
+   else if (existed_p)
+     *existed_p = true;
+ 
+   return &values[n];
+ }
+ 
+ /* Pass each pointer in PMAP to the function in FN, together with the pointer
+    to the value and the fixed parameter DATA.  If FN returns false, the
+    iteration stops.  */
+ 
+ template <class T>
+ void
+ pointer_map<T>::traverse (bool (*fn) (const void *, T *, void *), void *data)
+ {
+   for (size_t i = 0; i < n_slots; ++i)
+     if (slots[i] && !fn (slots[i], &values[i], data))
+       break;
+ }
+ 
  
  struct pointer_map_t;
! pointer_map_t *pointer_map_create (void);
! void pointer_map_destroy (pointer_map_t *pmap);
  
! void **pointer_map_contains (const pointer_map_t *pmap, const void *p);
! void **pointer_map_insert (pointer_map_t *pmap, const void *p);
! void pointer_map_traverse (const pointer_map_t *,
                           bool (*) (const void *, void **, void *), void *);
  
+ 
  #endif  /* POINTER_SET_H  */
Index: gcc/tree-streamer.c
===================================================================
*** gcc/tree-streamer.c.orig    2013-06-19 12:28:49.000000000 +0200
--- gcc/tree-streamer.c 2013-06-19 12:29:04.627440271 +0200
*************** streamer_tree_cache_insert_1 (struct str
*** 128,157 ****
                              tree t, hashval_t hash, unsigned *ix_p,
                              bool insert_at_next_slot_p)
  {
!   void **slot;
    unsigned ix;
    bool existed_p;
  
    gcc_assert (t);
  
!   slot = pointer_map_insert (cache->node_map, t);
!   if (!*slot)
      {
        /* Determine the next slot to use in the cache.  */
        if (insert_at_next_slot_p)
        ix = cache->nodes.length ();
        else
        ix = *ix_p;
!        *slot = (void *)(size_t) (ix + 1);
  
        streamer_tree_cache_add_to_node_array (cache, ix, t, hash);
- 
-       /* Indicate that the item was not present in the cache.  */
-       existed_p = false;
      }
    else
      {
!       ix = (size_t) *slot - 1;
  
        if (!insert_at_next_slot_p && ix != *ix_p)
        {
--- 128,154 ----
                              tree t, hashval_t hash, unsigned *ix_p,
                              bool insert_at_next_slot_p)
  {
!   unsigned *slot;
    unsigned ix;
    bool existed_p;
  
    gcc_assert (t);
  
!   slot = cache->node_map->insert (t, &existed_p);
!   if (!existed_p)
      {
        /* Determine the next slot to use in the cache.  */
        if (insert_at_next_slot_p)
        ix = cache->nodes.length ();
        else
        ix = *ix_p;
!        *slot = ix;
  
        streamer_tree_cache_add_to_node_array (cache, ix, t, hash);
      }
    else
      {
!       ix = *slot;
  
        if (!insert_at_next_slot_p && ix != *ix_p)
        {
*************** streamer_tree_cache_insert_1 (struct str
*** 160,170 ****
             the requested location slot.  */
          ix = *ix_p;
          streamer_tree_cache_add_to_node_array (cache, ix, t, hash);
!         *slot = (void *)(size_t) (ix + 1);
        }
- 
-       /* Indicate that T was already in the cache.  */
-       existed_p = true;
      }
  
    if (ix_p)
--- 157,164 ----
             the requested location slot.  */
          ix = *ix_p;
          streamer_tree_cache_add_to_node_array (cache, ix, t, hash);
!         *slot = ix;
        }
      }
  
    if (ix_p)
*************** bool
*** 225,237 ****
  streamer_tree_cache_lookup (struct streamer_tree_cache_d *cache, tree t,
                            unsigned *ix_p)
  {
!   void **slot;
    bool retval;
    unsigned ix;
  
    gcc_assert (t);
  
!   slot = pointer_map_contains  (cache->node_map, t);
    if (slot == NULL)
      {
        retval = false;
--- 219,231 ----
  streamer_tree_cache_lookup (struct streamer_tree_cache_d *cache, tree t,
                            unsigned *ix_p)
  {
!   unsigned *slot;
    bool retval;
    unsigned ix;
  
    gcc_assert (t);
  
!   slot = cache->node_map->contains (t);
    if (slot == NULL)
      {
        retval = false;
*************** streamer_tree_cache_lookup (struct strea
*** 240,246 ****
    else
      {
        retval = true;
!       ix = (size_t) *slot - 1;
      }
  
    if (ix_p)
--- 234,240 ----
    else
      {
        retval = true;
!       ix = *slot;
      }
  
    if (ix_p)
*************** streamer_tree_cache_create (bool with_ha
*** 332,338 ****
    cache = XCNEW (struct streamer_tree_cache_d);
  
    if (with_map)
!     cache->node_map = pointer_map_create ();
    cache->nodes.create (165);
    if (with_hashes)
      cache->hashes.create (165);
--- 326,332 ----
    cache = XCNEW (struct streamer_tree_cache_d);
  
    if (with_map)
!     cache->node_map = new pointer_map<unsigned>;
    cache->nodes.create (165);
    if (with_hashes)
      cache->hashes.create (165);
*************** streamer_tree_cache_delete (struct strea
*** 355,361 ****
      return;
  
    if (c->node_map)
!     pointer_map_destroy (c->node_map);
    c->nodes.release ();
    c->hashes.release ();
    free (c);
--- 349,355 ----
      return;
  
    if (c->node_map)
!     delete c->node_map;
    c->nodes.release ();
    c->hashes.release ();
    free (c);
Index: gcc/tree-streamer.h
===================================================================
*** gcc/tree-streamer.h.orig    2013-06-19 12:28:49.000000000 +0200
--- gcc/tree-streamer.h 2013-06-19 12:29:04.628440283 +0200
*************** along with GCC; see the file COPYING3.
*** 47,53 ****
  struct streamer_tree_cache_d
  {
    /* The mapping between tree nodes and slots into the nodes array.  */
!   struct pointer_map_t *node_map;
  
    /* The nodes pickled so far.  */
    vec<tree> nodes;
--- 47,53 ----
  struct streamer_tree_cache_d
  {
    /* The mapping between tree nodes and slots into the nodes array.  */
!   pointer_map<unsigned> *node_map;
  
    /* The nodes pickled so far.  */
    vec<tree> nodes;
Index: gcc/lto-streamer.h
===================================================================
*** gcc/lto-streamer.h.orig     2013-06-19 12:28:49.000000000 +0200
--- gcc/lto-streamer.h  2013-06-19 12:29:04.628440283 +0200
*************** struct GTY(()) lto_tree_ref_table
*** 479,485 ****
  
  struct lto_tree_ref_encoder
  {
!   pointer_map_t *tree_hash_table;     /* Maps pointers to indices. */
    vec<tree> trees;                    /* Maps indices to pointers. */
  };
  
--- 479,485 ----
  
  struct lto_tree_ref_encoder
  {
!   pointer_map<unsigned> *tree_hash_table;     /* Maps pointers to indices. */
    vec<tree> trees;                    /* Maps indices to pointers. */
  };
  
*************** lto_tag_check_range (enum LTO_tags actua
*** 997,1003 ****
  static inline void
  lto_init_tree_ref_encoder (struct lto_tree_ref_encoder *encoder)
  {
!   encoder->tree_hash_table = pointer_map_create ();
    encoder->trees.create (0);
  }
  
--- 997,1003 ----
  static inline void
  lto_init_tree_ref_encoder (struct lto_tree_ref_encoder *encoder)
  {
!   encoder->tree_hash_table = new pointer_map<unsigned>;
    encoder->trees.create (0);
  }
  
*************** lto_destroy_tree_ref_encoder (struct lto
*** 1009,1015 ****
  {
    /* Hash table may be delete already.  */
    if (encoder->tree_hash_table)
!     pointer_map_destroy (encoder->tree_hash_table);
    encoder->trees.release ();
  }
  
--- 1009,1015 ----
  {
    /* Hash table may be delete already.  */
    if (encoder->tree_hash_table)
!     delete encoder->tree_hash_table;
    encoder->trees.release ();
  }
  
Index: gcc/lto-section-out.c
===================================================================
*** gcc/lto-section-out.c.orig  2013-06-19 12:28:49.000000000 +0200
--- gcc/lto-section-out.c       2013-06-19 12:29:04.629440295 +0200
*************** lto_output_decl_index (struct lto_output
*** 233,252 ****
                       struct lto_tree_ref_encoder *encoder,
                       tree name, unsigned int *this_index)
  {
!   void **slot;
!   int index;
    bool new_entry_p = FALSE;
  
!   slot = pointer_map_insert (encoder->tree_hash_table, name);
!   if (*slot == NULL)
      {
        index = encoder->trees.length ();
!       *slot = (void *)(uintptr_t) index;
        encoder->trees.safe_push (name);
        new_entry_p = TRUE;
      }
    else
!     index = (uintptr_t) *slot;
  
    if (obs)
      streamer_write_uhwi_stream (obs, index);
--- 233,253 ----
                       struct lto_tree_ref_encoder *encoder,
                       tree name, unsigned int *this_index)
  {
!   unsigned *slot;
!   unsigned int index;
    bool new_entry_p = FALSE;
+   bool existed_p;
  
!   slot = encoder->tree_hash_table->insert (name, &existed_p);
!   if (!existed_p)
      {
        index = encoder->trees.length ();
!       *slot = index;
        encoder->trees.safe_push (name);
        new_entry_p = TRUE;
      }
    else
!     index = *slot;
  
    if (obs)
      streamer_write_uhwi_stream (obs, index);
*************** lto_record_function_out_decl_state (tree
*** 446,452 ****
    for (i = 0; i < LTO_N_DECL_STREAMS; i++)
      if (state->streams[i].tree_hash_table)
        {
!       pointer_map_destroy (state->streams[i].tree_hash_table);
        state->streams[i].tree_hash_table = NULL;
        }
    state->fn_decl = fn_decl;
--- 447,453 ----
    for (i = 0; i < LTO_N_DECL_STREAMS; i++)
      if (state->streams[i].tree_hash_table)
        {
!       delete state->streams[i].tree_hash_table;
        state->streams[i].tree_hash_table = NULL;
        }
    state->fn_decl = fn_decl;
Index: gcc/dominance.c
===================================================================
*** gcc/dominance.c.orig        2013-01-11 10:54:42.000000000 +0100
--- gcc/dominance.c     2013-06-19 14:14:12.308085487 +0200
*************** iterate_fix_dominators (enum cdi_directi
*** 1248,1254 ****
    size_t dom_i;
    edge e;
    edge_iterator ei;
!   struct pointer_map_t *map;
    int *parent, *son, *brother;
    unsigned int dir_index = dom_convert_dir_to_idx (dir);
  
--- 1248,1254 ----
    size_t dom_i;
    edge e;
    edge_iterator ei;
!   pointer_map<int> *map;
    int *parent, *son, *brother;
    unsigned int dir_index = dom_convert_dir_to_idx (dir);
  
*************** iterate_fix_dominators (enum cdi_directi
*** 1336,1350 ****
      }
  
    /* Construct the graph G.  */
!   map = pointer_map_create ();
    FOR_EACH_VEC_ELT (bbs, i, bb)
      {
        /* If the dominance tree is conservatively correct, split it now.  */
        if (conservative)
        set_immediate_dominator (CDI_DOMINATORS, bb, NULL);
!       *pointer_map_insert (map, bb) = (void *) (size_t) i;
      }
!   *pointer_map_insert (map, ENTRY_BLOCK_PTR) = (void *) (size_t) n;
  
    g = new_graph (n + 1);
    for (y = 0; y < g->n_vertices; y++)
--- 1336,1350 ----
      }
  
    /* Construct the graph G.  */
!   map = new pointer_map<int>;
    FOR_EACH_VEC_ELT (bbs, i, bb)
      {
        /* If the dominance tree is conservatively correct, split it now.  */
        if (conservative)
        set_immediate_dominator (CDI_DOMINATORS, bb, NULL);
!       *map->insert (bb) = i;
      }
!   *map->insert (ENTRY_BLOCK_PTR) = n;
  
    g = new_graph (n + 1);
    for (y = 0; y < g->n_vertices; y++)
*************** iterate_fix_dominators (enum cdi_directi
*** 1357,1363 ****
          if (dom == bb)
            continue;
  
!         dom_i = (size_t) *pointer_map_contains (map, dom);
  
          /* Do not include parallel edges to G.  */
          if (!bitmap_set_bit ((bitmap) g->vertices[dom_i].data, i))
--- 1357,1363 ----
          if (dom == bb)
            continue;
  
!         dom_i = *map->contains (dom);
  
          /* Do not include parallel edges to G.  */
          if (!bitmap_set_bit ((bitmap) g->vertices[dom_i].data, i))
*************** iterate_fix_dominators (enum cdi_directi
*** 1368,1374 ****
      }
    for (y = 0; y < g->n_vertices; y++)
      BITMAP_FREE (g->vertices[y].data);
!   pointer_map_destroy (map);
  
    /* Find the dominator tree of G.  */
    son = XNEWVEC (int, n + 1);
--- 1368,1374 ----
      }
    for (y = 0; y < g->n_vertices; y++)
      BITMAP_FREE (g->vertices[y].data);
!   delete map;
  
    /* Find the dominator tree of G.  */
    son = XNEWVEC (int, n + 1);

Reply via email to