On Mon, 9 Nov 2020, Jan Hubicka wrote: > Hi, > this patch implements cleanup we discussed some time ago on IRC. > Instead of recording reference types in ipa-modref I record pointer > types same way as done by RTL attributes and I moved corresponding logic > to tree-ssa-alias.c. > Problem is that it breaks some testcases: > > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr50444.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr50444.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr50444.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr50444.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr52419.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr52419.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr52419.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr52419.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-1.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-1.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-1.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-1.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-2.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-2.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-2.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-2.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-3.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-3.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-3.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-3.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-4.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-4.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-4.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr57748-4.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr58041.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr58041.c -O2 -flto > -fno-use-linker-plugin -flto-partition=none (test for excess errors) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr58041.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) > ./testsuite/gcc/gcc.sum:FAIL: gcc.dg/torture/pr58041.c -O2 -flto > -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) > > I looked into first one and it is caused by "may_alias" attribute on the > vector type. This makes build_pointer_type to set that it may alias all > and the get_deref_alias_type return 0 while ao_ref_alias_set returns 4.
Hmm, why does ao_ref_alias_set return 4? On what reference? Note that get_ref_alias_ptr_type necessarily gets you a single pointer type (compared to ao_refs base / ref ones). Still for vector types this shouldn't make a difference ... > I can live with this small loss of precision for ipa-modref, but I am > using same logic in the ao_ref_compare for ipa-icf where we can not be > conservative. I wonder how to fix this. One option is to keep the > ipa-modref way of recording actual types that determine alias set rather > pointers to them, but I recall you considered it confusing to have two > sets of machineries for this. So perhaps we want to add a way to build > pointer type ignoring may alias attribute? But the may-alias type makes a semantic difference ... So I'm not really understanding the issue here :/ (and sorry for the delay answering). Richard. > I see that RTL needs this to handle alias sets 0 because it also needs > mathcing type size. I do not need that in TBAA machinery. > > Honza > > diff --git a/gcc/alias.c b/gcc/alias.c > index f6d7a1791c4..0b12a89657e 100644 > --- a/gcc/alias.c > +++ b/gcc/alias.c > @@ -737,7 +737,7 @@ get_deref_alias_set (tree t) > adjusted to point to the outermost component reference that > can be used for assigning an alias set. */ > > -tree > +static tree > reference_alias_ptr_type_1 (tree *t) > { > tree inner; > diff --git a/gcc/alias.h b/gcc/alias.h > index 807af957f02..4453d9723ce 100644 > --- a/gcc/alias.h > +++ b/gcc/alias.h > @@ -36,7 +36,6 @@ extern int objects_must_conflict_p (tree, tree); > extern int nonoverlapping_memrefs_p (const_rtx, const_rtx, bool); > extern void dump_alias_stats_in_alias_c (FILE *s); > tree reference_alias_ptr_type (tree); > -tree reference_alias_ptr_type_1 (tree *); > bool alias_ptr_types_compatible_p (tree, tree); > int compare_base_decls (tree, tree); > bool refs_same_for_tbaa_p (tree, tree); > diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c > index 3f46bebed3c..a621b30b1e1 100644 > --- a/gcc/ipa-modref.c > +++ b/gcc/ipa-modref.c > @@ -328,7 +328,7 @@ dump_lto_records (modref_records_lto *tt, FILE *out) > fprintf (out, " Base %i:", (int)i); > print_generic_expr (dump_file, n->base); > fprintf (out, " (alias set %i)\n", > - n->base ? get_alias_set (n->base) : 0); > + n->base ? get_deref_alias_set (n->base) : 0); > if (n->every_ref) > { > fprintf (out, " Every ref\n"); > @@ -341,7 +341,7 @@ dump_lto_records (modref_records_lto *tt, FILE *out) > fprintf (out, " Ref %i:", (int)j); > print_generic_expr (dump_file, r->ref); > fprintf (out, " (alias set %i)\n", > - r->ref ? get_alias_set (r->ref) : 0); > + r->ref ? get_deref_alias_set (r->ref) : 0); > if (r->every_access) > { > fprintf (out, " Every access\n"); > @@ -478,48 +478,18 @@ record_access (modref_records *tt, ao_ref *ref) > static void > record_access_lto (modref_records_lto *tt, ao_ref *ref) > { > - /* get_alias_set sometimes use different type to compute the alias set > - than TREE_TYPE (base). Do same adjustments. */ > tree base_type = NULL_TREE, ref_type = NULL_TREE; > if (flag_strict_aliasing) > { > - tree base; > - > - base = ref->ref; > - while (handled_component_p (base)) > - base = TREE_OPERAND (base, 0); > - > - base_type = reference_alias_ptr_type_1 (&base); > - > - if (!base_type) > - base_type = TREE_TYPE (base); > - else > - base_type = TYPE_REF_CAN_ALIAS_ALL (base_type) > - ? NULL_TREE : TREE_TYPE (base_type); > - > - tree ref_expr = ref->ref; > - ref_type = reference_alias_ptr_type_1 (&ref_expr); > - > - if (!ref_type) > - ref_type = TREE_TYPE (ref_expr); > - else > - ref_type = TYPE_REF_CAN_ALIAS_ALL (ref_type) > - ? NULL_TREE : TREE_TYPE (ref_type); > - > - /* Sanity check that we are in sync with what get_alias_set does. */ > - gcc_checking_assert ((!base_type && !ao_ref_base_alias_set (ref)) > - || get_alias_set (base_type) > - == ao_ref_base_alias_set (ref)); > - gcc_checking_assert ((!ref_type && !ao_ref_alias_set (ref)) > - || get_alias_set (ref_type) > - == ao_ref_alias_set (ref)); > + base_type = ao_ref_base_alias_ptr_type (ref); > + ref_type = ao_ref_alias_ptr_type (ref); > > /* Do not bother to record types that have no meaningful alias set. > Also skip variably modified types since these go to local streams. */ > - if (base_type && (!get_alias_set (base_type) > + if (base_type && (!get_deref_alias_set (base_type) > || variably_modified_type_p (base_type, NULL_TREE))) > base_type = NULL_TREE; > - if (ref_type && (!get_alias_set (ref_type) > + if (ref_type && (!get_deref_alias_set (ref_type) > || variably_modified_type_p (ref_type, NULL_TREE))) > ref_type = NULL_TREE; > } > @@ -529,10 +499,10 @@ record_access_lto (modref_records_lto *tt, ao_ref *ref) > fprintf (dump_file, " - Recording base type:"); > print_generic_expr (dump_file, base_type); > fprintf (dump_file, " (alias set %i) ref type:", > - base_type ? get_alias_set (base_type) : 0); > + base_type ? get_deref_alias_set (base_type) : 0); > print_generic_expr (dump_file, ref_type); > fprintf (dump_file, " (alias set %i) parm:%i\n", > - ref_type ? get_alias_set (ref_type) : 0, > + ref_type ? get_deref_alias_set (ref_type) : 0, > a.parm_index); > } > > @@ -1477,7 +1447,7 @@ read_modref_records (lto_input_block *ib, struct > data_in *data_in, > something obviously unnecessary. Do not glob types by alias sets; > it is not 100% clear that ltrans types will get merged same way. > Types may get refined based on ODR type conflicts. */ > - if (base_tree && !get_alias_set (base_tree)) > + if (base_tree && !get_deref_alias_set (base_tree)) > { > if (dump_file) > { > @@ -1490,7 +1460,7 @@ read_modref_records (lto_input_block *ib, struct > data_in *data_in, > > if (nolto_ret) > nolto_base_node = (*nolto_ret)->insert_base (base_tree > - ? get_alias_set (base_tree) > + ? get_deref_alias_set > (base_tree) > : 0); > if (lto_ret) > lto_base_node = (*lto_ret)->insert_base (base_tree); > @@ -1509,7 +1479,7 @@ read_modref_records (lto_input_block *ib, struct > data_in *data_in, > { > tree ref_tree = stream_read_tree (ib, data_in); > > - if (ref_tree && !get_alias_set (ref_tree)) > + if (ref_tree && !get_deref_alias_set (ref_tree)) > { > if (dump_file) > { > @@ -1526,7 +1496,7 @@ read_modref_records (lto_input_block *ib, struct > data_in *data_in, > if (nolto_base_node) > nolto_ref_node > = nolto_base_node->insert_ref (ref_tree > - ? get_alias_set (ref_tree) : 0, > + ? get_deref_alias_set (ref_tree) : > 0, > max_refs); > if (lto_base_node) > lto_ref_node = lto_base_node->insert_ref (ref_tree, max_refs); > diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c > index e64011d04df..b4719825167 100644 > --- a/gcc/tree-ssa-alias.c > +++ b/gcc/tree-ssa-alias.c > @@ -739,6 +739,38 @@ ao_ref_alias_set (ao_ref *ref) > return ref->ref_alias_set; > } > > +/* Returns a type satisfying > + get_deref_alias_set (type) == ao_ref_base_alias_set (REF). */ > + > +tree > +ao_ref_base_alias_ptr_type (ao_ref *ref) > +{ > + tree base_ref; > + > + if (!ref->ref) > + return NULL_TREE; > + base_ref = ref->ref; > + while (handled_component_p (base_ref)) > + base_ref = TREE_OPERAND (base_ref, 0); > + tree ret = reference_alias_ptr_type (base_ref); > + gcc_checking_assert (get_deref_alias_set (ret) == ao_ref_base_alias_set > (ref)); > + return ret; > +} > + > +/* Returns a type satisfying > + get_deref_alias_set (type) == ao_ref_alias_set (REF). */ > + > +tree > +ao_ref_alias_ptr_type (ao_ref *ref) > +{ > + if (!ref->ref) > + return NULL_TREE; > + tree ret = reference_alias_ptr_type (ref->ref); > + gcc_checking_assert (get_deref_alias_set (ret) == ao_ref_alias_set (ref)); > + return ret; > +} > + > + > /* Init an alias-oracle reference representation from a gimple pointer > PTR a range specified by OFFSET, SIZE and MAX_SIZE under the assumption > that RANGE_KNOWN is set. > diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h > index 1561ead2941..830ac1bf84d 100644 > --- a/gcc/tree-ssa-alias.h > +++ b/gcc/tree-ssa-alias.h > @@ -114,6 +114,8 @@ extern void ao_ref_init_from_ptr_and_size (ao_ref *, > tree, tree); > extern tree ao_ref_base (ao_ref *); > extern alias_set_type ao_ref_alias_set (ao_ref *); > extern alias_set_type ao_ref_base_alias_set (ao_ref *); > +extern tree ao_ref_alias_ptr_type (ao_ref *); > +extern tree ao_ref_base_alias_ptr_type (ao_ref *); > extern bool ptr_deref_may_alias_global_p (tree); > extern bool ptr_derefs_may_alias_p (tree, tree); > extern bool ptrs_compare_unequal (tree, tree); > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imend