This patch, now that Micha made us less dependent on preloading exactly the same from each FE, gets rid of two hacks regarding to the frontend (and option) dependent char_type_node and boolean_type_node. It does so by first decoupling canonical type registering from cache-preloading and restrict it to lto1, and second by exempting nodes from the preloading that are known to cause problems because they differ semantically between frontends.
Queued for testing (depends on one prerequesite I think which is in testing currently). Diego, this was the patch I had in mind - does this look reasonable to you? In general I'm working towards identifying what global trees are initialized solely dependent on target info and which ones are really frontend dependent. Thanks, Richard. 2011-05-31 Richard Guenther <rguent...@suse.de> * tree.c (free_lang_data): Do not reset boolean_type_node nor char_type_node. * lto-streamer.c (lto_record_common_node): Take node pointer, do not register types. (lto_preload_common_nodes): Explicitly skip preloading nodes that differ between frontends. lto/ * lto-lang.c (lto_register_canonical_types): New function. (lto_init): Register common nodes with the canonical type machinery. Do not play tricks with char_type_node. Index: gcc/tree.c =================================================================== *** gcc/tree.c.orig 2011-05-31 15:04:08.000000000 +0200 --- gcc/tree.c 2011-05-31 15:04:24.000000000 +0200 *************** free_lang_data (void) *** 5184,5208 **** /* Create gimple variants for common types. */ ptrdiff_type_node = integer_type_node; fileptr_type_node = ptr_type_node; - if (TREE_CODE (boolean_type_node) != BOOLEAN_TYPE - || (TYPE_MODE (boolean_type_node) - != mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0)) - || TYPE_PRECISION (boolean_type_node) != 1 - || !TYPE_UNSIGNED (boolean_type_node)) - { - boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE); - TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE); - TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1); - TYPE_PRECISION (boolean_type_node) = 1; - boolean_false_node = TYPE_MIN_VALUE (boolean_type_node); - boolean_true_node = TYPE_MAX_VALUE (boolean_type_node); - } - - /* Unify char_type_node with its properly signed variant. */ - if (TYPE_UNSIGNED (char_type_node)) - unsigned_char_type_node = char_type_node; - else - signed_char_type_node = char_type_node; /* Reset some langhooks. Do not reset types_compatible_p, it may still be used indirectly via the get_alias_set langhook. */ --- 5184,5189 ---- Index: gcc/lto-streamer.c =================================================================== *** gcc/lto-streamer.c.orig 2011-05-31 15:04:08.000000000 +0200 --- gcc/lto-streamer.c 2011-05-31 15:04:24.000000000 +0200 *************** lto_streamer_cache_get (struct lto_strea *** 478,487 **** /* Record NODE in CACHE. */ static void ! lto_record_common_node (struct lto_streamer_cache_d *cache, tree *nodep) { - tree node = *nodep; - /* 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 --- 478,485 ---- /* Record NODE in CACHE. */ static void ! lto_record_common_node (struct lto_streamer_cache_d *cache, tree node) { /* 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 *************** lto_record_common_node (struct lto_strea *** 491,515 **** if (!node) node = error_mark_node; - if (TYPE_P (node)) - { - /* Type merging will get confused by the canonical types as they - are set by the middle-end. */ - if (in_lto_p) - TYPE_CANONICAL (node) = NULL_TREE; - node = gimple_register_type (node); - TYPE_CANONICAL (node) = gimple_register_canonical_type (node); - if (in_lto_p) - TYPE_CANONICAL (*nodep) = TYPE_CANONICAL (node); - *nodep = 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 (cache, &TREE_TYPE (node)); else if (TREE_CODE (node) == RECORD_TYPE) { /* The FIELD_DECLs of structures should be shared, so that every --- 489,500 ---- if (!node) node = error_mark_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 (cache, TREE_TYPE (node)); else if (TREE_CODE (node) == RECORD_TYPE) { /* The FIELD_DECLs of structures should be shared, so that every *************** lto_record_common_node (struct lto_strea *** 519,525 **** nonoverlapping_component_refs_p). */ tree f; for (f = TYPE_FIELDS (node); f; f = TREE_CHAIN (f)) ! lto_record_common_node (cache, &f); } } --- 504,510 ---- nonoverlapping_component_refs_p). */ tree f; for (f = TYPE_FIELDS (node); f; f = TREE_CHAIN (f)) ! lto_record_common_node (cache, f); } } *************** lto_preload_common_nodes (struct lto_str *** 553,568 **** gcc_assert (fileptr_type_node == ptr_type_node); gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node); ! /* 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 (cache, &integer_types[i]); for (i = 0; i < TYPE_KIND_LAST; i++) ! lto_record_common_node (cache, &sizetype_tab[i]); for (i = 0; i < TI_MAX; i++) ! lto_record_common_node (cache, &global_trees[i]); } /* Create a cache of pickled nodes. */ --- 538,557 ---- gcc_assert (fileptr_type_node == ptr_type_node); gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node); ! for (i = 0; i < itk_none; i++) ! /* Skip itk_char. char_type_node is dependent on -f[un]signed-char. */ ! if (i != itk_char) ! lto_record_common_node (cache, integer_types[i]); for (i = 0; i < TYPE_KIND_LAST; i++) ! lto_record_common_node (cache, sizetype_tab[i]); for (i = 0; i < TI_MAX; i++) ! /* Skip boolean type and constants, they are frontend dependent. */ ! if (i != TI_BOOLEAN_TYPE ! && i != TI_BOOLEAN_FALSE ! && i != TI_BOOLEAN_TRUE) ! lto_record_common_node (cache, global_trees[i]); } /* Create a cache of pickled nodes. */ Index: gcc/lto/lto-lang.c =================================================================== *** gcc/lto/lto-lang.c.orig 2011-05-31 15:04:08.000000000 +0200 --- gcc/lto/lto-lang.c 2011-05-31 15:06:14.000000000 +0200 *************** lto_build_c_type_nodes (void) *** 1052,1063 **** --- 1052,1082 ---- pid_type_node = integer_type_node; } + /* Re-compute TYPE_CANONICAL for NODE and related types. */ + + static void + lto_register_canonical_types (tree node) + { + if (!node + || !TYPE_P (node)) + return; + + TYPE_CANONICAL (node) = NULL_TREE; + TYPE_CANONICAL (node) = gimple_register_canonical_type (node); + + if (POINTER_TYPE_P (node) + || TREE_CODE (node) == COMPLEX_TYPE + || TREE_CODE (node) == ARRAY_TYPE) + lto_register_canonical_types (TREE_TYPE (node)); + } /* Perform LTO-specific initialization. */ static bool lto_init (void) { + unsigned i; + /* We need to generate LTO if running in WPA mode. */ flag_generate_lto = flag_wpa; *************** lto_init (void) *** 1068,1100 **** /* Create the basic integer types. */ build_common_tree_nodes (flag_signed_char); - /* Share char_type_node with whatever would be the default for the target. - char_type_node will be used for internal types such as - va_list_type_node but will not be present in the lto stream. */ - /* ??? This breaks the more common case of consistent but non-standard - setting of flag_signed_char, so share according to flag_signed_char. - See PR42528. */ - char_type_node - = flag_signed_char ? signed_char_type_node : unsigned_char_type_node; - /* Tell the middle end what type to use for the size of objects. */ if (strcmp (SIZE_TYPE, "unsigned int") == 0) ! { ! set_sizetype (unsigned_type_node); ! size_type_node = unsigned_type_node; ! } else if (strcmp (SIZE_TYPE, "long unsigned int") == 0) ! { ! set_sizetype (long_unsigned_type_node); ! size_type_node = long_unsigned_type_node; ! } else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0) ! { ! set_sizetype (long_long_unsigned_type_node); ! size_type_node = long_long_unsigned_type_node; ! } else gcc_unreachable (); /* The global tree for the main identifier is filled in by language-specific front-end initialization that is not run in the --- 1087,1102 ---- /* Create the basic integer types. */ build_common_tree_nodes (flag_signed_char); /* Tell the middle end what type to use for the size of objects. */ if (strcmp (SIZE_TYPE, "unsigned int") == 0) ! size_type_node = unsigned_type_node; else if (strcmp (SIZE_TYPE, "long unsigned int") == 0) ! size_type_node = long_unsigned_type_node; else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0) ! size_type_node = long_long_unsigned_type_node; else gcc_unreachable (); + set_sizetype (size_type_node); /* The global tree for the main identifier is filled in by language-specific front-end initialization that is not run in the *************** lto_init (void) *** 1158,1163 **** --- 1160,1176 ---- NAME_TYPE (boolean_type_node, "bool"); #undef NAME_TYPE + /* Register the common node types with the canonical type machinery so + we properly share alias-sets across languages and TUs. Do not + expose the common nodes as type merge target - those that should be + are already exposed so by pre-loading the LTO streamer caches. */ + for (i = 0; i < itk_none; ++i) + lto_register_canonical_types (integer_types[i]); + /* The sizetypes are not used to access data so we do not need to + do anything about them. */ + for (i = 0; i < TI_MAX; ++i) + lto_register_canonical_types (global_trees[i]); + /* Initialize LTO-specific data structures. */ lto_global_var_decls = VEC_alloc (tree, gc, 256); in_lto_p = true;