Commit 7c5848b8 by Richard Biener Committed by Richard Biener

pointer-set.h (struct pointer_set_t): Move here from pointer-set.c.

2013-06-24  Richard Biener  <rguenther@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>.

From-SVN: r200367
parent e04518ae
2013-06-24 Richard Biener <rguenther@suse.de> 2013-06-24 Richard Biener <rguenther@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>.
2013-06-24 Richard Biener <rguenther@suse.de>
PR tree-optimization/57488 PR tree-optimization/57488
* tree-ssa-pre.c (insert): Clear NEW sets before each iteration. * tree-ssa-pre.c (insert): Clear NEW sets before each iteration.
......
...@@ -1248,7 +1248,7 @@ iterate_fix_dominators (enum cdi_direction dir, vec<basic_block> bbs, ...@@ -1248,7 +1248,7 @@ iterate_fix_dominators (enum cdi_direction dir, vec<basic_block> bbs,
size_t dom_i; size_t dom_i;
edge e; edge e;
edge_iterator ei; edge_iterator ei;
struct pointer_map_t *map; pointer_map<int> *map;
int *parent, *son, *brother; int *parent, *son, *brother;
unsigned int dir_index = dom_convert_dir_to_idx (dir); unsigned int dir_index = dom_convert_dir_to_idx (dir);
...@@ -1336,15 +1336,15 @@ iterate_fix_dominators (enum cdi_direction dir, vec<basic_block> bbs, ...@@ -1336,15 +1336,15 @@ iterate_fix_dominators (enum cdi_direction dir, vec<basic_block> bbs,
} }
/* Construct the graph G. */ /* Construct the graph G. */
map = pointer_map_create (); map = new pointer_map<int>;
FOR_EACH_VEC_ELT (bbs, i, bb) FOR_EACH_VEC_ELT (bbs, i, bb)
{ {
/* If the dominance tree is conservatively correct, split it now. */ /* If the dominance tree is conservatively correct, split it now. */
if (conservative) if (conservative)
set_immediate_dominator (CDI_DOMINATORS, bb, NULL); set_immediate_dominator (CDI_DOMINATORS, bb, NULL);
*pointer_map_insert (map, bb) = (void *) (size_t) i; *map->insert (bb) = i;
} }
*pointer_map_insert (map, ENTRY_BLOCK_PTR) = (void *) (size_t) n; *map->insert (ENTRY_BLOCK_PTR) = n;
g = new_graph (n + 1); g = new_graph (n + 1);
for (y = 0; y < g->n_vertices; y++) for (y = 0; y < g->n_vertices; y++)
...@@ -1357,7 +1357,7 @@ iterate_fix_dominators (enum cdi_direction dir, vec<basic_block> bbs, ...@@ -1357,7 +1357,7 @@ iterate_fix_dominators (enum cdi_direction dir, vec<basic_block> bbs,
if (dom == bb) if (dom == bb)
continue; continue;
dom_i = (size_t) *pointer_map_contains (map, dom); dom_i = *map->contains (dom);
/* Do not include parallel edges to G. */ /* Do not include parallel edges to G. */
if (!bitmap_set_bit ((bitmap) g->vertices[dom_i].data, i)) if (!bitmap_set_bit ((bitmap) g->vertices[dom_i].data, i))
...@@ -1368,7 +1368,7 @@ iterate_fix_dominators (enum cdi_direction dir, vec<basic_block> bbs, ...@@ -1368,7 +1368,7 @@ iterate_fix_dominators (enum cdi_direction dir, vec<basic_block> bbs,
} }
for (y = 0; y < g->n_vertices; y++) for (y = 0; y < g->n_vertices; y++)
BITMAP_FREE (g->vertices[y].data); BITMAP_FREE (g->vertices[y].data);
pointer_map_destroy (map); delete map;
/* Find the dominator tree of G. */ /* Find the dominator tree of G. */
son = XNEWVEC (int, n + 1); son = XNEWVEC (int, n + 1);
......
...@@ -225,20 +225,21 @@ lto_output_decl_index (struct lto_output_stream *obs, ...@@ -225,20 +225,21 @@ lto_output_decl_index (struct lto_output_stream *obs,
struct lto_tree_ref_encoder *encoder, struct lto_tree_ref_encoder *encoder,
tree name, unsigned int *this_index) tree name, unsigned int *this_index)
{ {
void **slot; unsigned *slot;
int index; unsigned int index;
bool new_entry_p = FALSE; bool new_entry_p = FALSE;
bool existed_p;
slot = pointer_map_insert (encoder->tree_hash_table, name); slot = encoder->tree_hash_table->insert (name, &existed_p);
if (*slot == NULL) if (!existed_p)
{ {
index = encoder->trees.length (); index = encoder->trees.length ();
*slot = (void *)(uintptr_t) index; *slot = index;
encoder->trees.safe_push (name); encoder->trees.safe_push (name);
new_entry_p = TRUE; new_entry_p = TRUE;
} }
else else
index = (uintptr_t) *slot; index = *slot;
if (obs) if (obs)
streamer_write_uhwi_stream (obs, index); streamer_write_uhwi_stream (obs, index);
...@@ -438,7 +439,7 @@ lto_record_function_out_decl_state (tree fn_decl, ...@@ -438,7 +439,7 @@ lto_record_function_out_decl_state (tree fn_decl,
for (i = 0; i < LTO_N_DECL_STREAMS; i++) for (i = 0; i < LTO_N_DECL_STREAMS; i++)
if (state->streams[i].tree_hash_table) if (state->streams[i].tree_hash_table)
{ {
pointer_map_destroy (state->streams[i].tree_hash_table); delete state->streams[i].tree_hash_table;
state->streams[i].tree_hash_table = NULL; state->streams[i].tree_hash_table = NULL;
} }
state->fn_decl = fn_decl; state->fn_decl = fn_decl;
......
...@@ -479,7 +479,7 @@ struct GTY(()) lto_tree_ref_table ...@@ -479,7 +479,7 @@ struct GTY(()) lto_tree_ref_table
struct lto_tree_ref_encoder struct lto_tree_ref_encoder
{ {
pointer_map_t *tree_hash_table; /* Maps pointers to indices. */ pointer_map<unsigned> *tree_hash_table; /* Maps pointers to indices. */
vec<tree> trees; /* Maps indices to pointers. */ vec<tree> trees; /* Maps indices to pointers. */
}; };
...@@ -997,7 +997,7 @@ lto_tag_check_range (enum LTO_tags actual, enum LTO_tags tag1, ...@@ -997,7 +997,7 @@ lto_tag_check_range (enum LTO_tags actual, enum LTO_tags tag1,
static inline void static inline void
lto_init_tree_ref_encoder (struct lto_tree_ref_encoder *encoder) lto_init_tree_ref_encoder (struct lto_tree_ref_encoder *encoder)
{ {
encoder->tree_hash_table = pointer_map_create (); encoder->tree_hash_table = new pointer_map<unsigned>;
encoder->trees.create (0); encoder->trees.create (0);
} }
...@@ -1009,7 +1009,7 @@ lto_destroy_tree_ref_encoder (struct lto_tree_ref_encoder *encoder) ...@@ -1009,7 +1009,7 @@ lto_destroy_tree_ref_encoder (struct lto_tree_ref_encoder *encoder)
{ {
/* Hash table may be delete already. */ /* Hash table may be delete already. */
if (encoder->tree_hash_table) if (encoder->tree_hash_table)
pointer_map_destroy (encoder->tree_hash_table); delete encoder->tree_hash_table;
encoder->trees.release (); encoder->trees.release ();
} }
......
...@@ -21,21 +21,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -21,21 +21,6 @@ along with GCC; see the file COPYING3. If not see
#include "system.h" #include "system.h"
#include "pointer-set.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 /* 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. a hash code for P in the range [0, MAX). MAX == 2^LOGMAX.
...@@ -67,6 +52,7 @@ hash1 (const void *p, unsigned long max, unsigned long logmax) ...@@ -67,6 +52,7 @@ hash1 (const void *p, unsigned long max, unsigned long logmax)
return ((A * (uintptr_t) p) >> shift) & (max - 1); return ((A * (uintptr_t) p) >> shift) & (max - 1);
} }
/* Allocate an empty pointer set. */ /* Allocate an empty pointer set. */
struct pointer_set_t * struct pointer_set_t *
pointer_set_create (void) pointer_set_create (void)
...@@ -89,20 +75,28 @@ pointer_set_destroy (struct pointer_set_t *pset) ...@@ -89,20 +75,28 @@ pointer_set_destroy (struct pointer_set_t *pset)
XDELETE (pset); XDELETE (pset);
} }
/* Returns nonzero if PSET contains P. P must be nonnull.
Collisions are resolved by linear probing. */ /* Lookup the slot for the pointer P and return true if it exists,
int otherwise return false in which case *IX points to the slot that
pointer_set_contains (const struct pointer_set_t *pset, const void *p) 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); size_t n = hash1 (p, pset->n_slots, pset->log_slots);
while (true) while (true)
{ {
if (pset->slots[n] == p) if (pset->slots[n] == p)
return 1; {
*ix = n;
return true;
}
else if (pset->slots[n] == 0) else if (pset->slots[n] == 0)
return 0; {
*ix = n;
return false;
}
else else
{ {
++n; ++n;
...@@ -112,23 +106,14 @@ pointer_set_contains (const struct pointer_set_t *pset, const void *p) ...@@ -112,23 +106,14 @@ pointer_set_contains (const struct pointer_set_t *pset, const void *p)
} }
} }
/* Subroutine of pointer_set_insert. Return the insertion slot for P into /* Returns nonzero if PSET contains P. P must be nonnull.
an empty element of SLOTS, an array of length N_SLOTS. */
static inline size_t Collisions are resolved by linear probing. */
insert_aux (const void *p, const void **slots, size_t n_slots, size_t log_slots) int
pointer_set_contains (const struct pointer_set_t *pset, const void *p)
{ {
size_t n = hash1 (p, n_slots, log_slots); size_t n;
while (true) return pointer_set_lookup (pset, p, &n);
{
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 /* Inserts P into PSET if it wasn't already there. Returns nonzero
...@@ -142,26 +127,24 @@ pointer_set_insert (struct pointer_set_t *pset, const void *p) ...@@ -142,26 +127,24 @@ pointer_set_insert (struct pointer_set_t *pset, const void *p)
superfluous but can happen at most once. */ superfluous but can happen at most once. */
if (pset->n_elements > pset->n_slots / 4) if (pset->n_elements > pset->n_slots / 4)
{ {
size_t new_log_slots = pset->log_slots + 1; size_t old_n_slots = pset->n_slots;
size_t new_n_slots = pset->n_slots * 2; const void **old_slots = pset->slots;
const void **new_slots = XCNEWVEC (const void *, new_n_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; size_t i;
for (i = 0; i < pset->n_slots; ++i) for (i = 0; i < old_n_slots; ++i)
{ {
const void *value = pset->slots[i]; const void *value = old_slots[i];
n = insert_aux (value, new_slots, new_n_slots, new_log_slots); pointer_set_lookup (pset, value, &n);
new_slots[n] = value; pset->slots[n] = value;
} }
XDELETEVEC (pset->slots); XDELETEVEC (old_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 (pointer_set_lookup (pset, p, &n))
if (pset->slots[n])
return 1; return 1;
pset->slots[n] = p; pset->slots[n] = p;
...@@ -190,11 +173,7 @@ void pointer_set_traverse (const struct pointer_set_t *pset, ...@@ -190,11 +173,7 @@ void pointer_set_traverse (const struct pointer_set_t *pset,
struct pointer_map_t struct pointer_map_t
{ {
size_t log_slots; pointer_set_t pset;
size_t n_slots; /* n_slots = 2^log_slots */
size_t n_elements;
const void **keys;
void **values; void **values;
}; };
...@@ -204,19 +183,19 @@ pointer_map_create (void) ...@@ -204,19 +183,19 @@ pointer_map_create (void)
{ {
struct pointer_map_t *result = XNEW (struct pointer_map_t); struct pointer_map_t *result = XNEW (struct pointer_map_t);
result->n_elements = 0; result->pset.n_elements = 0;
result->log_slots = 8; result->pset.log_slots = 8;
result->n_slots = (size_t) 1 << result->log_slots; result->pset.n_slots = (size_t) 1 << result->pset.log_slots;
result->keys = XCNEWVEC (const void *, result->n_slots); result->pset.slots = XCNEWVEC (const void *, result->pset.n_slots);
result->values = XCNEWVEC (void *, result->n_slots); result->values = XCNEWVEC (void *, result->pset.n_slots);
return result; return result;
} }
/* Reclaims all memory associated with PMAP. */ /* Reclaims all memory associated with PMAP. */
void pointer_map_destroy (struct pointer_map_t *pmap) void pointer_map_destroy (struct pointer_map_t *pmap)
{ {
XDELETEVEC (pmap->keys); XDELETEVEC (pmap->pset.slots);
XDELETEVEC (pmap->values); XDELETEVEC (pmap->values);
XDELETE (pmap); XDELETE (pmap);
} }
...@@ -228,21 +207,11 @@ void pointer_map_destroy (struct pointer_map_t *pmap) ...@@ -228,21 +207,11 @@ void pointer_map_destroy (struct pointer_map_t *pmap)
void ** void **
pointer_map_contains (const struct pointer_map_t *pmap, const void *p) pointer_map_contains (const struct pointer_map_t *pmap, const void *p)
{ {
size_t n = hash1 (p, pmap->n_slots, pmap->log_slots); size_t n;
if (pointer_set_lookup (&pmap->pset, p, &n))
while (true) return &pmap->values[n];
{ else
if (pmap->keys[n] == p) return NULL;
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 /* Inserts P into PMAP if it wasn't already there. Returns a pointer
...@@ -254,36 +223,34 @@ pointer_map_insert (struct pointer_map_t *pmap, const void *p) ...@@ -254,36 +223,34 @@ pointer_map_insert (struct pointer_map_t *pmap, const void *p)
/* For simplicity, expand the map even if P is already there. This can be /* For simplicity, expand the map even if P is already there. This can be
superfluous but can happen at most once. */ superfluous but can happen at most once. */
if (pmap->n_elements > pmap->n_slots / 4) if (pmap->pset.n_elements > pmap->pset.n_slots / 4)
{ {
size_t new_log_slots = pmap->log_slots + 1; size_t old_n_slots = pmap->pset.n_slots;
size_t new_n_slots = pmap->n_slots * 2; const void **old_keys = pmap->pset.slots;
const void **new_keys = XCNEWVEC (const void *, new_n_slots); void **old_values = pmap->values;
void **new_values = XCNEWVEC (void *, new_n_slots); 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; size_t i;
for (i = 0; i < pmap->n_slots; ++i) for (i = 0; i < old_n_slots; ++i)
if (pmap->keys[i]) if (old_keys[i])
{ {
const void *key = pmap->keys[i]; const void *key = old_keys[i];
n = insert_aux (key, new_keys, new_n_slots, new_log_slots); pointer_set_lookup (&pmap->pset, key, &n);
new_keys[n] = key; pmap->pset.slots[n] = key;
new_values[n] = pmap->values[i]; pmap->values[n] = old_values[i];
} }
XDELETEVEC (pmap->keys); XDELETEVEC (old_keys);
XDELETEVEC (pmap->values); XDELETEVEC (old_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 (!pointer_set_lookup (&pmap->pset, p, &n))
if (!pmap->keys[n])
{ {
++pmap->n_elements; ++pmap->pset.n_elements;
pmap->keys[n] = p; pmap->pset.slots[n] = p;
} }
return &pmap->values[n]; return &pmap->values[n];
...@@ -297,7 +264,8 @@ void pointer_map_traverse (const struct pointer_map_t *pmap, ...@@ -297,7 +264,8 @@ void pointer_map_traverse (const struct pointer_map_t *pmap,
bool (*fn) (const void *, void **, void *), void *data) bool (*fn) (const void *, void **, void *), void *data)
{ {
size_t i; size_t i;
for (i = 0; i < pmap->n_slots; ++i) for (i = 0; i < pmap->pset.n_slots; ++i)
if (pmap->keys[i] && !fn (pmap->keys[i], &pmap->values[i], data)) if (pmap->pset.slots[i]
&& !fn (pmap->pset.slots[i], &pmap->values[i], data))
break; break;
} }
...@@ -20,23 +20,151 @@ along with GCC; see the file COPYING3. If not see ...@@ -20,23 +20,151 @@ along with GCC; see the file COPYING3. If not see
#ifndef POINTER_SET_H #ifndef POINTER_SET_H
#define POINTER_SET_H #define POINTER_SET_H
struct pointer_set_t;
/* 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); struct pointer_set_t *pointer_set_create (void);
void pointer_set_destroy (struct pointer_set_t *pset); 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_contains (const struct pointer_set_t *pset, const void *p);
int pointer_set_insert (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 *, void pointer_set_traverse (const struct pointer_set_t *,
bool (*) (const void *, void *), bool (*) (const void *, 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; struct pointer_map_t;
struct pointer_map_t *pointer_map_create (void); pointer_map_t *pointer_map_create (void);
void pointer_map_destroy (struct pointer_map_t *pmap); void pointer_map_destroy (pointer_map_t *pmap);
void **pointer_map_contains (const struct pointer_map_t *pmap, const void *p); void **pointer_map_contains (const pointer_map_t *pmap, const void *p);
void **pointer_map_insert (struct pointer_map_t *pmap, const void *p); void **pointer_map_insert (pointer_map_t *pmap, const void *p);
void pointer_map_traverse (const struct pointer_map_t *, void pointer_map_traverse (const pointer_map_t *,
bool (*) (const void *, void **, void *), void *); bool (*) (const void *, void **, void *), void *);
#endif /* POINTER_SET_H */ #endif /* POINTER_SET_H */
...@@ -128,30 +128,27 @@ streamer_tree_cache_insert_1 (struct streamer_tree_cache_d *cache, ...@@ -128,30 +128,27 @@ streamer_tree_cache_insert_1 (struct streamer_tree_cache_d *cache,
tree t, hashval_t hash, unsigned *ix_p, tree t, hashval_t hash, unsigned *ix_p,
bool insert_at_next_slot_p) bool insert_at_next_slot_p)
{ {
void **slot; unsigned *slot;
unsigned ix; unsigned ix;
bool existed_p; bool existed_p;
gcc_assert (t); gcc_assert (t);
slot = pointer_map_insert (cache->node_map, t); slot = cache->node_map->insert (t, &existed_p);
if (!*slot) if (!existed_p)
{ {
/* Determine the next slot to use in the cache. */ /* Determine the next slot to use in the cache. */
if (insert_at_next_slot_p) if (insert_at_next_slot_p)
ix = cache->nodes.length (); ix = cache->nodes.length ();
else else
ix = *ix_p; ix = *ix_p;
*slot = (void *)(size_t) (ix + 1); *slot = ix;
streamer_tree_cache_add_to_node_array (cache, ix, t, hash); 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 else
{ {
ix = (size_t) *slot - 1; ix = *slot;
if (!insert_at_next_slot_p && ix != *ix_p) if (!insert_at_next_slot_p && ix != *ix_p)
{ {
...@@ -160,11 +157,8 @@ streamer_tree_cache_insert_1 (struct streamer_tree_cache_d *cache, ...@@ -160,11 +157,8 @@ streamer_tree_cache_insert_1 (struct streamer_tree_cache_d *cache,
the requested location slot. */ the requested location slot. */
ix = *ix_p; ix = *ix_p;
streamer_tree_cache_add_to_node_array (cache, ix, t, hash); streamer_tree_cache_add_to_node_array (cache, ix, t, hash);
*slot = (void *)(size_t) (ix + 1); *slot = ix;
} }
/* Indicate that T was already in the cache. */
existed_p = true;
} }
if (ix_p) if (ix_p)
...@@ -225,13 +219,13 @@ bool ...@@ -225,13 +219,13 @@ bool
streamer_tree_cache_lookup (struct streamer_tree_cache_d *cache, tree t, streamer_tree_cache_lookup (struct streamer_tree_cache_d *cache, tree t,
unsigned *ix_p) unsigned *ix_p)
{ {
void **slot; unsigned *slot;
bool retval; bool retval;
unsigned ix; unsigned ix;
gcc_assert (t); gcc_assert (t);
slot = pointer_map_contains (cache->node_map, t); slot = cache->node_map->contains (t);
if (slot == NULL) if (slot == NULL)
{ {
retval = false; retval = false;
...@@ -240,7 +234,7 @@ streamer_tree_cache_lookup (struct streamer_tree_cache_d *cache, tree t, ...@@ -240,7 +234,7 @@ streamer_tree_cache_lookup (struct streamer_tree_cache_d *cache, tree t,
else else
{ {
retval = true; retval = true;
ix = (size_t) *slot - 1; ix = *slot;
} }
if (ix_p) if (ix_p)
...@@ -332,7 +326,7 @@ streamer_tree_cache_create (bool with_hashes, bool with_map) ...@@ -332,7 +326,7 @@ streamer_tree_cache_create (bool with_hashes, bool with_map)
cache = XCNEW (struct streamer_tree_cache_d); cache = XCNEW (struct streamer_tree_cache_d);
if (with_map) if (with_map)
cache->node_map = pointer_map_create (); cache->node_map = new pointer_map<unsigned>;
cache->nodes.create (165); cache->nodes.create (165);
if (with_hashes) if (with_hashes)
cache->hashes.create (165); cache->hashes.create (165);
...@@ -355,7 +349,7 @@ streamer_tree_cache_delete (struct streamer_tree_cache_d *c) ...@@ -355,7 +349,7 @@ streamer_tree_cache_delete (struct streamer_tree_cache_d *c)
return; return;
if (c->node_map) if (c->node_map)
pointer_map_destroy (c->node_map); delete c->node_map;
c->nodes.release (); c->nodes.release ();
c->hashes.release (); c->hashes.release ();
free (c); free (c);
......
...@@ -47,7 +47,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -47,7 +47,7 @@ along with GCC; see the file COPYING3. If not see
struct streamer_tree_cache_d struct streamer_tree_cache_d
{ {
/* The mapping between tree nodes and slots into the nodes array. */ /* The mapping between tree nodes and slots into the nodes array. */
struct pointer_map_t *node_map; pointer_map<unsigned> *node_map;
/* The nodes pickled so far. */ /* The nodes pickled so far. */
vec<tree> nodes; vec<tree> nodes;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment