This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][LTO] Allow bootstrapping lto, break whopr (ugh)
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Diego Novillo <dnovillo at google dot com>
- Date: Sat, 15 Aug 2009 18:16:15 +0200 (CEST)
- Subject: [PATCH][LTO] Allow bootstrapping lto, break whopr (ugh)
This patch allows me to bootstrap with BOOT_CFLAGS including -flto
until the comparison which fails. The key element of the patch and
all what should be required to fix bootstrapping is the
gimple_get_alias_set change - but that doesn't work because of
lto/41071. I tried to fix that and it went smooth until running
the testsuite which shows whopr is confused about all the main
variant stuff (the original fix was just to
LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE both the TYPE_MAIN_VARIANT
and TYPE_NEXT_VARIANT (which in turn required the compar_type_names_p
change). With the extra hacks the whopr fails are down to a few
hundred (ugh).
Does anyone remember why we have to hack around the TYPE_MAIN/NEXT_VARIANT
stuff (we do so in free-lang-data, but new next-variants are introduced
before streaming out again during ltrans - it's not enough to stream
out NULLs here either)?
I will probably try (just because I am a masochist) to properly
deal with this variant list and not fix them up during free-lang-data
(which should hopefully uncover the problems with -flto as well).
But - I guess you guys tried that already?
Anyway, the following patch bootstraps ok and tests with zero extra
-flto fails. It fixes bootstrap with -flto on i?86 for me, building
all of stage3 fine.
Thanks,
Richard.
2009-08-15 Richard Guenther <rguenther@suse.de>
PR lto/41071
* gimple.c (compare_type_names_p): Do not look at the
types main variant.
(gimple_register_type): Always register the main variant first.
(gimple_get_alias_set): Pointers to CV qualified variants
have the same alias-set as unqualified variants.
lto/
* lto.c (lto_fixup_type): Register and replace the types
main variant, zero its next variant.
Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c.orig 2009-08-15 15:25:24.000000000 +0200
--- gcc/gimple.c 2009-08-15 16:36:36.000000000 +0200
*************** lookup_type_pair (tree t1, tree t2, htab
*** 3185,3192 ****
static bool
compare_type_names_p (tree t1, tree t2)
{
- tree variant1 = TYPE_MAIN_VARIANT (t1);
- tree variant2 = TYPE_MAIN_VARIANT (t2);
tree name1 = TYPE_NAME (t1);
tree name2 = TYPE_NAME (t2);
--- 3185,3190 ----
*************** compare_type_names_p (tree t1, tree t2)
*** 3215,3228 ****
if (name1 == name2)
return true;
- /* If either type has a variant type, compare that. This finds
- the case where a struct is typedef'ed in one module but referred
- to as 'struct foo' in the other; here, the main type for one is
- 'foo', and for the other 'foo_t', but the variants have the same
- name 'foo'. */
- if (variant1 != t1 || variant2 != t2)
- return compare_type_names_p (variant1, variant2);
-
return false;
}
--- 3213,3218 ----
*************** gimple_register_type (tree t)
*** 3907,3912 ****
--- 3897,3907 ----
print_generic_stmt (stderr, t, 0);
}
+ /* Always register the main variant first. It is the one we want to
+ canonicalize to - otherwise that somehow breaks whopr. */
+ if (TYPE_MAIN_VARIANT (t) != t)
+ gimple_register_type (TYPE_MAIN_VARIANT (t));
+
slot = htab_find_slot (gimple_types, t, INSERT);
if (*slot)
{
*************** gimple_get_alias_set (tree t)
*** 4183,4188 ****
--- 4178,4213 ----
if (t1 != t)
return get_alias_set (t1);
}
+ else if (POINTER_TYPE_P (t))
+ {
+ tree t1;
+
+ /* Unfortunately, there is no canonical form of a pointer type.
+ In particular, if we have `typedef int I', then `int *', and
+ `I *' are different types. So, we have to pick a canonical
+ representative. We do this below.
+
+ Technically, this approach is actually more conservative that
+ it needs to be. In particular, `const int *' and `int *'
+ should be in different alias sets, according to the C and C++
+ standard, since their types are not the same, and so,
+ technically, an `int **' and `const int **' cannot point at
+ the same thing.
+
+ But, the standard is wrong. In particular, this code is
+ legal C++:
+
+ int *ip;
+ int **ipp = &ip;
+ const int* const* cipp = ipp;
+ And, it doesn't make sense for that to be legal unless you
+ can dereference IPP and CIPP. So, we ignore cv-qualifiers on
+ the pointed-to types. This issue has been reported to the
+ C++ committee. */
+ t1 = build_type_no_quals (t);
+ if (t1 != t)
+ return get_alias_set (t1);
+ }
return -1;
}
Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c.orig 2009-08-15 15:25:13.000000000 +0200
--- gcc/lto/lto.c 2009-08-15 16:35:28.000000000 +0200
*************** lto_fixup_type (tree t, void *data)
*** 1215,1222 ****
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);
--- 1215,1223 ----
LTO_FIXUP_SUBTREE (t->type.minval);
LTO_FIXUP_SUBTREE (t->type.maxval);
! LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_MAIN_VARIANT (t));
! /* FIXME lto. We are not good in preserving the list of variant types. */
! TYPE_NEXT_VARIANT (t) = NULL_TREE;
/* Accessor is for derived node types only. */
LTO_FIXUP_SUBTREE (t->type.binfo);