From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 122766 invoked by alias); 21 Nov 2019 13:16:51 -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 122750 invoked by uid 89); 21 Nov 2019 13:16:51 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-8.9 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.1 spammy=05, 0.5, H*i:sk:hmxaCx8, H*f:sk:Vs0Rnbp X-HELO: esa2.mentor.iphmx.com Received: from esa2.mentor.iphmx.com (HELO esa2.mentor.iphmx.com) (68.232.141.98) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 21 Nov 2019 13:16:50 +0000 IronPort-SDR: 2os3YLbOKbuIgu0+69WkRCx935ZixoK1hckrTM6YkrKOR9cV5rYSqsJohJYrqIy4AZtcye2b2H e2btksX3iq3O7g/r5CVCWPjlwcp9ByWEjB9H24itH1cpW8jqKrZq+x6Qq2Tr8ilA296bs5xsVx 8u57ptdbm/ye+4eAsutQM8cZjH1YMiHEenTV9yBOjfLfC4lbQVJCtaB6BBaP7md6c4RqV6LEVC 0TSin8Qpr/NwmTJ9pr4PpQEGIR3NRbQ5j/YzJs8WgmJnUbiwN9boHyOJgVSb0QIrKLdIIBVhj1 uIA= Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa2.mentor.iphmx.com with ESMTP; 21 Nov 2019 05:16:48 -0800 IronPort-SDR: 28uMSYEy6Or/1/XNCQ86rbyTz2cLUPKFfmzyBHJERhgi/BzBgrqS3GFbFDv43INdmhEL1IofPT ENAKkNOsW8TeSPBoDvExh11pZXJny18KZoHigeb1RVJIFLmxCmo9iiuYdX3l8OJElwEJWgODaX W60ZFbP9O19ybxm6igjXPAHYf+33zloTQ0QYmPN2mlXHNOuJPWD/UfQSdsIAlZo1j2O5vunGb3 ecozhx3/lz7m/QSTtLq0Cirt5sI0mMzHWDm1tgtzEmcuf32X1nYYlnTCA/8LuCdqdIEHlAvDrX +tQ= Subject: Re: [patch, fortran] Load scalar intent-in variables at the beginning of procedures To: Richard Biener , Tobias Burnus CC: =?UTF-8?Q?Thomas_K=c3=b6nig?= , Janne Blomqvist , Thomas Koenig , "fortran@gcc.gnu.org" , gcc-patches References: <48286910-ebbb-10e4-488b-8c96e505375c@tkoenig.net> <43b9fcf0-f457-90a7-c807-4aebc65cb045@tkoenig.net> <2981fd67-007e-7327-8208-27e8fd18d9db@netcologne.de> <4e68f250-1e41-ac7c-dc64-88f91cdf183e@tkoenig.net> <4ecba99c-f63a-628c-0778-d651503f7aa6@codesourcery.com> From: Tobias Burnus Message-ID: <64ac7298-7589-79dc-9ce8-8f801c247b55@codesourcery.com> Date: Thu, 21 Nov 2019 13:17:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 8bit Return-Path: tobias@codesourcery.com X-IsSubscribed: yes X-SW-Source: 2019-11/txt/msg02099.txt.bz2 Hi Richard, On 11/21/19 1:16 PM, Richard Biener wrote: > OK, so I found it, it's handled via SSA_NAME_POINTS_TO_READONLY_MEMORY > which is initialized during the rewrite into SSA form from the > information given by the "fn spec" attribute […] so when the frontend > sets "fn spec" from the intent it should already work. Which I can confirm for the following made-up example: real function foo(n) implicit none (type) integer, intent(in) :: n integer :: i foo = 0.5 if (n /= 0) return call bar() do i = 1, n foo = foo + sin(foo) end do end The optimized dump shows the following, i.e. GCC nicely optimizes both the loop and the 'sin' call away: foo (integer(kind=4) & restrict n) { integer(kind=4) _1; [local count: 241635843]: _1 = *n_9(D); if (_1 != 0) goto ; [51.12%] else goto ; [48.88%] [local count: 118111600]: bar (); [local count: 241635844]: return 5.0e-1; } I think this optimization permits some crucial optimizations. I have not fully followed the later versions of the patch whether they exploit some additional language semantics to permit optimizations even without intent(in), but the initial discussion started with intent(in). > But the examples I saw above didn't use INTENT(IN) for the scalar > parameters. I concur that a well-written program should make use of intent(in) where sensible. There are cases, which could be optimized likewise – but based on the case that the pointer address cannot escape instead of just assuming that the argument cannot change. – The question is how to convey this to the middle end. I wonder whether there is a 'fn attr' which can tell that the first argument of 'print_i' does not cause the address of 'i' escape. If so, one could mark all procedure arguments such – unless they have the pointer, target or asynchronous attribute or are coarrays. [Probably needs some fine tuning.] In this example, variable values do change, but only in a controlled way ('print_i' could change it, 'bar' cannot). The semantic is also mainly a property of the (local) variable (or dummy argument) declaration and not of the functions which are called – although, if 'i' has no target attribute, print_i's argument cannot have neither – hence, one could generated a function interface real function foo(i, y) implicit none (type) integer :: i real :: y foo = 0.0 call print_i(i) i = 5 call bar() ! < this prevents optimizing the sin(y) away if (i == 5) return foo = sin(y) end Fortran semantics implies that 'i' can only change after the 'i = 5' if: 'i' has the TARGET (or POINTER) attribute. Or it is possible if 'i' has the ASYNCHRONOUS or VOLATILE attribute – or it is a coarray (where a remote image can modify the local value). For asynchronous, it would be something like "call read_i(i); call wait()" which is structurally the same as above. TARGET: "An object without the TARGET attribute shall not have a pointer associated with it." VOLATILE: "may be referenced, defined, or become undefined, by means20not specified by the program" ASYNCHRONOUS: "An entity with the ASYNCHRONOUS attribute is a variable, and may be subject to asynchronous input/output or asynchronous communication." Tobias