On Thu, Apr 21, 2011 at 3:46 PM, Michael Matz <m...@suse.de> wrote: > Hi, > > On Wed, 20 Apr 2011, Michael Matz wrote: > >> > It would have been nice to have the top-level tree merging as a >> > separate patch, as I am not convinced it is correct, but see below ... >> >> I'll split it out. > > Like so (also including the other remarks). > > Regstrapping on x86_64-linux in progress.
Ok if it passed. Thanks, Richard. > > Ciao, > Michael. > > * lto-streamer.c (lto_streamer_cache_insert_1): Accept to override > other trees that just builtins. > (lto_record_common_node): Don't leave NULL TYPE_CANONICAL. > > lto/ > * lto.c (toplevel): Include tree-flow.h. > (lto_read_in_decl_state): Don't merge types here. > (tree_with_vars): New static hash table. > (remember_with_vars): New static functions. > (LTO_FIXUP_TYPE): New macro. > (lto_ft_common, lto_ft_decl_minimal, lto_ft_decl_common, > lto_ft_decl_with_vis, lto_ft_decl_non_common, lto_ft_function, > lto_ft_field_decl, lto_ft_type, lto_ft_binfo, lto_ft_constructor, > lto_ft_expr, lto_fixup_types, uniquify_nodes): New static functions. > (lto_read_decls): Uniquify while reading in trees. > (lto_fixup_data_t, LTO_FIXUP_SUBTREE, > LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE, no_fixup_p, lto_fixup_common, > lto_fixup_decl_minimal, lto_fixup_decl_common, lto_fixup_decl_with_vis, > lto_fixup_decl_non_common, lto_fixup_function, lto_fixup_field_decl, > lto_fixup_type, lto_fixup_binfo, lto_fixup_constructor, > lto_fixup_tree): Remove. > (lto_fixup_state): Remove data argument. Use > lto_symtab_prevailing_decl. > (LTO_SET_PREVAIL, LTO_NO_PREVAIL): New macros. > (lto_fixup_prevailing_decls): New function. > (lto_fixup_state_aux): Argument aux is unused. > (lto_fixup_decls): Don't allocate pointer sets, don't use > lto_fixup_tree, use lto_fixup_prevailing_decls. > (read_cgraph_and_symbols): Allocate and remove tree_with_vars. > * Make-lang.in (lto/lto.o): Depend on $(TREE_FLOW_H). > > Index: lto-streamer.c > =================================================================== > *** lto-streamer.c (revision 172769) > --- lto-streamer.c (working copy) > *************** lto_streamer_cache_insert_1 (struct lto_ > *** 383,401 **** > { > /* If the caller wants to insert T at a specific slot > location, and ENTRY->TO does not match *IX_P, add T to > ! the requested location slot. This situation arises when > ! streaming builtin functions. > ! > ! For instance, on the writer side we could have two > ! FUNCTION_DECLS T1 and T2 that are represented by the same > ! builtin function. The reader will only instantiate the > ! canonical builtin, but since T1 and T2 had been > ! originally stored in different cache slots (S1 and S2), > ! the reader must be able to find the canonical builtin > ! function at slots S1 and S2. */ > ! gcc_assert (lto_stream_as_builtin_p (t)); > ix = *ix_p; > - > lto_streamer_cache_add_to_node_array (cache, ix, t); > } > > --- 383,390 ---- > { > /* If the caller wants to insert T at a specific slot > location, and ENTRY->TO does not match *IX_P, add T to > ! the requested location slot. */ > ix = *ix_p; > lto_streamer_cache_add_to_node_array (cache, ix, t); > } > > *************** lto_record_common_node (tree *nodep, VEC > *** 513,518 **** > --- 502,509 ---- > 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; > } > > Index: lto/lto.c > =================================================================== > *** lto/lto.c (revision 172769) > --- lto/lto.c (working copy) > *************** along with GCC; see the file COPYING3. > *** 24,29 **** > --- 24,30 ---- > #include "opts.h" > #include "toplev.h" > #include "tree.h" > + #include "tree-flow.h" > #include "diagnostic-core.h" > #include "tm.h" > #include "cgraph.h" > *************** lto_read_in_decl_state (struct data_in * > *** 215,228 **** > tree *decls = ggc_alloc_vec_tree (size); > > for (j = 0; j < size; j++) > ! { > ! decls[j] = lto_streamer_cache_get (data_in->reader_cache, data[j]); > ! > ! /* Register every type in the global type table. If the > ! type existed already, use the existing type. */ > ! if (TYPE_P (decls[j])) > ! decls[j] = gimple_register_type (decls[j]); > ! } > > state->streams[i].size = size; > state->streams[i].trees = decls; > --- 216,222 ---- > tree *decls = ggc_alloc_vec_tree (size); > > for (j = 0; j < size; j++) > ! decls[j] = lto_streamer_cache_get (data_in->reader_cache, data[j]); > > state->streams[i].size = size; > state->streams[i].trees = decls; > *************** lto_read_in_decl_state (struct data_in * > *** 232,237 **** > --- 226,666 ---- > return data; > } > > + /* A hashtable of trees that potentially refer to variables or functions > + that must be replaced with their prevailing variant. */ > + static GTY((if_marked ("ggc_marked_p"), param_is (union tree_node))) htab_t > + tree_with_vars; > + > + /* Remember that T is a tree that (potentially) refers to a variable > + or function decl that may be replaced with its prevailing variant. */ > + static void > + remember_with_vars (tree t) > + { > + *(tree *) htab_find_slot (tree_with_vars, t, INSERT) = t; > + } > + > + #define LTO_FIXUP_TREE(tt) \ > + do \ > + { \ > + if (tt) \ > + { \ > + if (TYPE_P (tt)) \ > + (tt) = gimple_register_type (tt); \ > + if (VAR_OR_FUNCTION_DECL_P (tt) && TREE_PUBLIC (tt)) \ > + remember_with_vars (t); \ > + } \ > + } while (0) > + > + static void lto_fixup_types (tree); > + > + /* Fix up fields of a tree_common T. */ > + > + static void > + lto_ft_common (tree t) > + { > + /* The following re-creates the TYPE_REFERENCE_TO and TYPE_POINTER_TO > + lists. We do not stream TYPE_REFERENCE_TO, TYPE_POINTER_TO or > + TYPE_NEXT_PTR_TO and TYPE_NEXT_REF_TO. > + First remove us from any pointer list we are on. */ > + if (TREE_CODE (t) == POINTER_TYPE) > + { > + if (TYPE_POINTER_TO (TREE_TYPE (t)) == t) > + TYPE_POINTER_TO (TREE_TYPE (t)) = TYPE_NEXT_PTR_TO (t); > + else > + { > + tree tem = TYPE_POINTER_TO (TREE_TYPE (t)); > + while (tem && TYPE_NEXT_PTR_TO (tem) != t) > + tem = TYPE_NEXT_PTR_TO (tem); > + if (tem) > + TYPE_NEXT_PTR_TO (tem) = TYPE_NEXT_PTR_TO (t); > + } > + TYPE_NEXT_PTR_TO (t) = NULL_TREE; > + } > + else if (TREE_CODE (t) == REFERENCE_TYPE) > + { > + if (TYPE_REFERENCE_TO (TREE_TYPE (t)) == t) > + TYPE_REFERENCE_TO (TREE_TYPE (t)) = TYPE_NEXT_REF_TO (t); > + else > + { > + tree tem = TYPE_REFERENCE_TO (TREE_TYPE (t)); > + while (tem && TYPE_NEXT_REF_TO (tem) != t) > + tem = TYPE_NEXT_REF_TO (tem); > + if (tem) > + TYPE_NEXT_REF_TO (tem) = TYPE_NEXT_REF_TO (t); > + } > + TYPE_NEXT_REF_TO (t) = NULL_TREE; > + } > + > + /* Fixup our type. */ > + LTO_FIXUP_TREE (TREE_TYPE (t)); > + > + /* Second put us on the list of pointers of the new pointed-to type > + if we are a main variant. This is done in lto_ft_type after > + fixing up our main variant. */ > + LTO_FIXUP_TREE (TREE_CHAIN (t)); > + } > + > + /* Fix up fields of a decl_minimal T. */ > + > + static void > + lto_ft_decl_minimal (tree t) > + { > + lto_ft_common (t); > + LTO_FIXUP_TREE (DECL_NAME (t)); > + LTO_FIXUP_TREE (DECL_CONTEXT (t)); > + } > + > + /* Fix up fields of a decl_common T. */ > + > + static void > + lto_ft_decl_common (tree t) > + { > + lto_ft_decl_minimal (t); > + LTO_FIXUP_TREE (DECL_SIZE (t)); > + LTO_FIXUP_TREE (DECL_SIZE_UNIT (t)); > + LTO_FIXUP_TREE (DECL_INITIAL (t)); > + LTO_FIXUP_TREE (DECL_ATTRIBUTES (t)); > + LTO_FIXUP_TREE (DECL_ABSTRACT_ORIGIN (t)); > + } > + > + /* Fix up fields of a decl_with_vis T. */ > + > + static void > + lto_ft_decl_with_vis (tree t) > + { > + lto_ft_decl_common (t); > + > + /* Accessor macro has side-effects, use field-name here. */ > + LTO_FIXUP_TREE (t->decl_with_vis.assembler_name); > + LTO_FIXUP_TREE (DECL_SECTION_NAME (t)); > + } > + > + /* Fix up fields of a decl_non_common T. */ > + > + static void > + lto_ft_decl_non_common (tree t) > + { > + lto_ft_decl_with_vis (t); > + LTO_FIXUP_TREE (DECL_ARGUMENT_FLD (t)); > + LTO_FIXUP_TREE (DECL_RESULT_FLD (t)); > + LTO_FIXUP_TREE (DECL_VINDEX (t)); > + } > + > + /* Fix up fields of a decl_non_common T. */ > + > + static void > + lto_ft_function (tree t) > + { > + lto_ft_decl_non_common (t); > + LTO_FIXUP_TREE (DECL_FUNCTION_PERSONALITY (t)); > + } > + > + /* Fix up fields of a field_decl T. */ > + > + static void > + lto_ft_field_decl (tree t) > + { > + lto_ft_decl_common (t); > + LTO_FIXUP_TREE (DECL_FIELD_OFFSET (t)); > + LTO_FIXUP_TREE (DECL_BIT_FIELD_TYPE (t)); > + LTO_FIXUP_TREE (DECL_QUALIFIER (t)); > + LTO_FIXUP_TREE (DECL_FIELD_BIT_OFFSET (t)); > + LTO_FIXUP_TREE (DECL_FCONTEXT (t)); > + } > + > + /* Fix up fields of a type T. */ > + > + static void > + lto_ft_type (tree t) > + { > + tree tem, mv; > + > + lto_ft_common (t); > + LTO_FIXUP_TREE (TYPE_CACHED_VALUES (t)); > + LTO_FIXUP_TREE (TYPE_SIZE (t)); > + LTO_FIXUP_TREE (TYPE_SIZE_UNIT (t)); > + LTO_FIXUP_TREE (TYPE_ATTRIBUTES (t)); > + LTO_FIXUP_TREE (TYPE_NAME (t)); > + > + /* Accessors are for derived node types only. */ > + if (!POINTER_TYPE_P (t)) > + LTO_FIXUP_TREE (t->type.minval); > + LTO_FIXUP_TREE (t->type.maxval); > + > + /* Accessor is for derived node types only. */ > + LTO_FIXUP_TREE (t->type.binfo); > + > + LTO_FIXUP_TREE (TYPE_CONTEXT (t)); > + > + /* Compute the canonical type of t and fix that up. From this point > + there are no longer any types with TYPE_STRUCTURAL_EQUALITY_P > + and its type-based alias problems. */ > + if (!TYPE_CANONICAL (t)) > + { > + TYPE_CANONICAL (t) = gimple_register_canonical_type (t); > + LTO_FIXUP_TREE (TYPE_CANONICAL (t)); > + } > + > + /* The following re-creates proper variant lists while fixing up > + the variant leaders. We do not stream TYPE_NEXT_VARIANT so the > + variant list state before fixup is broken. */ > + > + /* Remove us from our main variant list if we are not the variant leader. > */ > + if (TYPE_MAIN_VARIANT (t) != t) > + { > + tem = TYPE_MAIN_VARIANT (t); > + while (tem && TYPE_NEXT_VARIANT (tem) != t) > + tem = TYPE_NEXT_VARIANT (tem); > + if (tem) > + TYPE_NEXT_VARIANT (tem) = TYPE_NEXT_VARIANT (t); > + TYPE_NEXT_VARIANT (t) = NULL_TREE; > + } > + > + /* Query our new main variant. */ > + mv = gimple_register_type (TYPE_MAIN_VARIANT (t)); > + > + /* If we were the variant leader and we get replaced ourselves drop > + all variants from our list. */ > + if (TYPE_MAIN_VARIANT (t) == t > + && mv != t) > + { > + tem = t; > + while (tem) > + { > + tree tem2 = TYPE_NEXT_VARIANT (tem); > + TYPE_NEXT_VARIANT (tem) = NULL_TREE; > + tem = tem2; > + } > + } > + > + /* Finally adjust our main variant and fix it up. */ > + TYPE_MAIN_VARIANT (t) = mv; > + LTO_FIXUP_TREE (TYPE_MAIN_VARIANT (t)); > + > + /* As the second step of reconstructing the pointer chains put us > + on the list of pointers of the new pointed-to type > + if we are a main variant. See lto_ft_common for the first step. */ > + if (TREE_CODE (t) == POINTER_TYPE > + && TYPE_MAIN_VARIANT (t) == t) > + { > + TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (TREE_TYPE (t)); > + TYPE_POINTER_TO (TREE_TYPE (t)) = t; > + } > + else if (TREE_CODE (t) == REFERENCE_TYPE > + && TYPE_MAIN_VARIANT (t) == t) > + { > + TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (TREE_TYPE (t)); > + TYPE_REFERENCE_TO (TREE_TYPE (t)) = t; > + } > + } > + > + /* Fix up fields of a BINFO T. */ > + > + static void > + lto_ft_binfo (tree t) > + { > + unsigned HOST_WIDE_INT i, n; > + tree base, saved_base; > + > + lto_ft_common (t); > + LTO_FIXUP_TREE (BINFO_VTABLE (t)); > + LTO_FIXUP_TREE (BINFO_OFFSET (t)); > + LTO_FIXUP_TREE (BINFO_VIRTUALS (t)); > + LTO_FIXUP_TREE (BINFO_VPTR_FIELD (t)); > + n = VEC_length (tree, BINFO_BASE_ACCESSES (t)); > + for (i = 0; i < n; i++) > + { > + saved_base = base = BINFO_BASE_ACCESS (t, i); > + LTO_FIXUP_TREE (base); > + if (base != saved_base) > + VEC_replace (tree, BINFO_BASE_ACCESSES (t), i, base); > + } > + LTO_FIXUP_TREE (BINFO_INHERITANCE_CHAIN (t)); > + LTO_FIXUP_TREE (BINFO_SUBVTT_INDEX (t)); > + LTO_FIXUP_TREE (BINFO_VPTR_INDEX (t)); > + n = BINFO_N_BASE_BINFOS (t); > + for (i = 0; i < n; i++) > + { > + saved_base = base = BINFO_BASE_BINFO (t, i); > + LTO_FIXUP_TREE (base); > + if (base != saved_base) > + VEC_replace (tree, BINFO_BASE_BINFOS (t), i, base); > + } > + } > + > + /* Fix up fields of a CONSTRUCTOR T. */ > + > + static void > + lto_ft_constructor (tree t) > + { > + unsigned HOST_WIDE_INT idx; > + constructor_elt *ce; > + > + LTO_FIXUP_TREE (TREE_TYPE (t)); > + > + for (idx = 0; > + VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (t), idx, ce); > + idx++) > + { > + LTO_FIXUP_TREE (ce->index); > + LTO_FIXUP_TREE (ce->value); > + } > + } > + > + /* Fix up fields of an expression tree T. */ > + > + static void > + lto_ft_expr (tree t) > + { > + int i; > + lto_ft_common (t); > + for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i) > + LTO_FIXUP_TREE (TREE_OPERAND (t, i)); > + } > + > + /* Given a tree T fixup fields of T by replacing types with their merged > + variant and other entities by an equal entity from an earlier compilation > + unit, or an entity being canonical in a different way. This includes > + for instance integer or string constants. */ > + > + static void > + lto_fixup_types (tree t) > + { > + switch (TREE_CODE (t)) > + { > + case IDENTIFIER_NODE: > + break; > + > + case TREE_LIST: > + LTO_FIXUP_TREE (TREE_VALUE (t)); > + LTO_FIXUP_TREE (TREE_PURPOSE (t)); > + LTO_FIXUP_TREE (TREE_CHAIN (t)); > + break; > + > + case FIELD_DECL: > + lto_ft_field_decl (t); > + break; > + > + case LABEL_DECL: > + case CONST_DECL: > + case PARM_DECL: > + case RESULT_DECL: > + case IMPORTED_DECL: > + lto_ft_decl_common (t); > + break; > + > + case VAR_DECL: > + lto_ft_decl_with_vis (t); > + break; > + > + case TYPE_DECL: > + lto_ft_decl_non_common (t); > + break; > + > + case FUNCTION_DECL: > + lto_ft_function (t); > + break; > + > + case TREE_BINFO: > + lto_ft_binfo (t); > + break; > + > + case PLACEHOLDER_EXPR: > + lto_ft_common (t); > + break; > + > + case BLOCK: > + case TRANSLATION_UNIT_DECL: > + case OPTIMIZATION_NODE: > + case TARGET_OPTION_NODE: > + break; > + > + default: > + if (TYPE_P (t)) > + lto_ft_type (t); > + else if (TREE_CODE (t) == CONSTRUCTOR) > + lto_ft_constructor (t); > + else if (CONSTANT_CLASS_P (t)) > + LTO_FIXUP_TREE (TREE_TYPE (t)); > + else if (EXPR_P (t)) > + { > + lto_ft_expr (t); > + } > + else > + { > + remember_with_vars (t); > + } > + } > + } > + > + /* Given a streamer cache structure DATA_IN (holding a sequence of trees > + for one compilation unit) go over all trees starting at index FROM until > the > + end of the sequence and replace fields of those trees, and the trees > + themself with their canonical variants as per gimple_register_type. */ > + > + static void > + uniquify_nodes (struct data_in *data_in, unsigned from) > + { > + struct lto_streamer_cache_d *cache = data_in->reader_cache; > + unsigned len = VEC_length (tree, cache->nodes); > + unsigned i; > + /* Go backwards because childs streamed for the first time come > + as part of their parents, and hence are created after them. */ > + for (i = len; i-- > from;) > + { > + tree t = VEC_index (tree, cache->nodes, i); > + tree oldt = t; > + if (!t) > + continue; > + > + /* First fixup the fields of T. */ > + lto_fixup_types (t); > + > + /* Now try to find a canonical variant of T itself. */ > + if (TYPE_P (t)) > + { > + t = gimple_register_type (t); > + if (t == oldt > + && TYPE_MAIN_VARIANT (t) != t) > + { > + /* If this is its own type, link it into the variant chain. */ > + TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT > (t)); > + TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (t)) = t; > + } > + } > + if (t != oldt) > + { > + if (RECORD_OR_UNION_TYPE_P (t)) > + { > + tree f1, f2; > + if (TYPE_FIELDS (t) != TYPE_FIELDS (oldt)) > + for (f1 = TYPE_FIELDS (t), f2 = TYPE_FIELDS (oldt); > + f1 && f2; f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2)) > + { > + unsigned ix; > + gcc_assert (f1 != f2 && DECL_NAME (f1) == DECL_NAME (f2)); > + if (!lto_streamer_cache_lookup (cache, f2, &ix)) > + gcc_unreachable (); > + /* If we're going to replace an element which we'd > + still visit in the next iterations, we wouldn't > + handle it, so do it here. We do have to handle it > + even though the field_decl itself will be removed, > + as it could refer to e.g. integer_cst which we > + wouldn't reach via any other way, hence they > + (and their type) would stay uncollected. */ > + if (ix < i) > + lto_fixup_types (f2); > + lto_streamer_cache_insert_at (cache, f1, ix); > + } > + } > + > + /* If we found a tree that is equal to oldt replace it in the > + cache, so that further users (in the various LTO sections) > + make use of it. */ > + lto_streamer_cache_insert_at (cache, t, i); > + } > + } > + } > > /* Read all the symbols from buffer DATA, using descriptors in DECL_DATA. > RESOLUTIONS is the set of symbols picked by the linker (read from the > *************** lto_read_decls (struct lto_file_decl_dat > *** 260,267 **** > /* Read the global declarations and types. */ > while (ib_main.p < ib_main.len) > { > ! tree t = lto_input_tree (&ib_main, data_in); > gcc_assert (t && ib_main.p <= ib_main.len); > } > > /* Read in lto_in_decl_state objects. */ > --- 689,699 ---- > /* Read the global declarations and types. */ > while (ib_main.p < ib_main.len) > { > ! tree t; > ! unsigned from = VEC_length (tree, data_in->reader_cache->nodes); > ! t = lto_input_tree (&ib_main, data_in); > gcc_assert (t && ib_main.p <= ib_main.len); > + uniquify_nodes (data_in, from); > } > > /* Read in lto_in_decl_state objects. */ > *************** lto_wpa_write_files (void) > *** 1514,1520 **** > fprintf (stderr, " %s (%s %i insns)", temp_filename, part->name, > part->insns); > if (cgraph_dump_file) > { > ! fprintf (cgraph_dump_file, "Writting partition %s to file %s, %i > insns\n", > part->name, temp_filename, part->insns); > fprintf (cgraph_dump_file, "cgraph nodes:"); > dump_cgraph_node_set (cgraph_dump_file, set); > --- 1946,1952 ---- > fprintf (stderr, " %s (%s %i insns)", temp_filename, part->name, > part->insns); > if (cgraph_dump_file) > { > ! fprintf (cgraph_dump_file, "Writing partition %s to file %s, %i > insns\n", > part->name, temp_filename, part->insns); > fprintf (cgraph_dump_file, "cgraph nodes:"); > dump_cgraph_node_set (cgraph_dump_file, set); > *************** lto_wpa_write_files (void) > *** 1548,1963 **** > } > > > ! typedef struct { > ! struct pointer_set_t *seen; > ! } lto_fixup_data_t; > ! > ! #define LTO_FIXUP_SUBTREE(t) \ > ! do \ > ! walk_tree (&(t), lto_fixup_tree, data, NULL); \ > ! while (0) > ! > ! #define LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE(t) \ > ! do \ > ! { \ > ! if (t) \ > ! (t) = gimple_register_type (t); \ > ! walk_tree (&(t), lto_fixup_tree, data, NULL); \ > ! } \ > ! while (0) > ! > ! static tree lto_fixup_tree (tree *, int *, void *); > ! > ! /* Return true if T does not need to be fixed up recursively. */ > ! > ! static inline bool > ! no_fixup_p (tree t) > ! { > ! return (t == NULL > ! || CONSTANT_CLASS_P (t) > ! || TREE_CODE (t) == IDENTIFIER_NODE); > ! } > ! > ! /* Fix up fields of a tree_common T. DATA points to fix-up states. */ > ! > ! static void > ! lto_fixup_common (tree t, void *data) > ! { > ! /* The following re-creates the TYPE_REFERENCE_TO and TYPE_POINTER_TO > ! lists. We do not stream TYPE_REFERENCE_TO, TYPE_POINTER_TO or > ! TYPE_NEXT_PTR_TO and TYPE_NEXT_REF_TO. > ! First remove us from any pointer list we are on. */ > ! if (TREE_CODE (t) == POINTER_TYPE) > ! { > ! if (TYPE_POINTER_TO (TREE_TYPE (t)) == t) > ! TYPE_POINTER_TO (TREE_TYPE (t)) = TYPE_NEXT_PTR_TO (t); > ! else > ! { > ! tree tem = TYPE_POINTER_TO (TREE_TYPE (t)); > ! while (tem && TYPE_NEXT_PTR_TO (tem) != t) > ! tem = TYPE_NEXT_PTR_TO (tem); > ! if (tem) > ! TYPE_NEXT_PTR_TO (tem) = TYPE_NEXT_PTR_TO (t); > ! } > ! TYPE_NEXT_PTR_TO (t) = NULL_TREE; > ! } > ! else if (TREE_CODE (t) == REFERENCE_TYPE) > ! { > ! if (TYPE_REFERENCE_TO (TREE_TYPE (t)) == t) > ! TYPE_REFERENCE_TO (TREE_TYPE (t)) = TYPE_NEXT_REF_TO (t); > ! else > ! { > ! tree tem = TYPE_REFERENCE_TO (TREE_TYPE (t)); > ! while (tem && TYPE_NEXT_REF_TO (tem) != t) > ! tem = TYPE_NEXT_REF_TO (tem); > ! if (tem) > ! TYPE_NEXT_REF_TO (tem) = TYPE_NEXT_REF_TO (t); > ! } > ! TYPE_NEXT_REF_TO (t) = NULL_TREE; > ! } > ! > ! /* Fixup our type. */ > ! LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TREE_TYPE (t)); > ! > ! /* Second put us on the list of pointers of the new pointed-to type > ! if we are a main variant. This is done in lto_fixup_type after > ! fixing up our main variant. */ > ! > ! /* This is not very efficient because we cannot do tail-recursion with > ! a long chain of trees. */ > ! if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_COMMON)) > ! LTO_FIXUP_SUBTREE (TREE_CHAIN (t)); > ! } > ! > ! /* Fix up fields of a decl_minimal T. DATA points to fix-up states. */ > ! > ! static void > ! lto_fixup_decl_minimal (tree t, void *data) > ! { > ! lto_fixup_common (t, data); > ! LTO_FIXUP_SUBTREE (DECL_NAME (t)); > ! LTO_FIXUP_SUBTREE (DECL_CONTEXT (t)); > ! } > ! > ! /* Fix up fields of a decl_common T. DATA points to fix-up states. */ > ! > ! static void > ! lto_fixup_decl_common (tree t, void *data) > ! { > ! lto_fixup_decl_minimal (t, data); > ! LTO_FIXUP_SUBTREE (DECL_SIZE (t)); > ! LTO_FIXUP_SUBTREE (DECL_SIZE_UNIT (t)); > ! LTO_FIXUP_SUBTREE (DECL_INITIAL (t)); > ! LTO_FIXUP_SUBTREE (DECL_ATTRIBUTES (t)); > ! LTO_FIXUP_SUBTREE (DECL_ABSTRACT_ORIGIN (t)); > ! } > ! > ! /* Fix up fields of a decl_with_vis T. DATA points to fix-up states. */ > ! > ! static void > ! lto_fixup_decl_with_vis (tree t, void *data) > ! { > ! lto_fixup_decl_common (t, data); > ! > ! /* Accessor macro has side-effects, use field-name here. */ > ! LTO_FIXUP_SUBTREE (t->decl_with_vis.assembler_name); > ! > ! gcc_assert (no_fixup_p (DECL_SECTION_NAME (t))); > ! } > ! > ! /* Fix up fields of a decl_non_common T. DATA points to fix-up states. */ > ! > ! static void > ! lto_fixup_decl_non_common (tree t, void *data) > ! { > ! lto_fixup_decl_with_vis (t, data); > ! LTO_FIXUP_SUBTREE (DECL_ARGUMENT_FLD (t)); > ! LTO_FIXUP_SUBTREE (DECL_RESULT_FLD (t)); > ! LTO_FIXUP_SUBTREE (DECL_VINDEX (t)); > ! > ! /* SAVED_TREE should not cleared by now. Also no accessor for base type. > */ > ! gcc_assert (no_fixup_p (t->decl_non_common.saved_tree)); > ! } > ! > ! /* Fix up fields of a decl_non_common T. DATA points to fix-up states. */ > ! > ! static void > ! lto_fixup_function (tree t, void *data) > ! { > ! lto_fixup_decl_non_common (t, data); > ! LTO_FIXUP_SUBTREE (DECL_FUNCTION_PERSONALITY (t)); > ! } > ! > ! /* Fix up fields of a field_decl T. DATA points to fix-up states. */ > ! > ! static void > ! lto_fixup_field_decl (tree t, void *data) > ! { > ! lto_fixup_decl_common (t, data); > ! LTO_FIXUP_SUBTREE (DECL_FIELD_OFFSET (t)); > ! LTO_FIXUP_SUBTREE (DECL_BIT_FIELD_TYPE (t)); > ! LTO_FIXUP_SUBTREE (DECL_QUALIFIER (t)); > ! gcc_assert (no_fixup_p (DECL_FIELD_BIT_OFFSET (t))); > ! LTO_FIXUP_SUBTREE (DECL_FCONTEXT (t)); > ! } > ! > ! /* Fix up fields of a type T. DATA points to fix-up states. */ > ! > ! static void > ! lto_fixup_type (tree t, void *data) > ! { > ! tree tem, mv; > ! > ! lto_fixup_common (t, data); > ! LTO_FIXUP_SUBTREE (TYPE_CACHED_VALUES (t)); > ! LTO_FIXUP_SUBTREE (TYPE_SIZE (t)); > ! LTO_FIXUP_SUBTREE (TYPE_SIZE_UNIT (t)); > ! LTO_FIXUP_SUBTREE (TYPE_ATTRIBUTES (t)); > ! LTO_FIXUP_SUBTREE (TYPE_NAME (t)); > ! > ! /* Accessors are for derived node types only. */ > ! if (!POINTER_TYPE_P (t)) > ! LTO_FIXUP_SUBTREE (t->type.minval); > ! LTO_FIXUP_SUBTREE (t->type.maxval); > ! > ! /* Accessor is for derived node types only. */ > ! LTO_FIXUP_SUBTREE (t->type.binfo); > ! > ! if (TYPE_CONTEXT (t)) > ! { > ! if (TYPE_P (TYPE_CONTEXT (t))) > ! LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CONTEXT (t)); > ! else > ! LTO_FIXUP_SUBTREE (TYPE_CONTEXT (t)); > ! } > ! > ! /* Compute the canonical type of t and fix that up. From this point > ! there are no longer any types with TYPE_STRUCTURAL_EQUALITY_P > ! and its type-based alias problems. */ > ! if (!TYPE_CANONICAL (t)) > ! { > ! TYPE_CANONICAL (t) = gimple_register_canonical_type (t); > ! LTO_FIXUP_SUBTREE (TYPE_CANONICAL (t)); > ! } > ! > ! /* The following re-creates proper variant lists while fixing up > ! the variant leaders. We do not stream TYPE_NEXT_VARIANT so the > ! variant list state before fixup is broken. */ > ! > ! /* Remove us from our main variant list if we are not the variant leader. > */ > ! if (TYPE_MAIN_VARIANT (t) != t) > ! { > ! tem = TYPE_MAIN_VARIANT (t); > ! while (tem && TYPE_NEXT_VARIANT (tem) != t) > ! tem = TYPE_NEXT_VARIANT (tem); > ! if (tem) > ! TYPE_NEXT_VARIANT (tem) = TYPE_NEXT_VARIANT (t); > ! TYPE_NEXT_VARIANT (t) = NULL_TREE; > ! } > ! > ! /* Query our new main variant. */ > ! mv = gimple_register_type (TYPE_MAIN_VARIANT (t)); > ! > ! /* If we were the variant leader and we get replaced ourselves drop > ! all variants from our list. */ > ! if (TYPE_MAIN_VARIANT (t) == t > ! && mv != t) > ! { > ! tem = t; > ! while (tem) > ! { > ! tree tem2 = TYPE_NEXT_VARIANT (tem); > ! TYPE_NEXT_VARIANT (tem) = NULL_TREE; > ! tem = tem2; > ! } > ! } > ! > ! /* If we are not our own variant leader link us into our new leaders > ! variant list. */ > ! if (mv != t) > ! { > ! TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (mv); > ! TYPE_NEXT_VARIANT (mv) = t; > ! } > ! > ! /* Finally adjust our main variant and fix it up. */ > ! TYPE_MAIN_VARIANT (t) = mv; > ! LTO_FIXUP_SUBTREE (TYPE_MAIN_VARIANT (t)); > ! > ! /* As the second step of reconstructing the pointer chains put us > ! on the list of pointers of the new pointed-to type > ! if we are a main variant. See lto_fixup_common for the first step. */ > ! if (TREE_CODE (t) == POINTER_TYPE > ! && TYPE_MAIN_VARIANT (t) == t) > ! { > ! TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (TREE_TYPE (t)); > ! TYPE_POINTER_TO (TREE_TYPE (t)) = t; > ! } > ! else if (TREE_CODE (t) == REFERENCE_TYPE > ! && TYPE_MAIN_VARIANT (t) == t) > ! { > ! TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (TREE_TYPE (t)); > ! TYPE_REFERENCE_TO (TREE_TYPE (t)) = t; > ! } > ! } > ! > ! /* Fix up fields of a BINFO T. DATA points to fix-up states. */ > ! > ! static void > ! lto_fixup_binfo (tree t, void *data) > ! { > ! unsigned HOST_WIDE_INT i, n; > ! tree base, saved_base; > ! > ! lto_fixup_common (t, data); > ! gcc_assert (no_fixup_p (BINFO_OFFSET (t))); > ! LTO_FIXUP_SUBTREE (BINFO_VTABLE (t)); > ! LTO_FIXUP_SUBTREE (BINFO_VIRTUALS (t)); > ! LTO_FIXUP_SUBTREE (BINFO_VPTR_FIELD (t)); > ! n = VEC_length (tree, BINFO_BASE_ACCESSES (t)); > ! for (i = 0; i < n; i++) > ! { > ! saved_base = base = BINFO_BASE_ACCESS (t, i); > ! LTO_FIXUP_SUBTREE (base); > ! if (base != saved_base) > ! VEC_replace (tree, BINFO_BASE_ACCESSES (t), i, base); > ! } > ! LTO_FIXUP_SUBTREE (BINFO_INHERITANCE_CHAIN (t)); > ! LTO_FIXUP_SUBTREE (BINFO_SUBVTT_INDEX (t)); > ! LTO_FIXUP_SUBTREE (BINFO_VPTR_INDEX (t)); > ! n = BINFO_N_BASE_BINFOS (t); > ! for (i = 0; i < n; i++) > ! { > ! saved_base = base = BINFO_BASE_BINFO (t, i); > ! LTO_FIXUP_SUBTREE (base); > ! if (base != saved_base) > ! VEC_replace (tree, BINFO_BASE_BINFOS (t), i, base); > ! } > ! } > ! > ! /* Fix up fields of a CONSTRUCTOR T. DATA points to fix-up states. */ > ! > ! static void > ! lto_fixup_constructor (tree t, void *data) > ! { > ! unsigned HOST_WIDE_INT idx; > ! constructor_elt *ce; > ! > ! LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TREE_TYPE (t)); > ! > ! for (idx = 0; > ! VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (t), idx, ce); > ! idx++) > ! { > ! LTO_FIXUP_SUBTREE (ce->index); > ! LTO_FIXUP_SUBTREE (ce->value); > ! } > ! } > ! > ! /* A walk_tree callback used by lto_fixup_state. TP is the pointer to the > ! current tree. WALK_SUBTREES indicates if the subtrees will be walked. > ! DATA is a pointer set to record visited nodes. */ > ! > ! static tree > ! lto_fixup_tree (tree *tp, int *walk_subtrees, void *data) > ! { > ! tree t; > ! lto_fixup_data_t *fixup_data = (lto_fixup_data_t *) data; > ! tree prevailing; > ! > ! t = *tp; > ! *walk_subtrees = 0; > ! if (!t || pointer_set_contains (fixup_data->seen, t)) > ! return NULL; > ! > ! if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == FUNCTION_DECL) > ! { > ! prevailing = lto_symtab_prevailing_decl (t); > ! > ! if (t != prevailing) > ! { > ! /* Also replace t with prevailing defintion. We don't want to > ! insert the other defintion in the seen set as we want to > ! replace all instances of it. */ > ! *tp = prevailing; > ! t = prevailing; > } > } > else if (TYPE_P (t)) > { > ! /* Replace t with the prevailing type. We don't want to insert the > ! other type in the seen set as we want to replace all instances of > it. */ > ! t = gimple_register_type (t); > ! *tp = t; > } > ! > ! if (pointer_set_insert (fixup_data->seen, t)) > ! return NULL; > ! > ! /* walk_tree does not visit all reachable nodes that need to be fixed up. > ! Hence we do special processing here for those kind of nodes. */ > ! switch (TREE_CODE (t)) > { > ! case FIELD_DECL: > ! lto_fixup_field_decl (t, data); > ! break; > ! > ! case LABEL_DECL: > ! case CONST_DECL: > ! case PARM_DECL: > ! case RESULT_DECL: > ! case IMPORTED_DECL: > ! lto_fixup_decl_common (t, data); > ! break; > ! > ! case VAR_DECL: > ! lto_fixup_decl_with_vis (t, data); > ! break; > ! > ! case TYPE_DECL: > ! lto_fixup_decl_non_common (t, data); > ! break; > ! > ! case FUNCTION_DECL: > ! lto_fixup_function (t, data); > ! break; > ! > ! case TREE_BINFO: > ! lto_fixup_binfo (t, data); > ! break; > ! > ! default: > ! if (TYPE_P (t)) > ! lto_fixup_type (t, data); > ! else if (TREE_CODE (t) == CONSTRUCTOR) > ! lto_fixup_constructor (t, data); > ! else if (CONSTANT_CLASS_P (t)) > ! LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TREE_TYPE (t)); > ! else if (EXPR_P (t)) > ! { > ! /* walk_tree only handles TREE_OPERANDs. Do the rest here. */ > ! lto_fixup_common (t, data); > ! LTO_FIXUP_SUBTREE (t->exp.block); > ! *walk_subtrees = 1; > ! } > ! else > { > ! /* Let walk_tree handle sub-trees. */ > ! *walk_subtrees = 1; > } > } > - > - return NULL; > } > > /* Helper function of lto_fixup_decls. Walks the var and fn streams in STATE, > ! replaces var and function decls with the corresponding prevailing def and > ! records the old decl in the free-list in DATA. We also record visted > nodes > ! in the seen-set in DATA to avoid multiple visit for nodes that need not > ! to be replaced. */ > > static void > ! lto_fixup_state (struct lto_in_decl_state *state, lto_fixup_data_t *data) > { > unsigned i, si; > struct lto_tree_ref_table *table; > --- 1980,2085 ---- > } > > > ! /* If TT is a variable or function decl replace it with its > ! prevailing variant. */ > ! #define LTO_SET_PREVAIL(tt) \ > ! do {\ > ! if ((tt) && VAR_OR_FUNCTION_DECL_P (tt)) \ > ! tt = lto_symtab_prevailing_decl (tt); \ > ! } while (0) > ! > ! /* Ensure that TT isn't a replacable var of function decl. */ > ! #define LTO_NO_PREVAIL(tt) \ > ! gcc_assert (!(tt) || !VAR_OR_FUNCTION_DECL_P (tt)) > ! > ! /* Given a tree T replace all fields referring to variables or functions > ! with their prevailing variant. */ > ! static void > ! lto_fixup_prevailing_decls (tree t) > ! { > ! enum tree_code code = TREE_CODE (t); > ! LTO_NO_PREVAIL (TREE_TYPE (t)); > ! LTO_NO_PREVAIL (TREE_CHAIN (t)); > ! if (DECL_P (t)) > ! { > ! LTO_NO_PREVAIL (DECL_NAME (t)); > ! LTO_SET_PREVAIL (DECL_CONTEXT (t)); > ! if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) > ! { > ! LTO_SET_PREVAIL (DECL_SIZE (t)); > ! LTO_SET_PREVAIL (DECL_SIZE_UNIT (t)); > ! LTO_SET_PREVAIL (DECL_INITIAL (t)); > ! LTO_NO_PREVAIL (DECL_ATTRIBUTES (t)); > ! LTO_SET_PREVAIL (DECL_ABSTRACT_ORIGIN (t)); > ! } > ! if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)) > ! { > ! LTO_NO_PREVAIL (t->decl_with_vis.assembler_name); > ! LTO_NO_PREVAIL (DECL_SECTION_NAME (t)); > ! } > ! if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON)) > ! { > ! LTO_NO_PREVAIL (DECL_ARGUMENT_FLD (t)); > ! LTO_NO_PREVAIL (DECL_RESULT_FLD (t)); > ! LTO_NO_PREVAIL (DECL_VINDEX (t)); > ! } > ! if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL)) > ! LTO_SET_PREVAIL (DECL_FUNCTION_PERSONALITY (t)); > ! if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL)) > ! { > ! LTO_NO_PREVAIL (DECL_FIELD_OFFSET (t)); > ! LTO_NO_PREVAIL (DECL_BIT_FIELD_TYPE (t)); > ! LTO_NO_PREVAIL (DECL_QUALIFIER (t)); > ! LTO_NO_PREVAIL (DECL_FIELD_BIT_OFFSET (t)); > ! LTO_NO_PREVAIL (DECL_FCONTEXT (t)); > } > } > else if (TYPE_P (t)) > { > ! LTO_NO_PREVAIL (TYPE_CACHED_VALUES (t)); > ! LTO_SET_PREVAIL (TYPE_SIZE (t)); > ! LTO_SET_PREVAIL (TYPE_SIZE_UNIT (t)); > ! LTO_NO_PREVAIL (TYPE_ATTRIBUTES (t)); > ! LTO_NO_PREVAIL (TYPE_NAME (t)); > ! > ! LTO_SET_PREVAIL (t->type.minval); > ! LTO_SET_PREVAIL (t->type.maxval); > ! LTO_SET_PREVAIL (t->type.binfo); > ! > ! LTO_SET_PREVAIL (TYPE_CONTEXT (t)); > ! > ! LTO_NO_PREVAIL (TYPE_CANONICAL (t)); > ! LTO_NO_PREVAIL (TYPE_MAIN_VARIANT (t)); > ! LTO_NO_PREVAIL (TYPE_NEXT_VARIANT (t)); > ! } > ! else if (EXPR_P (t)) > ! { > ! int i; > ! LTO_NO_PREVAIL (t->exp.block); > ! for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i) > ! LTO_SET_PREVAIL (TREE_OPERAND (t, i)); > } > ! else > { > ! switch (code) > { > ! case TREE_LIST: > ! LTO_SET_PREVAIL (TREE_VALUE (t)); > ! LTO_SET_PREVAIL (TREE_PURPOSE (t)); > ! break; > ! default: > ! gcc_unreachable (); > } > } > } > + #undef LTO_SET_PREVAIL > + #undef LTO_NO_PREVAIL > > /* Helper function of lto_fixup_decls. Walks the var and fn streams in STATE, > ! replaces var and function decls with the corresponding prevailing def. > */ > > static void > ! lto_fixup_state (struct lto_in_decl_state *state) > { > unsigned i, si; > struct lto_tree_ref_table *table; > *************** lto_fixup_state (struct lto_in_decl_stat > *** 1969,1986 **** > { > table = &state->streams[si]; > for (i = 0; i < table->size; i++) > ! walk_tree (table->trees + i, lto_fixup_tree, data, NULL); > } > } > > ! /* A callback of htab_traverse. Just extract a state from SLOT and the > ! lto_fixup_data_t object from AUX and calls lto_fixup_state. */ > > static int > ! lto_fixup_state_aux (void **slot, void *aux) > { > struct lto_in_decl_state *state = (struct lto_in_decl_state *) *slot; > ! lto_fixup_state (state, (lto_fixup_data_t *) aux); > return 1; > } > > --- 2091,2112 ---- > { > table = &state->streams[si]; > for (i = 0; i < table->size; i++) > ! { > ! tree *tp = table->trees + i; > ! if (VAR_OR_FUNCTION_DECL_P (*tp)) > ! *tp = lto_symtab_prevailing_decl (*tp); > ! } > } > } > > ! /* A callback of htab_traverse. Just extracts a state from SLOT > ! and calls lto_fixup_state. */ > > static int > ! lto_fixup_state_aux (void **slot, void *aux ATTRIBUTE_UNUSED) > { > struct lto_in_decl_state *state = (struct lto_in_decl_state *) *slot; > ! lto_fixup_state (state); > return 1; > } > > *************** static void > *** 1991,2019 **** > lto_fixup_decls (struct lto_file_decl_data **files) > { > unsigned int i; > ! tree decl; > ! struct pointer_set_t *seen = pointer_set_create (); > ! lto_fixup_data_t data; > > - data.seen = seen; > for (i = 0; files[i]; i++) > { > struct lto_file_decl_data *file = files[i]; > struct lto_in_decl_state *state = file->global_decl_state; > ! lto_fixup_state (state, &data); > ! > ! htab_traverse (file->function_decl_states, lto_fixup_state_aux, > &data); > ! } > > ! FOR_EACH_VEC_ELT (tree, lto_global_var_decls, i, decl) > ! { > ! tree saved_decl = decl; > ! walk_tree (&decl, lto_fixup_tree, &data, NULL); > ! if (decl != saved_decl) > ! VEC_replace (tree, lto_global_var_decls, i, decl); > } > - > - pointer_set_destroy (seen); > } > > /* Read the options saved from each file in the command line. Called > --- 2117,2136 ---- > lto_fixup_decls (struct lto_file_decl_data **files) > { > unsigned int i; > ! htab_iterator hi; > ! tree t; > ! > ! FOR_EACH_HTAB_ELEMENT (tree_with_vars, t, tree, hi) > ! lto_fixup_prevailing_decls (t); > > for (i = 0; files[i]; i++) > { > struct lto_file_decl_data *file = files[i]; > struct lto_in_decl_state *state = file->global_decl_state; > ! lto_fixup_state (state); > > ! htab_traverse (file->function_decl_states, lto_fixup_state_aux, NULL); > } > } > > /* Read the options saved from each file in the command line. Called > *************** read_cgraph_and_symbols (unsigned nfiles > *** 2144,2149 **** > --- 2261,2269 ---- > gcc_assert (num_objects == nfiles); > } > > + tree_with_vars = htab_create_ggc (101, htab_hash_pointer, htab_eq_pointer, > + NULL); > + > if (!quiet_flag) > fprintf (stderr, "Reading object files:"); > > *************** read_cgraph_and_symbols (unsigned nfiles > *** 2211,2216 **** > --- 2331,2338 ---- > > /* Fixup all decls and types and free the type hash tables. */ > lto_fixup_decls (all_file_decl_data); > + htab_delete (tree_with_vars); > + tree_with_vars = NULL; > free_gimple_type_tables (); > ggc_collect (); > > Index: lto/Make-lang.in > =================================================================== > *** lto/Make-lang.in (revision 172769) > --- lto/Make-lang.in (working copy) > *************** lto/lto-lang.o: lto/lto-lang.c $(CONFIG_ > *** 81,87 **** > $(TARGET_H) $(LTO_H) $(GIMPLE_H) gtype-lto.h gt-lto-lto-lang.h \ > $(EXPR_H) $(LTO_STREAMER_H) > lto/lto.o: lto/lto.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(OPTS_H) \ > ! toplev.h $(TREE_H) $(DIAGNOSTIC_CORE_H) $(TM_H) \ > $(CGRAPH_H) $(GGC_H) tree-ssa-operands.h $(TREE_PASS_H) \ > langhooks.h $(VEC_H) $(BITMAP_H) pointer-set.h $(IPA_PROP_H) \ > $(COMMON_H) debug.h $(TIMEVAR_H) $(GIMPLE_H) $(LTO_H) $(LTO_TREE_H) \ > --- 81,87 ---- > $(TARGET_H) $(LTO_H) $(GIMPLE_H) gtype-lto.h gt-lto-lto-lang.h \ > $(EXPR_H) $(LTO_STREAMER_H) > lto/lto.o: lto/lto.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(OPTS_H) \ > ! toplev.h $(TREE_H) $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(TM_H) \ > $(CGRAPH_H) $(GGC_H) tree-ssa-operands.h $(TREE_PASS_H) \ > langhooks.h $(VEC_H) $(BITMAP_H) pointer-set.h $(IPA_PROP_H) \ > $(COMMON_H) debug.h $(TIMEVAR_H) $(GIMPLE_H) $(LTO_H) $(LTO_TREE_H) \ >