This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix SPEC gcc micompile with LTO
Hi,
this is updated version of the patch. As discussed on IRC, C++ has two
different types of references (rvalue and normal). They have different
canonical type, but this does not affect outcome of get_alias_set
because it rebuilds the pointer/reference types from scratch.
The effect of this patch is to turn both into one type when pointer is
reuilt that should be safe. So I simply relaxed the sanity check that
type canonicals needs to be same for pointers.
lto-bootstrapped/regtested x86_64-linux, plan to commit it shortly.
Honza
* gcc.dg/lto/tbaa-1.c: New testcase.
* tree.c (fld_type_variant): Copy canonical type.
(fld_incomplete_type_of): Check that canonical types looks sane;
copy canonical type.
(verify_type): Accept when incomplete type has complete canonical type.
Index: testsuite/gcc.dg/lto/tbaa-1.c
===================================================================
--- testsuite/gcc.dg/lto/tbaa-1.c (nonexistent)
+++ testsuite/gcc.dg/lto/tbaa-1.c (working copy)
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -flto -fdump-tree-evrp" } */
+typedef struct rtx_def *rtx;
+typedef struct cselib_val_struct
+{
+ union
+ {
+ } u;
+ struct elt_loc_list *locs;
+}
+cselib_val;
+struct elt_loc_list
+{
+ struct elt_loc_list *next;
+ rtx loc;
+};
+static int n_useless_values;
+unchain_one_elt_loc_list (pl)
+ struct elt_loc_list **pl;
+{
+ struct elt_loc_list *l = *pl;
+ *pl = l->next;
+}
+
+discard_useless_locs (x, info)
+ void **x;
+{
+ cselib_val *v = (cselib_val *) * x;
+ struct elt_loc_list **p = &v->locs;
+ int had_locs = v->locs != 0;
+ while (*p)
+ {
+ unchain_one_elt_loc_list (p);
+ p = &(*p)->next;
+ }
+ if (had_locs && v->locs == 0)
+ {
+ n_useless_values++;
+ }
+}
+/* { dg-final { scan-tree-dump-times "n_useless_values" 2 "evrp" } } */
Index: tree.c
===================================================================
--- tree.c (revision 265807)
+++ tree.c (working copy)
@@ -5118,6 +5118,7 @@ fld_type_variant (tree first, tree t, st
TYPE_ADDR_SPACE (v) = TYPE_ADDR_SPACE (t);
TYPE_NAME (v) = TYPE_NAME (t);
TYPE_ATTRIBUTES (v) = TYPE_ATTRIBUTES (t);
+ TYPE_CANONICAL (v) = TYPE_CANONICAL (t);
add_tree_to_fld_list (v, fld);
return v;
}
@@ -5146,6 +5147,8 @@ fld_incomplete_type_of (tree t, struct f
else
first = build_reference_type_for_mode (t2, TYPE_MODE (t),
TYPE_REF_CAN_ALIAS_ALL (t));
+ gcc_assert (TYPE_CANONICAL (t2) != t2
+ && TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t)));
add_tree_to_fld_list (first, fld);
return fld_type_variant (first, t, fld);
}
@@ -5169,6 +5174,7 @@ fld_incomplete_type_of (tree t, struct f
SET_TYPE_MODE (copy, VOIDmode);
SET_TYPE_ALIGN (copy, BITS_PER_UNIT);
TYPE_SIZE_UNIT (copy) = NULL;
+ TYPE_CANONICAL (copy) = TYPE_CANONICAL (t);
if (AGGREGATE_TYPE_P (t))
{
TYPE_FIELDS (copy) = NULL;
@@ -13880,7 +13893,8 @@ verify_type (const_tree t)
with variably sized arrays because their sizes possibly
gimplified to different variables. */
&& !variably_modified_type_p (ct, NULL)
- && !gimple_canonical_types_compatible_p (t, ct, false))
+ && !gimple_canonical_types_compatible_p (t, ct, false)
+ && COMPLETE_TYPE_P (t))
{
error ("TYPE_CANONICAL is not compatible");
debug_tree (ct);