This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][LTO] [3/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 16:09:33 +0200 (CEST)
- Subject: [PATCH][LTO] [3/3] Fix bootstrap with -flto
Third part. This part reconstructs the pointer-to and reference-to
chains during fixup and avoids streaming them. We were arriving with
some odd pointer-to chains previously which confuses build_pointer_type
and caused it to re-build pointers endlessly.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
Richard.
2009-08-19 Richard Guenther <rguenther@suse.de>
PR lto/41071
* gimple.c (gimple_register_type): Unlink a pointer from its
pointer chain if we will use a different type for it.
* lto-streamer-out.c (lto_output_ts_type_tree_pointers):
Do not output TYPE_POINTER_TO, TYPE_REFERENCE_TO and
TYPE_NEXT_PTR/REF_TO.
* lto-streamer-in.c (lto_input_ts_type_tree_pointers):
Do not input TYPE_POINTER_TO, TYPE_REFERENCE_TO and
TYPE_NEXT_PTR/REF_TO.
lto/
* lto.c (lto_fixup_common): Re-build the pointer-to chain part one.
(lto_fixup_type): Re-build the pointer-to chain part two.
Index: lto/gcc/lto-streamer-out.c
===================================================================
*** lto.orig/gcc/lto-streamer-out.c 2009-08-19 11:32:03.000000000 +0200
--- lto/gcc/lto-streamer-out.c 2009-08-19 11:32:25.000000000 +0200
*************** lto_output_ts_type_tree_pointers (struct
*** 1061,1070 ****
lto_output_tree_or_ref (ob, TYPE_SIZE (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_SIZE_UNIT (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_ATTRIBUTES (expr), ref_p);
- lto_output_tree_or_ref (ob, TYPE_POINTER_TO (expr), ref_p);
- lto_output_tree_or_ref (ob, TYPE_REFERENCE_TO (expr), ref_p);
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
--- 1061,1071 ----
lto_output_tree_or_ref (ob, TYPE_SIZE (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_SIZE_UNIT (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_ATTRIBUTES (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_NAME (expr), ref_p);
! /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO nor
! TYPE_NEXT_PTR_TO or TYPE_NEXT_REF_TO. */
! if (!POINTER_TYPE_P (expr))
! 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
Index: lto/gcc/gimple.c
===================================================================
*** lto.orig/gcc/gimple.c 2009-08-19 11:19:39.000000000 +0200
--- lto/gcc/gimple.c 2009-08-19 12:28:44.000000000 +0200
*************** gimple_register_type (tree t)
*** 3926,3931 ****
--- 3926,3963 ----
TYPE_NEXT_VARIANT (t) = NULL_TREE;
}
+ /* If we are a pointer then remove us from the pointer-to or
+ reference-to chain. Otherwise we'd queue up a lot of duplicates
+ there. */
+ 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;
+ }
+
t = new_type;
}
else
Index: lto/gcc/lto-streamer-in.c
===================================================================
*** lto.orig/gcc/lto-streamer-in.c 2009-08-19 11:32:16.000000000 +0200
--- lto/gcc/lto-streamer-in.c 2009-08-19 11:32:34.000000000 +0200
*************** lto_input_ts_type_tree_pointers (struct
*** 1985,1994 ****
TYPE_SIZE (expr) = lto_input_tree (ib, data_in);
TYPE_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
TYPE_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
- TYPE_POINTER_TO (expr) = lto_input_tree (ib, data_in);
- TYPE_REFERENCE_TO (expr) = lto_input_tree (ib, data_in);
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
--- 1985,1995 ----
TYPE_SIZE (expr) = lto_input_tree (ib, data_in);
TYPE_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
TYPE_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
TYPE_NAME (expr) = lto_input_tree (ib, data_in);
! /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO nor
! TYPE_NEXT_PTR_TO or TYPE_NEXT_REF_TO. */
! if (!POINTER_TYPE_P (expr))
! 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
Index: lto/gcc/lto/lto.c
===================================================================
*** lto.orig/gcc/lto/lto.c 2009-08-19 11:16:15.000000000 +0200
--- lto/gcc/lto/lto.c 2009-08-19 12:25:41.000000000 +0200
*************** no_fixup_p (tree t)
*** 1114,1125 ****
static void
lto_fixup_common (tree t, void *data)
{
! /* If T has a type, make sure it is registered in the global type
! table. If the type existed already, use the existing one. */
! if (TREE_TYPE (t))
! TREE_TYPE (t) = gimple_register_type (TREE_TYPE (t));
- LTO_FIXUP_SUBTREE (TREE_TYPE (t));
/* This is not very efficient because we cannot do tail-recursion with
a long chain of trees. */
LTO_FIXUP_SUBTREE (TREE_CHAIN (t));
--- 1114,1159 ----
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. */
LTO_FIXUP_SUBTREE (TREE_CHAIN (t));
*************** lto_fixup_type (tree t, void *data)
*** 1209,1220 ****
LTO_FIXUP_SUBTREE (TYPE_SIZE (t));
LTO_FIXUP_SUBTREE (TYPE_SIZE_UNIT (t));
LTO_FIXUP_SUBTREE (TYPE_ATTRIBUTES (t));
- LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_POINTER_TO (t));
- LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_REFERENCE_TO (t));
LTO_FIXUP_SUBTREE (TYPE_NAME (t));
/* Accessors are for derived node types only. */
! LTO_FIXUP_SUBTREE (t->type.minval);
LTO_FIXUP_SUBTREE (t->type.maxval);
/* Accessor is for derived node types only. */
--- 1243,1253 ----
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_type (tree t, void *data)
*** 1266,1271 ****
--- 1299,1320 ----
/* 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. */