This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Ensure all frontends have the same number of common nodes
- From: Richard Guenther <rguenther at suse dot de>
- To: Michael Matz <matz at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 20 May 2011 16:12:21 +0200 (CEST)
- Subject: Re: Ensure all frontends have the same number of common nodes
- References: <Pine.LNX.4.64.1105201445590.19219@wotan.suse.de>
On Fri, 20 May 2011, Michael Matz wrote:
> Hi,
>
> for various changes we can run into the situation that frontends fill the
> cache with a different number of common nodes than the LTO frontend,
> leading to confusion of which numbers mean which tree. This can happen
> when some global trees are NULL, or when some global trees are
> pointer-equal to others in one frontend but not the other. We can't
> really avoid filling the cache with doubled pointers if need be. So, do
> away with the pointer map and just always append to the cache.
>
> Based on a patch from Richi. Regstrapping on x86_64-linux in progress.
> Okay for trunk?
Ok.
Thanks,
Richard.
>
> Ciao,
> Michael.
>
> * lto-streamer.c (lto_record_common_node): Don't track seen nodes,
> use lto_streamer_cache_append directly instead of returning a VEC.
> (preload_common_node): Remove.
> (lto_get_common_nodes): Rename to lto_preload_common_nodes, don't
> track seen nodes.
> (lto_streamer_cache_create): Call lto_preload_common_nodes.
>
> Index: lto-streamer.c
> ===================================================================
> --- lto-streamer.c (revision 173940)
> +++ lto-streamer.c (working copy)
> @@ -475,17 +475,21 @@ lto_streamer_cache_get (struct lto_strea
> }
>
>
> -/* Record NODE in COMMON_NODES if it is not NULL and is not already in
> - SEEN_NODES. */
> +/* Record NODE in CACHE. */
>
> static void
> -lto_record_common_node (tree *nodep, VEC(tree, heap) **common_nodes,
> - struct pointer_set_t *seen_nodes)
> +lto_record_common_node (struct lto_streamer_cache_d *cache, tree *nodep)
> {
> tree node = *nodep;
>
> - if (node == NULL_TREE)
> - return;
> + /* We have to make sure to fill exactly the same number of
> + elements for all frontends. That can include NULL trees.
> + As our hash table can't deal with zero entries we'll simply stream
> + a random other tree. A NULL tree never will be looked up so it
> + doesn't matter which tree we replace it with, just to be sure
> + use error_mark_node. */
> + if (!node)
> + node = error_mark_node;
>
> if (TYPE_P (node))
> {
> @@ -500,28 +504,32 @@ lto_record_common_node (tree *nodep, VEC
> *nodep = node;
> }
>
> - /* Return if node is already seen. */
> - if (pointer_set_insert (seen_nodes, node))
> - return;
> -
> - VEC_safe_push (tree, heap, *common_nodes, node);
> + lto_streamer_cache_append (cache, node);
>
> if (POINTER_TYPE_P (node)
> || TREE_CODE (node) == COMPLEX_TYPE
> || TREE_CODE (node) == ARRAY_TYPE)
> - lto_record_common_node (&TREE_TYPE (node), common_nodes, seen_nodes);
> + lto_record_common_node (cache, &TREE_TYPE (node));
> + else if (TREE_CODE (node) == RECORD_TYPE)
> + {
> + /* The FIELD_DECLs of structures should be shared, so that every
> + COMPONENT_REF uses the same tree node when referencing a field.
> + Pointer equality between FIELD_DECLs is used by the alias
> + machinery to compute overlapping memory references (See
> + nonoverlapping_component_refs_p). */
> + tree f;
> + for (f = TYPE_FIELDS (node); f; f = TREE_CHAIN (f))
> + lto_record_common_node (cache, &f);
> + }
> }
>
> -
> -/* Generate a vector of common nodes and make sure they are merged
> +/* Preload common nodes into CACHE and make sure they are merged
> properly according to the gimple type table. */
>
> -static VEC(tree,heap) *
> -lto_get_common_nodes (void)
> +static void
> +lto_preload_common_nodes (struct lto_streamer_cache_d *cache)
> {
> unsigned i;
> - VEC(tree,heap) *common_nodes = NULL;
> - struct pointer_set_t *seen_nodes;
>
> /* The MAIN_IDENTIFIER_NODE is normally set up by the front-end, but the
> LTO back-end must agree. Currently, the only languages that set this
> @@ -545,59 +553,24 @@ lto_get_common_nodes (void)
> gcc_assert (fileptr_type_node == ptr_type_node);
> gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node);
>
> - seen_nodes = pointer_set_create ();
> -
> /* Skip itk_char. char_type_node is shared with the appropriately
> signed variant. */
> for (i = itk_signed_char; i < itk_none; i++)
> - lto_record_common_node (&integer_types[i], &common_nodes, seen_nodes);
> + lto_record_common_node (cache, &integer_types[i]);
>
> for (i = 0; i < TYPE_KIND_LAST; i++)
> - lto_record_common_node (&sizetype_tab[i], &common_nodes, seen_nodes);
> + lto_record_common_node (cache, &sizetype_tab[i]);
>
> for (i = 0; i < TI_MAX; i++)
> - lto_record_common_node (&global_trees[i], &common_nodes, seen_nodes);
> -
> - pointer_set_destroy (seen_nodes);
> -
> - return common_nodes;
> -}
> -
> -
> -/* Assign an index to tree node T and enter it in the streamer cache
> - CACHE. */
> -
> -static void
> -preload_common_node (struct lto_streamer_cache_d *cache, tree t)
> -{
> - gcc_assert (t);
> -
> - lto_streamer_cache_insert (cache, t, NULL);
> -
> - /* The FIELD_DECLs of structures should be shared, so that every
> - COMPONENT_REF uses the same tree node when referencing a field.
> - Pointer equality between FIELD_DECLs is used by the alias
> - machinery to compute overlapping memory references (See
> - nonoverlapping_component_refs_p). */
> - if (TREE_CODE (t) == RECORD_TYPE)
> - {
> - tree f;
> -
> - for (f = TYPE_FIELDS (t); f; f = TREE_CHAIN (f))
> - preload_common_node (cache, f);
> - }
> + lto_record_common_node (cache, &global_trees[i]);
> }
>
> -
> /* Create a cache of pickled nodes. */
>
> struct lto_streamer_cache_d *
> lto_streamer_cache_create (void)
> {
> struct lto_streamer_cache_d *cache;
> - VEC(tree, heap) *common_nodes;
> - unsigned i;
> - tree node;
>
> cache = XCNEW (struct lto_streamer_cache_d);
>
> @@ -606,12 +579,7 @@ lto_streamer_cache_create (void)
> /* Load all the well-known tree nodes that are always created by
> the compiler on startup. This prevents writing them out
> unnecessarily. */
> - common_nodes = lto_get_common_nodes ();
> -
> - FOR_EACH_VEC_ELT (tree, common_nodes, i, node)
> - preload_common_node (cache, node);
> -
> - VEC_free(tree, heap, common_nodes);
> + lto_preload_common_nodes (cache);
>
> return cache;
> }
>
>
--
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer