From patchwork Tue Jul 16 08:56:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 1132536 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-505125-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="K4pKepo0"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45nvQz2qJmz9s7T for ; Tue, 16 Jul 2019 18:56:58 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=R4MRNfybjcJJezdLuO+uLqQaBg4yMhnuC4vAhriE14dj6Mngnt0r2 UKlTrQ6v+NFXIibXrgeD6CDoCQ+b2TsJDgo9rkl4lIyeXowwcJv9J5j7blkHuAdq 2o3Fnt6UubBL+Eu0zE8RSgZQhS/ZxE24fzDgfbGdoo943ju8gNymuI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=PfByVQG/R8f47v5nBmPdj8DR98c=; b=K4pKepo0PNUZfak32AmB CvyYsKPYrjoco3WNliCTZq3EgGUVAhCa6UXeWMp3uh3y2l9F5SHTmQegw6u7ae1Y 16wh4LQ48Zi0R/o0Ffe9AOvz70EbT5U+2aonhGuFRAV7++jacw4ICuspIsUTojvI pZiNd++QuJ3Lcr/dnYO40oQ= Received: (qmail 128686 invoked by alias); 16 Jul 2019 08:56:50 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 128633 invoked by uid 89); 16 Jul 2019 08:56:48 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-9.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS autolearn=ham version=3.3.1 spammy=strut X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 16 Jul 2019 08:56:46 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 0B2432825BA; Tue, 16 Jul 2019 10:56:44 +0200 (CEST) Date: Tue, 16 Jul 2019 10:56:44 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org, rguenther@suse.de Subject: Make alias sets of ODR types more precise Message-ID: <20190716085643.wnqot6j7dkcp2mva@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20170113 (1.7.2) 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; +}