From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id D85BB385780E for ; Mon, 9 Nov 2020 10:29:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org D85BB385780E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: sourceware.org; spf=none smtp.mailfrom=hubicka@kam.mff.cuni.cz Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 691872811D2; Mon, 9 Nov 2020 11:29:46 +0100 (CET) Date: Mon, 9 Nov 2020 11:29:46 +0100 From: Jan Hubicka To: Richard Biener Cc: gcc@gcc.gnu.org Subject: Re: Definition of EAF_NOESCAPE and fnspec strings Message-ID: <20201109102946.GA83507@kam.mff.cuni.cz> References: <20201108124711.GD65107@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) X-Spam-Status: No, score=-9.5 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=no autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Nov 2020 10:29:49 -0000 > > But it also means that some of our FNSPECs are wrong now. I wonder if we can > > split this porperty to two different flags like EAF_NOEASCAPE and > > EAF_INDIRECT_NOESCAPE? > > Note that EAF_NOESCAPE allows "escaping" to the return value (see > handle_rhs_call). I guess for simplicity we could allow escaping I see, missed that! > of not escaped but USED params to other written to params. I think > we also don't handle "escaping" of a parameter indirectly to itself, thus > > int i; > int *p = &i; > int **q = &p; > foo (&q); > if (*q != i) > abort (); > > and > > foo (int ***p) > { > *p = **p; > } > > or so with foos param EAF_NOESCAPE (but not EAF_DIRECT). > > Splitting up EAF_NOESCAPE makes it quite difficult to understand. > Arguably explicit handling of memcpy and friends _does_ pay off > for points-to analysis since I'd say modelling all possible and useful > things in fnspec would make it a monster ... you'd basically want > to have a way to specify additional constraints in the fnspec itself, > like *1 = *2, but then also distinguish points-to effects from > may-alias ones. Yep, i am not arguing for eliminating special case of memcpy (because we have the additional info that it only copies pointers from *src to *dest). However I find current definition of EAF_NOESCAPE bit hard to handle in modref, since naturally it is quite reliable to track all uses of ssa name that correspond to parameters, but it is harder to track where values read from pointed-to memory can eventually go. What I do is to walk all uses of SSA_NAME that correspond to parameter and try to unerstand it. If it is one of 1) memory load via derefence of name 2) memory store where name is base of LHS 3) memory store where name is rhs 4) name is passed as a value to function 5) dereferenced value from name is passed to funtion 6) used as value normal gimple expression 7) used in return (as RHS or base of memory dereference address) 8) it is used only in reference but not as base (as array index or so) Then I merge in (and) flags I determine as follow: For 1) clear EAF_USED and recurse to LHS name. Based on its flags I decide on: - EAF_DIRECT (if LHS has EAF_UNUSED), - EAF_NOCLOBBER (if LHS has EAF_NOCLOBBER) - EAF_NOESCAPE (if LHS has EAF_NOESCAPE). For 2) I clear EAF_NOCLOBBER and EAF_UNUSED flag For 3) I give up (clear all flags) since I would need to track where the memory is going. For 4) I determine flag of function parameter For 5) I need to do same handling as 1) where flag of "loaded value" is flag of the function For 6) I determine flags of LHS and merge them in For 7) I clear NOESCAPE if rhs is name itself and UNUSED + NOESCAPE if rhs is derefernece from name. For 8) I do nothing. Here the names are non-pointers that I track because of earlier dereference. So I think 7) can be relaxed. Main problem is hoever that we often see 1) and then 3) or 7) on LHS that makes us punt very often. The fact that pointer directly does not escape but pointed to memory can seems still very useful since one does not need to add *ptr to points-to sets. But I will try relaxing 7). If we allow values escaping to other parameters and itself, I think I can relax 3) if base of the store is default def of PARM_DECL. > > I wonder if we should teach the GIMPLE FE to parse 'fn spec' > so we can write unit tests for the attribute ... or maybe simply > add this to the __GIMPLE spec string. May be nice and also describe carefully that NOESCAPE and NOCLOBBER also reffers to indirect references. Current description "Nonzero if the argument does not escape." reads to me that it is about ptr itself, not about *ptr and also it does not speak of the escaping to return value etc. Honza