* Make alias sets of ODR types more precise
@ 2019-07-16 9:07 Jan Hubicka
2019-07-17 10:54 ` Richard Biener
0 siblings, 1 reply; 2+ messages in thread
From: Jan Hubicka @ 2019-07-16 9:07 UTC (permalink / raw)
To: gcc-patches, rguenther
Hi,
this is the hunk we omitted from the original patch enabling TBAA for
ODR types. Currently record_component_aliases record all pointers as
void *. This is because canonical type merging handles them this way
and thus it may merge for example
strut a { int *ptr;};
and
struct b { short *ptr;};
into one canonical type. The alias set of that canonical type then must
conflict with both int * and short * which we do by globing it to void *
which conflict with everything.
For ODR types where we do canonical types based on their name we however
assign differnt TYPE_CANONICAL to each of them. Thanks to this we can
make alias set to contain int * or short * respectively.
Bootstrapped/regtested x86_64-linux, OK?
Honza
* alias.c (record_component_aliases): Do not simplify pointed-to
types of ODR types
* testsuite/g++.dg/lto/alias-4_0.C
Index: alias.c
===================================================================
--- alias.c (revision 273478)
+++ alias.c (working copy)
@@ -1202,47 +1202,52 @@ record_component_aliases (tree type)
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
- for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field))
- if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field))
- {
- /* LTO type merging does not make any difference between
- component pointer types. We may have
-
- struct foo {int *a;};
-
- as TYPE_CANONICAL of
-
- struct bar {float *a;};
-
- Because accesses to int * and float * do not alias, we would get
- false negative when accessing the same memory location by
- float ** and bar *. We thus record the canonical type as:
-
- struct {void *a;};
-
- void * is special cased and works as a universal pointer type.
- Accesses to it conflicts with accesses to any other pointer
- type. */
- tree t = TREE_TYPE (field);
- if (in_lto_p)
- {
- /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
- element type and that type has to be normalized to void *,
- too, in the case it is a pointer. */
- while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
- {
- gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
- t = TREE_TYPE (t);
- }
- if (POINTER_TYPE_P (t))
- t = ptr_type_node;
- else if (flag_checking)
- gcc_checking_assert (get_alias_set (t)
- == get_alias_set (TREE_TYPE (field)));
- }
-
- record_alias_subset (superset, get_alias_set (t));
- }
+ {
+ /* LTO non-ODR type merging does not make any difference between
+ component pointer types. We may have
+
+ struct foo {int *a;};
+
+ as TYPE_CANONICAL of
+
+ struct bar {float *a;};
+
+ Because accesses to int * and float * do not alias, we would get
+ false negative when accessing the same memory location by
+ float ** and bar *. We thus record the canonical type as:
+
+ struct {void *a;};
+
+ void * is special cased and works as a universal pointer type.
+ Accesses to it conflicts with accesses to any other pointer
+ type. */
+ bool void_pointers = in_lto_p
+ && (!odr_type_p (type)
+ || !odr_based_tbaa_p (type));
+ for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field))
+ {
+ tree t = TREE_TYPE (field);
+ if (void_pointers)
+ {
+ /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
+ element type and that type has to be normalized to void *,
+ too, in the case it is a pointer. */
+ while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
+ {
+ gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
+ t = TREE_TYPE (t);
+ }
+ if (POINTER_TYPE_P (t))
+ t = ptr_type_node;
+ else if (flag_checking)
+ gcc_checking_assert (get_alias_set (t)
+ == get_alias_set (TREE_TYPE (field)));
+ }
+
+ record_alias_subset (superset, get_alias_set (t));
+ }
+ }
break;
case COMPLEX_TYPE:
Index: testsuite/g++.dg/lto/alias-4_0.C
===================================================================
--- testsuite/g++.dg/lto/alias-4_0.C (nonexistent)
+++ testsuite/g++.dg/lto/alias-4_0.C (working copy)
@@ -0,0 +1,31 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -O3 -flto -fno-early-inlining } } } */
+__attribute__ ((used))
+short *ptr_init, **ptr=&ptr_init;
+
+__attribute__ ((used))
+struct a {
+ int *aptr;
+} a, *aptr=&a;
+
+void
+write_ptr ()
+{
+ *aptr = a;
+}
+
+__attribute__ ((used))
+void
+test ()
+{
+ *ptr = (short int *)0;
+ write_ptr ();
+ if (!__builtin_constant_p (*ptr == (void *)0))
+ __builtin_abort ();
+}
+int
+main()
+{
+ test ();
+ return 0;
+}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Make alias sets of ODR types more precise
2019-07-16 9:07 Make alias sets of ODR types more precise Jan Hubicka
@ 2019-07-17 10:54 ` Richard Biener
0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2019-07-17 10:54 UTC (permalink / raw)
To: Jan Hubicka; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 5359 bytes --]
On Tue, 16 Jul 2019, Jan Hubicka wrote:
> Hi,
> this is the hunk we omitted from the original patch enabling TBAA for
> ODR types. Currently record_component_aliases record all pointers as
> void *. This is because canonical type merging handles them this way
> and thus it may merge for example
>
> strut a { int *ptr;};
>
> and
>
> struct b { short *ptr;};
>
> into one canonical type. The alias set of that canonical type then must
> conflict with both int * and short * which we do by globing it to void *
> which conflict with everything.
>
> For ODR types where we do canonical types based on their name we however
> assign differnt TYPE_CANONICAL to each of them. Thanks to this we can
> make alias set to contain int * or short * respectively.
>
>
> Bootstrapped/regtested x86_64-linux, OK?
OK.
Richard.
> Honza
> * alias.c (record_component_aliases): Do not simplify pointed-to
> types of ODR types
> * testsuite/g++.dg/lto/alias-4_0.C
> Index: alias.c
> ===================================================================
> --- alias.c (revision 273478)
> +++ alias.c (working copy)
> @@ -1202,47 +1202,52 @@ record_component_aliases (tree type)
> case RECORD_TYPE:
> case UNION_TYPE:
> case QUAL_UNION_TYPE:
> - for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field))
> - if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field))
> - {
> - /* LTO type merging does not make any difference between
> - component pointer types. We may have
> -
> - struct foo {int *a;};
> -
> - as TYPE_CANONICAL of
> -
> - struct bar {float *a;};
> -
> - Because accesses to int * and float * do not alias, we would get
> - false negative when accessing the same memory location by
> - float ** and bar *. We thus record the canonical type as:
> -
> - struct {void *a;};
> -
> - void * is special cased and works as a universal pointer type.
> - Accesses to it conflicts with accesses to any other pointer
> - type. */
> - tree t = TREE_TYPE (field);
> - if (in_lto_p)
> - {
> - /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
> - element type and that type has to be normalized to void *,
> - too, in the case it is a pointer. */
> - while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
> - {
> - gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
> - t = TREE_TYPE (t);
> - }
> - if (POINTER_TYPE_P (t))
> - t = ptr_type_node;
> - else if (flag_checking)
> - gcc_checking_assert (get_alias_set (t)
> - == get_alias_set (TREE_TYPE (field)));
> - }
> -
> - record_alias_subset (superset, get_alias_set (t));
> - }
> + {
> + /* LTO non-ODR type merging does not make any difference between
> + component pointer types. We may have
> +
> + struct foo {int *a;};
> +
> + as TYPE_CANONICAL of
> +
> + struct bar {float *a;};
> +
> + Because accesses to int * and float * do not alias, we would get
> + false negative when accessing the same memory location by
> + float ** and bar *. We thus record the canonical type as:
> +
> + struct {void *a;};
> +
> + void * is special cased and works as a universal pointer type.
> + Accesses to it conflicts with accesses to any other pointer
> + type. */
> + bool void_pointers = in_lto_p
> + && (!odr_type_p (type)
> + || !odr_based_tbaa_p (type));
> + for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field))
> + if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field))
> + {
> + tree t = TREE_TYPE (field);
> + if (void_pointers)
> + {
> + /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
> + element type and that type has to be normalized to void *,
> + too, in the case it is a pointer. */
> + while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
> + {
> + gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
> + t = TREE_TYPE (t);
> + }
> + if (POINTER_TYPE_P (t))
> + t = ptr_type_node;
> + else if (flag_checking)
> + gcc_checking_assert (get_alias_set (t)
> + == get_alias_set (TREE_TYPE (field)));
> + }
> +
> + record_alias_subset (superset, get_alias_set (t));
> + }
> + }
> break;
>
> case COMPLEX_TYPE:
>
> Index: testsuite/g++.dg/lto/alias-4_0.C
> ===================================================================
> --- testsuite/g++.dg/lto/alias-4_0.C (nonexistent)
> +++ testsuite/g++.dg/lto/alias-4_0.C (working copy)
> @@ -0,0 +1,31 @@
> +/* { dg-lto-do run } */
> +/* { dg-lto-options { { -O3 -flto -fno-early-inlining } } } */
> +__attribute__ ((used))
> +short *ptr_init, **ptr=&ptr_init;
> +
> +__attribute__ ((used))
> +struct a {
> + int *aptr;
> +} a, *aptr=&a;
> +
> +void
> +write_ptr ()
> +{
> + *aptr = a;
> +}
> +
> +__attribute__ ((used))
> +void
> +test ()
> +{
> + *ptr = (short int *)0;
> + write_ptr ();
> + if (!__builtin_constant_p (*ptr == (void *)0))
> + __builtin_abort ();
> +}
> +int
> +main()
> +{
> + test ();
> + return 0;
> +}
>
--
Richard Biener <rguenther@suse.de>
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG NÌrnberg)
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-07-17 10:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-16 9:07 Make alias sets of ODR types more precise Jan Hubicka
2019-07-17 10:54 ` Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).