llvm-project/flang/test/Semantics/omp-symbol05.f90

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

41 lines
1.0 KiB
Fortran
Raw Normal View History

! RUN: %S/test_symbols.sh %s %t %f18 -fopenmp
[flang] [OpenMP] OmpVisitor framework for Name Resolution This is a preliminary framework to do the name resolution for data references on the OpenMP clauses. Unlike data references in the OpenMP region, clauses determining the data-sharing or data-mapping attributes are straightforward and the resolution process could be extended to do the name resolution in the OpenMP region. It is hard to determine what kind of checks can be done in this visitor and what checks should be done later after name resolution. But the guide line is that `After the completion of this phase, every Name corresponds to a Symbol with proper OpenMP attribute(s) determined unless an error occurred.` 1. Take data-sharing clauses as example, create new symbol for variable that require private access within the OpenMP region. Declare the entity implicitly if necessary. The new symbol has `HostAssocDetails`, which is mentioned in the `OpenMP-semantics.md`. 2. For `Shared` or `ThreadPrivate`, no symbol needs to be created. OpenMP attribute Flag `OmpThreadprivate` needs to be marked for `Threadprivate` because the `threadprivate` attribute remains the same whenever these variables are referenced in the program. `Names` in `Shared` clause need to be resolved to associate the symbols in the clause enclosing scope (contains the OpenMP directive) but `OmpShared` does not need to be marked. Declare the entity implicitly if necessary. 3. For `COMMON block`, when a named common block appears in a list, it has the same meaning as if every explicit member of the common block appeared in the list. Also, a common block name specified in a data-sharing attribute clause must be declared to be a common block in the same scoping unit in which the data-sharing attribute clause appears. So, if a named common block appears on a `PRIVATE` clause, all its members should have new symbols created within the OpenMP region (scope). For later Semantic checks and CG, a new symbol is also created for common block name with `HostAssocDetails`. There are many things are still on the TODO list: - Better error/warning messages with directive/clause source provenance - Resolve variables referenced in the OpenMP region, for example, `private(tt%a)` is not allowed but `tt%a = 1` is allowed in the OpenMP region and a private version of `tt` maybe created for the region. The functions created in the `OmpVisitor` should be able to handle the name resolution on the statement too (more data structures may be introduced). This is a big portion and may require some interface changes to distinguish a reference is on `OpenMP directive/clause` or `statements within OpenMP region`. - Same data reference appears on multiple data-sharing clauses. - Take association into consideration for example Pointer association, `ASSOCIATE` construct, and etc. - Handle `Array Sections` and `Array or Structure Element`. - Handle all the name resolution for directives/clauses that have `parser::Name`. - More tests Original-commit: flang-compiler/f18@b2ea520885eceb6e118f690b95e1846183fe378b
2019-09-12 05:42:51 +08:00
! 2.15.2 threadprivate Directive
! The threadprivate directive specifies that variables are replicated,
! with each thread having its own copy. When threadprivate variables are
! referenced in the OpenMP region, we know they are already private to
! their threads, so no new symbol needs to be created.
!DEF: /mm Module
module mm
!$omp threadprivate (i)
contains
!DEF: /mm/foo PUBLIC (Subroutine) Subprogram
subroutine foo
!DEF: /mm/foo/a ObjectEntity INTEGER(4)
integer :: a = 3
!$omp parallel
!REF: /mm/foo/a
a = 1
!DEF: /mm/i PUBLIC (Implicit, OmpThreadprivate) ObjectEntity INTEGER(4)
!REF: /mm/foo/a
i = a
!$omp end parallel
!REF: /mm/foo/a
print *, a
block
!DEF: /mm/foo/Block2/i ObjectEntity REAL(4)
real i
!REF: /mm/foo/Block2/i
i = 3.14
end block
end subroutine foo
end module mm
!DEF: /tt MainProgram
program tt
!REF: /mm
use :: mm
!DEF: /tt/foo (Subroutine) Use
call foo
end program tt