> Hi, > > On Mon, 2 May 2011, Richard Guenther wrote: > > > >> --- 348,367 ---- > > >> 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) > > > > > > ix might legitimately be zero. Hence this transformation is not > > > equivalent. You might want to enter ix+1 into the cache with the > > > appropriate adjustment at read-out. Same for the other places. > > > > Or not use index zero. > > I never like these sentinals. > > > Maybe better than also have to deal with ix + 1 wrapping ... > > We don't handle ix wrapping, why should we now suddenly care about ix+1 > wrapping?
Duh, I actually intended to implement the ix+1 wrapping, but got dragged into discussions about thunks ;) I am testing the following patch. Seems sane? Honza Index: lto-streamer.c =================================================================== *** lto-streamer.c (revision 173251) --- lto-streamer.c (working copy) *************** lto_streamer_cache_insert_1 (struct lto_ *** 348,373 **** bool insert_at_next_slot_p) { void **slot; - struct tree_int_map d_entry, *entry; unsigned ix; bool existed_p; gcc_assert (t); ! d_entry.base.from = t; ! slot = htab_find_slot (cache->node_map, &d_entry, INSERT); ! if (*slot == NULL) { /* Determine the next slot to use in the cache. */ if (insert_at_next_slot_p) ix = VEC_length (tree, cache->nodes); else ix = *ix_p; ! ! entry = (struct tree_int_map *)pool_alloc (cache->node_map_entries); ! entry->base.from = t; ! entry->to = ix; ! *slot = entry; lto_streamer_cache_add_to_node_array (cache, ix, t); --- 348,367 ---- 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 = VEC_length (tree, cache->nodes); else ix = *ix_p; ! *slot = (void *)(size_t) (ix + 1); lto_streamer_cache_add_to_node_array (cache, ix, t); *************** lto_streamer_cache_insert_1 (struct lto_ *** 376,383 **** } else { ! entry = (struct tree_int_map *) *slot; ! ix = entry->to; if (!insert_at_next_slot_p && ix != *ix_p) { --- 370,376 ---- } else { ! ix = (size_t) *slot - 1; if (!insert_at_next_slot_p && ix != *ix_p) { *************** lto_streamer_cache_lookup (struct lto_st *** 442,455 **** unsigned *ix_p) { void **slot; - struct tree_int_map d_slot; bool retval; unsigned ix; gcc_assert (t); ! d_slot.base.from = t; ! slot = htab_find_slot (cache->node_map, &d_slot, NO_INSERT); if (slot == NULL) { retval = false; --- 435,446 ---- 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; *************** lto_streamer_cache_lookup (struct lto_st *** 458,464 **** else { retval = true; ! ix = ((struct tree_int_map *) *slot)->to; } if (ix_p) --- 449,455 ---- else { retval = true; ! ix = (size_t) *slot - 1; } if (ix_p) *************** lto_streamer_cache_create (void) *** 608,618 **** cache = XCNEW (struct lto_streamer_cache_d); ! cache->node_map = htab_create (101, tree_int_map_hash, tree_int_map_eq, NULL); ! ! cache->node_map_entries = create_alloc_pool ("node map", ! sizeof (struct tree_int_map), ! 100); /* Load all the well-known tree nodes that are always created by the compiler on startup. This prevents writing them out --- 599,605 ---- cache = XCNEW (struct lto_streamer_cache_d); ! cache->node_map = pointer_map_create (); /* Load all the well-known tree nodes that are always created by the compiler on startup. This prevents writing them out *************** lto_streamer_cache_delete (struct lto_st *** 636,643 **** if (c == NULL) return; ! htab_delete (c->node_map); ! free_alloc_pool (c->node_map_entries); VEC_free (tree, heap, c->nodes); free (c); } --- 623,629 ---- if (c == NULL) return; ! pointer_map_destroy (c->node_map); VEC_free (tree, heap, c->nodes); free (c); } Index: lto-streamer.h =================================================================== *** lto-streamer.h (revision 173251) --- lto-streamer.h (working copy) *************** typedef void (lto_free_section_data_f) ( *** 346,355 **** struct lto_streamer_cache_d { /* The mapping between tree nodes and slots into the nodes array. */ ! htab_t node_map; ! ! /* Node map to store entries into. */ ! alloc_pool node_map_entries; /* The nodes pickled so far. */ VEC(tree,heap) *nodes; --- 346,352 ---- struct lto_streamer_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,heap) *nodes;