Bug 92628 - Make use of TYPE_RESTRICT for function-call pointer-escape analysis – especially for Fortran
Summary: Make use of TYPE_RESTRICT for function-call pointer-escape analysis – especia...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: alias, missed-optimization
: 49733 (view as bug list)
Depends on:
Blocks: restrict
  Show dependency treegraph
 
Reported: 2019-11-22 10:05 UTC by Tobias Burnus
Modified: 2021-12-22 10:14 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-01-30 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2019-11-22 10:05:00 UTC
As discussed, TYPE_RESTRICT should also be used for of pointer-escape analysis.

In Fortran, assume the following program. When honoring the Fortran semantics – passed to the ME via the TYPE_RESTRICT for 'n' – the loop can be optimized away:

  subroutine test(n)  ! n is passed by reference
    integer :: n, i
    n = 0
    call do_something() ! ME assumes that callee might modify 'n'
    ! the following loop could be optimized way as still  n == 0
    do i = 1, n
      call bar()
    end do
  end subroutine
    
A full test case and a *patch* to actually *set* TYPE_RESTRICT in the Fortran FE can be found at https://gcc.gnu.org/ml/fortran/2019-11/msg00127.html

Some more discussion and references to the Fortran standard can be found at
https://gcc.gnu.org/ml/fortran/2019-11/msg00126.html

 * * *

A similar rule applies to other variables in Fortran (in principle also to static variables). Example - the same but not using a PARM_DECL:
[Will surely require changes to the FE and not only to the ME.]

subroutine foo()
    integer :: n, i ! Both local variables
    call my_print(n)  ! n passed by reference, regarded as pointer escape
    n = 0
    call bar() ! ME assumes that the callee might modify 'n'
    ! the following loop could be optimized way as  n == 0
    do i = 1, n
      call bar()
    end d
end

[The Fortran programs become nicer by providing an 'interface', i.e. an explicit function declaration (cf. test case in the link above). But in terms of the pointer-escape analysis, this has no effect.]

 * * *

Fortran standard wise

Within the language, a pointer escape is only possible by associating a pointer to a variable – which is only permitted for variables with POINTER or TARGET attribute.
This can be locally removed (e.g. passing a TARGET variable as argument to a function whose dummy argument declaration does not have it. Then, within that function one can assume no aliasing is done [restriction on the programmer].)

Additionally, ASYNCHRONOUS ("call start_do(var); … ; call wait()") (implies default ME behavior, i.e. pointer address escapes) and VOLATILE have an effect. – As well as concurrency (coarrays, asynchronous I/O, thread parallelization, e.g. via OpenMP or OpenACC).

For a non-pointer, non-target variable, there remains one way to get two identifiers pointing to the same memory: Passing it as argument to a function (multiple times – or once and accessing it directly from the other scope).
In order to avoid problems here, Fortran requires (from the programmer) that those variables are either only accessed for reading – or that only one identifier is used for modification and all others are not not used for read access (neither before nor after the modification).

See https://gcc.gnu.org/ml/fortran/2019-11/msg00126.html for some language quotes.

Otherwise, see Fortran 2018, https://j3-fortran.org/doc/year/18/18-007r1.pdf for the definitions of TARGET, POINTER, ASYNCHRONOUS and VOLATILE.
For argument association, see Section 15.5.2 in general and 15.5.2.13 in particular. (An in-depth description of data association/defining/undefining is in Chapter 9)
Comment 1 Tobias Burnus 2019-11-22 10:07:41 UTC
*** Bug 49733 has been marked as a duplicate of this bug. ***
Comment 2 Tobias Burnus 2019-11-22 10:16:37 UTC
(In reply to Tobias Burnus from comment #0)
> A similar rule applies to other variables in Fortran
See also PR 60712 regarding restrict and local variables (as opposed to PARAM_DECL) for a simpler case (no function call).
Comment 3 Richard Biener 2019-11-25 10:02:13 UTC
I think we have a duplicate asking about restrict to have an effect on
function calls.
Comment 4 Tobias Burnus 2019-11-25 10:08:25 UTC
(In reply to Richard Biener from comment #3)
> I think we have a duplicate asking about restrict to have an effect on
> function calls.

Could be PR tree-optimization/81008.
Comment 5 Thomas Koenig 2020-07-19 16:33:36 UTC
Any progress in this direction? Should we revisit PR 67202
(maybe do this in trans-*), or maybe even it?