From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 126522 invoked by alias); 9 Jul 2019 13:37:34 -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 126513 invoked by uid 89); 9 Jul 2019 13:37:34 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-10.8 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_2,GIT_PATCH_3,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; Tue, 09 Jul 2019 13:37:32 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 79CDFACB7; Tue, 9 Jul 2019 13:37:30 +0000 (UTC) Date: Tue, 09 Jul 2019 13:41:00 -0000 From: Richard Biener To: Jan Hubicka cc: gcc-patches@gcc.gnu.org, d@dcepelik.cz Subject: Re: Make nonoverlapping_component_refs work with duplicated main variants In-Reply-To: <20190709133008.tph5qhzvwis6ciz3@kam.mff.cuni.cz> Message-ID: References: <20190708072649.vqd5u6jxsz5ybtt7@kam.mff.cuni.cz> <20190709114917.qva4nb2h7j5vzdur@kam.mff.cuni.cz> <20190709133008.tph5qhzvwis6ciz3@kam.mff.cuni.cz> User-Agent: Alpine 2.20 (LSU 67 2015-01-07) MIME-Version: 1.0 Content-Type: multipart/mixed; BOUNDARY="-1609908220-2133073544-1562679450=:2976" X-SW-Source: 2019-07/txt/msg00705.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-2133073544-1562679450=:2976 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8BIT Content-length: 11623 On Tue, 9 Jul 2019, Jan Hubicka wrote: > Hi, > this is updated variant I am testing. > It documents better how function works and streamlines the checks. > > OK assuming it passes the tests? > > Honza > > Index: tree-ssa-alias.c > =================================================================== > --- tree-ssa-alias.c (revision 273193) > +++ tree-ssa-alias.c (working copy) > @@ -1128,6 +1128,91 @@ aliasing_component_refs_p (tree ref1, > return false; > } > > +/* FIELD1 and FIELD2 are two fields of component refs. We assume > + that bases of both component refs are > + (*) are either equivalent or they point to different objects. are either equivalent(*) or not overlapping > + We do not assume that FIELD1 and FIELD2 are of same type. that the containers of FIELD1 and FIELD2 are of the same type? > + > + Return 0 if FIELD1 and FIELD2 satisfy (*). > + This is the case when their offsets are the same. Hmm, so when the offsets are the same then the bases are equivalent? I think you want to say Return 0 if in case the component refs satisfy (*) we know FIELD1 and FIELD2 are overlapping exactly. > + Return 1 if FIELD1 and FIELD2 are non-overlapping. > + > + Return -1 otherwise. > + > + Main difference between 0 and -1 is to let > + nonoverlapping_component_refs_since_match_p discover the semnatically semantically otherwise looks good now. Thanks, Richard. > + equivalent part of the access path. > + > + Note that this function is used even with -fno-strict-aliasing > + and makes use of no TBAA assumptions. */ > + > +static int > +nonoverlapping_component_refs_p_1 (const_tree field1, const_tree field2) > +{ > + /* If both fields are of the same type, we could save hard work of > + comparing offsets. */ > + tree type1 = DECL_CONTEXT (field1); > + tree type2 = DECL_CONTEXT (field2); > + > + if (DECL_BIT_FIELD_REPRESENTATIVE (field1)) > + field1 = DECL_BIT_FIELD_REPRESENTATIVE (field1); > + if (DECL_BIT_FIELD_REPRESENTATIVE (field2)) > + field2 = DECL_BIT_FIELD_REPRESENTATIVE (field1); > + > + /* ??? Bitfields can overlap at RTL level so punt on them. > + FIXME: RTL expansion should be fixed by adjusting the access path > + when producing MEM_ATTRs for MEMs which are wider than > + the bitfields similarly as done in set_mem_attrs_minus_bitpos. */ > + if (DECL_BIT_FIELD (field1) && DECL_BIT_FIELD (field2)) > + return -1; > + > + /* Assume that different FIELD_DECLs never overlap within a RECORD_TYPE. */ > + if (type1 == type2 && TREE_CODE (type1) == RECORD_TYPE) > + return field1 != field2; > + > + /* In common case the offsets and bit offsets will be the same. > + However if frontends do not agree on the alignment, they may be > + different even if they actually represent same address. > + Try the common case first and if that fails calcualte the > + actual bit offset. */ > + if (tree_int_cst_equal (DECL_FIELD_OFFSET (field1), > + DECL_FIELD_OFFSET (field2)) > + && tree_int_cst_equal (DECL_FIELD_BIT_OFFSET (field1), > + DECL_FIELD_BIT_OFFSET (field2))) > + return 0; > + > + /* Note that it may be possible to use component_ref_field_offset > + which would provide offsets as trees. However constructing and folding > + trees is expensive and does not seem to be worth the compile time > + cost. */ > + > + poly_uint64 offset1, offset2; > + poly_uint64 bit_offset1, bit_offset2; > + > + if (poly_int_tree_p (DECL_FIELD_OFFSET (field1), &offset1) > + && poly_int_tree_p (DECL_FIELD_OFFSET (field2), &offset2) > + && poly_int_tree_p (DECL_FIELD_BIT_OFFSET (field1), &bit_offset1) > + && poly_int_tree_p (DECL_FIELD_BIT_OFFSET (field2), &bit_offset2)) > + { > + offset1 = (offset1 << LOG2_BITS_PER_UNIT) + bit_offset1; > + offset2 = (offset2 << LOG2_BITS_PER_UNIT) + bit_offset2; > + > + if (known_eq (offset1, offset2)) > + return 0; > + > + poly_uint64 size1, size2; > + > + if (poly_int_tree_p (DECL_SIZE (field1), &size1) > + && poly_int_tree_p (DECL_SIZE (field2), &size2) > + && !ranges_maybe_overlap_p (offset1, size1, offset2, size2)) > + return 1; > + } > + /* Resort to slower overlap checking by looking for matching types in > + the middle of access path. */ > + return -1; > +} > + > /* Try to disambiguate REF1 and REF2 under the assumption that MATCH1 and > MATCH2 either point to the same address or are disjoint. > MATCH1 and MATCH2 are assumed to be ref in the access path of REF1 and REF2 > @@ -1224,6 +1309,7 @@ nonoverlapping_component_refs_since_matc > case the return value will precisely be false. */ > while (true) > { > + bool seen_noncomponent_ref_p = false; > do > { > if (component_refs1.is_empty ()) > @@ -1233,6 +1319,8 @@ nonoverlapping_component_refs_since_matc > return 0; > } > ref1 = component_refs1.pop (); > + if (TREE_CODE (ref1) != COMPONENT_REF) > + seen_noncomponent_ref_p = true; > } > while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref1, 0)))); > > @@ -1245,17 +1333,15 @@ nonoverlapping_component_refs_since_matc > return 0; > } > ref2 = component_refs2.pop (); > + if (TREE_CODE (ref2) != COMPONENT_REF) > + seen_noncomponent_ref_p = true; > } > while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref2, 0)))); > > - /* Beware of BIT_FIELD_REF. */ > - if (TREE_CODE (ref1) != COMPONENT_REF > - || TREE_CODE (ref2) != COMPONENT_REF) > - { > - ++alias_stats > - .nonoverlapping_component_refs_since_match_p_may_alias; > - return -1; > - } > + /* BIT_FIELD_REF and VIEW_CONVERT_EXPR are taken off the vectors > + earlier. */ > + gcc_checking_assert (TREE_CODE (ref1) == COMPONENT_REF > + && TREE_CODE (ref2) == COMPONENT_REF); > > tree field1 = TREE_OPERAND (ref1, 1); > tree field2 = TREE_OPERAND (ref2, 1); > @@ -1266,33 +1352,27 @@ nonoverlapping_component_refs_since_matc > tree type1 = DECL_CONTEXT (field1); > tree type2 = DECL_CONTEXT (field2); > > - /* We cannot disambiguate fields in a union or qualified union. */ > - if (type1 != type2 || TREE_CODE (type1) != RECORD_TYPE) > + /* If we skipped array refs on type of different sizes, we can > + no longer be sure that there are not partial overlaps. */ > + if (seen_noncomponent_ref_p > + && !operand_equal_p (TYPE_SIZE (type1), TYPE_SIZE (type2), 0)) > { > - ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias; > + ++alias_stats > + .nonoverlapping_component_refs_since_match_p_may_alias; > return -1; > } > > - if (field1 != field2) > + int cmp = nonoverlapping_component_refs_p_1 (field1, field2); > + if (cmp == -1) > { > - /* A field and its representative need to be considered the > - same. */ > - if (DECL_BIT_FIELD_REPRESENTATIVE (field1) == field2 > - || DECL_BIT_FIELD_REPRESENTATIVE (field2) == field1) > - { > - ++alias_stats > - .nonoverlapping_component_refs_since_match_p_must_overlap; > - return 0; > - } > - /* Different fields of the same record type cannot overlap. > - ??? Bitfields can overlap at RTL level so punt on them. */ > - if (DECL_BIT_FIELD (field1) && DECL_BIT_FIELD (field2)) > - { > - ++alias_stats > - .nonoverlapping_component_refs_since_match_p_must_overlap; > - return 0; > - } > - ++alias_stats.nonoverlapping_component_refs_since_match_p_no_alias; > + ++alias_stats > + .nonoverlapping_component_refs_since_match_p_may_alias; > + return -1; > + } > + else if (cmp == 1) > + { > + ++alias_stats > + .nonoverlapping_component_refs_since_match_p_no_alias; > return 1; > } > } > @@ -1301,6 +1381,24 @@ nonoverlapping_component_refs_since_matc > return 0; > } > > +/* Return TYPE_UID which can be used to match record types we consider > + same for TBAA purposes. */ > + > +static inline int > +ncr_type_uid (const_tree field) > +{ > + /* ??? We cannot simply use the type of operand #0 of the refs here > + as the Fortran compiler smuggles type punning into COMPONENT_REFs > + for common blocks instead of using unions like everyone else. */ > + tree type = DECL_FIELD_CONTEXT (field); > + /* With LTO types considered same_type_for_tbaa_p > + from different translation unit may not have same > + main variant. They however have same TYPE_CANONICAL. */ > + if (TYPE_CANONICAL (type)) > + return TYPE_UID (TYPE_CANONICAL (type)); > + return TYPE_UID (type); > +} > + > /* qsort compare function to sort FIELD_DECLs after their > DECL_FIELD_CONTEXT TYPE_UID. */ > > @@ -1309,8 +1407,9 @@ ncr_compar (const void *field1_, const v > { > const_tree field1 = *(const_tree *) const_cast (field1_); > const_tree field2 = *(const_tree *) const_cast (field2_); > - unsigned int uid1 = TYPE_UID (DECL_FIELD_CONTEXT (field1)); > - unsigned int uid2 = TYPE_UID (DECL_FIELD_CONTEXT (field2)); > + unsigned int uid1 = ncr_type_uid (field1); > + unsigned int uid2 = ncr_type_uid (field2); > + > if (uid1 < uid2) > return -1; > else if (uid1 > uid2) > @@ -1377,10 +1476,9 @@ nonoverlapping_component_refs_p (const_t > if (fieldsx.length () == 1 > && fieldsy.length () == 1) > { > - if ((DECL_FIELD_CONTEXT (fieldsx[0]) > - == DECL_FIELD_CONTEXT (fieldsy[0])) > - && fieldsx[0] != fieldsy[0] > - && !(DECL_BIT_FIELD (fieldsx[0]) && DECL_BIT_FIELD (fieldsy[0]))) > + if (same_type_for_tbaa (DECL_FIELD_CONTEXT (fieldsx[0]), > + DECL_FIELD_CONTEXT (fieldsy[0])) == 1 > + && nonoverlapping_component_refs_p_1 (fieldsx[0], fieldsy[0]) == 1) > { > ++alias_stats.nonoverlapping_component_refs_p_no_alias; > return true; > @@ -1413,31 +1511,18 @@ nonoverlapping_component_refs_p (const_t > { > const_tree fieldx = fieldsx[i]; > const_tree fieldy = fieldsy[j]; > - tree typex = DECL_FIELD_CONTEXT (fieldx); > - tree typey = DECL_FIELD_CONTEXT (fieldy); > - if (typex == typey) > - { > - /* We're left with accessing different fields of a structure, > - no possible overlap. */ > - if (fieldx != fieldy) > - { > - /* A field and its representative need to be considered the > - same. */ > - if (DECL_BIT_FIELD_REPRESENTATIVE (fieldx) == fieldy > - || DECL_BIT_FIELD_REPRESENTATIVE (fieldy) == fieldx) > - ; > - /* Different fields of the same record type cannot overlap. > - ??? Bitfields can overlap at RTL level so punt on them. */ > - else if (DECL_BIT_FIELD (fieldx) && DECL_BIT_FIELD (fieldy)) > - ; > - else > - { > - ++alias_stats.nonoverlapping_component_refs_p_no_alias; > - return true; > - } > - } > + > + /* We're left with accessing different fields of a structure, > + no possible overlap. */ > + if (same_type_for_tbaa (DECL_FIELD_CONTEXT (fieldx), > + DECL_FIELD_CONTEXT (fieldy)) == 1 > + && nonoverlapping_component_refs_p_1 (fieldx, fieldy) == 1) > + { > + ++alias_stats.nonoverlapping_component_refs_p_no_alias; > + return true; > } > - if (TYPE_UID (typex) < TYPE_UID (typey)) > + > + if (ncr_type_uid (fieldx) < ncr_type_uid (fieldy)) > { > i++; > if (i == fieldsx.length ()) > -- Richard Biener SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG Nürnberg) ---1609908220-2133073544-1562679450=:2976--