This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][LTO] [2/3] Fix bootstrap with -flto
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 19 Aug 2009 13:57:42 +0200 (CEST)
- Subject: [PATCH][LTO] [2/3] Fix bootstrap with -flto
This is piece two. It reconstructs the type variant chains during
fixup time and avoids streaming TYPE_NEXT_VARIANT at all.
Bootstrapped and tested on x86_64-unknown-linux-gnu ontop of patch one.
Richard.
2009-08-19 Richard Guenther <rguenther@suse.de>
PR lto/41071
* gimple.c (gimple_register_type): Unlink a non-main-variant from its
variant chain if we will use a different type for it.
* tree.c (free_lang_data_in_type): Do not free the variant chains.
* lto-streamer-out.c (lto_output_ts_type_tree_pointers): Do
not output TYPE_NEXT_VARIANT.
* lto-streamer-in.c (lto_input_ts_type_tree_pointers): Do not
input TYPE_NEXT_VARIANT.
lto/
* lto.c (lto_fixup_type): Re-build the type variant chain.
Index: lto/gcc/gimple.c
===================================================================
*** lto.orig/gcc/gimple.c 2009-08-19 10:49:51.000000000 +0200
--- lto/gcc/gimple.c 2009-08-19 11:19:39.000000000 +0200
*************** gimple_register_type (tree t)
*** 3898,3904 ****
}
slot = htab_find_slot (gimple_types, t, INSERT);
! if (*slot)
{
tree new_type = (tree) *((tree *) slot);
--- 3898,3905 ----
}
slot = htab_find_slot (gimple_types, t, INSERT);
! if (*slot
! && *(tree *)slot != t)
{
tree new_type = (tree) *((tree *) slot);
*************** gimple_register_type (tree t)
*** 3907,3918 ****
if (getenv ("MERGE_TYPE_DEBUG"))
{
! if (t != new_type)
! {
! fprintf (stderr, "Merged with existing compatible type: %p - ",
! *slot);
! print_generic_stmt (stderr, new_type, 0);
! }
}
t = new_type;
--- 3908,3929 ----
if (getenv ("MERGE_TYPE_DEBUG"))
{
! fprintf (stderr, "Merged with existing compatible type: %p - ",
! *slot);
! print_generic_stmt (stderr, new_type, 0);
! }
!
! /* If t is not its main variant then make t unreachable from its
! main variant list. Otherwise we'd queue up a lot of duplicates
! there. */
! if (t != TYPE_MAIN_VARIANT (t))
! {
! tree 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;
}
t = new_type;
Index: lto/gcc/lto-streamer-in.c
===================================================================
*** lto.orig/gcc/lto-streamer-in.c 2009-08-18 17:24:59.000000000 +0200
--- lto/gcc/lto-streamer-in.c 2009-08-19 10:53:32.000000000 +0200
*************** lto_input_ts_type_tree_pointers (struct
*** 1990,1997 ****
TYPE_NAME (expr) = lto_input_tree (ib, data_in);
TYPE_MINVAL (expr) = lto_input_tree (ib, data_in);
TYPE_MAXVAL (expr) = lto_input_tree (ib, data_in);
- TYPE_NEXT_VARIANT (expr) = lto_input_tree (ib, data_in);
TYPE_MAIN_VARIANT (expr) = lto_input_tree (ib, data_in);
if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE)
TYPE_BINFO (expr) = lto_input_tree (ib, data_in);
TYPE_CONTEXT (expr) = lto_input_tree (ib, data_in);
--- 1990,1998 ----
TYPE_NAME (expr) = lto_input_tree (ib, data_in);
TYPE_MINVAL (expr) = lto_input_tree (ib, data_in);
TYPE_MAXVAL (expr) = lto_input_tree (ib, data_in);
TYPE_MAIN_VARIANT (expr) = lto_input_tree (ib, data_in);
+ /* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
+ during fixup. */
if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE)
TYPE_BINFO (expr) = lto_input_tree (ib, data_in);
TYPE_CONTEXT (expr) = lto_input_tree (ib, data_in);
Index: lto/gcc/lto-streamer-out.c
===================================================================
*** lto.orig/gcc/lto-streamer-out.c 2009-08-19 10:49:51.000000000 +0200
--- lto/gcc/lto-streamer-out.c 2009-08-19 10:52:59.000000000 +0200
*************** lto_output_ts_type_tree_pointers (struct
*** 1066,1073 ****
lto_output_tree_or_ref (ob, TYPE_NAME (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_MINVAL (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_MAXVAL (expr), ref_p);
- lto_output_tree_or_ref (ob, TYPE_NEXT_VARIANT (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_MAIN_VARIANT (expr), ref_p);
if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE)
lto_output_tree_or_ref (ob, TYPE_BINFO (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_CONTEXT (expr), ref_p);
--- 1066,1074 ----
lto_output_tree_or_ref (ob, TYPE_NAME (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_MINVAL (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_MAXVAL (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_MAIN_VARIANT (expr), ref_p);
+ /* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
+ during fixup. */
if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE)
lto_output_tree_or_ref (ob, TYPE_BINFO (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_CONTEXT (expr), ref_p);
Index: lto/gcc/lto/lto.c
===================================================================
*** lto.orig/gcc/lto/lto.c 2009-08-19 10:49:51.000000000 +0200
--- lto/gcc/lto/lto.c 2009-08-19 11:16:15.000000000 +0200
*************** lto_fixup_field_decl (tree t, void *data
*** 1202,1207 ****
--- 1202,1209 ----
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_type (tree t, void *data)
*** 1215,1228 ****
LTO_FIXUP_SUBTREE (t->type.minval);
LTO_FIXUP_SUBTREE (t->type.maxval);
- LTO_FIXUP_SUBTREE (TYPE_NEXT_VARIANT (t));
- LTO_FIXUP_SUBTREE (TYPE_MAIN_VARIANT (t));
-
/* Accessor is for derived node types only. */
LTO_FIXUP_SUBTREE (t->type.binfo);
LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CONTEXT (t));
LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CANONICAL (t));
}
/* Fix up fields of a BINFO T. DATA points to fix-up states. */
--- 1217,1271 ----
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);
LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CONTEXT (t));
LTO_REGISTER_TYPE_AND_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));
}
/* Fix up fields of a BINFO T. DATA points to fix-up states. */
Index: lto/gcc/tree.c
===================================================================
*** lto.orig/gcc/tree.c 2009-08-18 17:24:59.000000000 +0200
--- lto/gcc/tree.c 2009-08-19 10:52:25.000000000 +0200
*************** free_lang_data_in_type (tree type)
*** 4222,4237 ****
/* FIXME lto: This will break debug info generation. */
TYPE_STUB_DECL (type) = NULL_TREE;
-
- /* Remove type variants other than the main variant. This is both
- wasteful and it may introduce infinite loops when the types are
- read from disk and merged (since the variant will be the same
- type as the main variant, traversing type variants will get into
- an infinite loop). */
- if (TYPE_MAIN_VARIANT (type))
- TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (type)) = NULL_TREE;
-
- TYPE_NEXT_VARIANT (type) = NULL_TREE;
}
--- 4222,4227 ----