From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 86111 invoked by alias); 17 Jul 2019 10:39:42 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 86102 invoked by uid 89); 17 Jul 2019 10:39:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-10.4 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_2,GIT_PATCH_3,KAM_ASCII_DIVIDERS,SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mx1.suse.de Received: from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 17 Jul 2019 10:39:40 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 00529AF05; Wed, 17 Jul 2019 10:39:37 +0000 (UTC) Date: Wed, 17 Jul 2019 10:54:00 -0000 From: Richard Biener To: Jan Hubicka cc: gcc-patches@gcc.gnu.org Subject: Re: Make alias sets of ODR types more precise In-Reply-To: <20190716085643.wnqot6j7dkcp2mva@kam.mff.cuni.cz> Message-ID: References: <20190716085643.wnqot6j7dkcp2mva@kam.mff.cuni.cz> User-Agent: Alpine 2.20 (LSU 67 2015-01-07) MIME-Version: 1.0 Content-Type: multipart/mixed; BOUNDARY="-1609908220-611537464-1563359977=:2976" X-SW-Source: 2019-07/txt/msg01165.txt.bz2 This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. ---1609908220-611537464-1563359977=:2976 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8BIT Content-length: 5357 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 SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG Nürnberg) ---1609908220-611537464-1563359977=:2976--