Add two more AST nodes, one for a misplaced end-directive, and one for
an invalid string following the OpenMP sentinel (e.g. "!$OMP XYZ").
Emit error messages when either node is encountered in semantic
analysis.
This patch adds semantics for the `omp fuse` directive in flang, as
specified in OpenMP 6.0. This patch also enables semantic support for
loop sequences which are needed for the fuse directive along with
semantics for the `looprange` clause. These changes are only semantic.
Relevant tests have been added , and previous behavior is retained with
no changes.
---------
Co-authored-by: Ferran Toda <ferran.todacasaban@bsc.es>
Co-authored-by: Krzysztof Parzyszek <Krzysztof.Parzyszek@amd.com>
Flang does not allow the use of Structure Component types inside of
certain OpenMP clauses. While this has been introduced, it seemed that
Structure Component Array Elements were not being captured as they got
embedded in the parse tree. To ensure all structure component types are
identified, a new `HasStructureComponent` evaluate function has been
introduced to walk a Semantics expression, identified where Components
are used within.
This replaces the previous implementation of `CheckStructureComponent`
which just looked for the StructureComponent inside of a DataRef.
Fixes#150830
The ALLOCATE directive has two forms:
- A declarative form with a standalone directive:
```
!$OMP ALLOCATE (variable-list-item...)
```
- An executable form that consists of several directives followed by an
ALLOCATE statement:
```
!$OMP ALLOCATE (variable-list-item...)
!$OMP ALLOCATE (variable-list-item...)
...
ALLOCATE (...)
```
The second form was deprecated in OpenMP 5.2 in favor of the ALLOCATORS
construct.
Since in the parse tree every type corresponding to a directive only
corresponds to a single directive, the executable form is represented by
a sequence of nested OmpAllocateDirectives, e.g.
```
!$OMP ALLOCATE(x)
!$OMP ALLOCATE(y)
ALLOCATE(x, y)
```
will become
```
OmpAllocateDirective
|- ALLOCATE(x) // begin directive
`- OmpAllocateDirective // block
|- ALLOCATE(y) // begin directive
`- ALLOCATE(x, y) // block
```
With this change all AST nodes for directives use
OmpDirectiveSpecification as the directive representation.
For ALLOCATORS and executable ALLOCATE first perform list item checks in
the context of an individual ALLOCATE clause or directive respectively,
then perform "global" checks, e.g. whether all list items are present on
the ALLOCATE statement.
These changes allowed to simplify the checks for presence on ALLOCATE
statement and the use of a predefined allocator.
Additionally, allow variable list item lists to be empty, add a test for
the related spec restriction.
This is a first step towards unifying OpenMPDeclarativeAllocate and
OpenMPExecutableAllocate into a single directive.
OpenMP 5.0 and 5.1 allowed the ALLOCATE directive to appear in two
forms, declarative and executable. The syntax of an individual directive
was the same in both cases, but the semantic restrictions were slightly
different.
- Update the semantic checks to reflect the different restrictions,
gather them in a single function.
- Improve test for the presence of a TARGET region, add a check for
REQUIRES directive.
- Update tests.
Introduce a stack of scopes to OmpStructureChecker for scoping units,
plus function/subroutine entries in interfaces.
This will help with applying and locating properties introduced by
declarative or informational directives (e.g. DECLARE_TARGET, REQUIRES),
which are stored as flags on the corresponding symbols.
Replace more parse tree references to "thing" and "value()" with usage
of the parser::Unwrap<> template function.
Add parser::UnwrapRef<> as an alias for DEREF(Unwrap<>()).
Use ScalarIntConstantExpr in the parse tree instead of ScalarIntExpr.
This will still parse a general expression, but the semantic checker for
expressions will automatically perfom a test for whether the value is
constant or not.
Use that instead of manual checks, it will make diagnostics more
uniform. There is no functional change other than that.
OpenMP 6.0 added an optional logical parameter to the requirement
clauses (except ATOMIC_DEFAULT_MEM_ORDER) to indicate whether the clause
should take effect or not. The parameter defaults to true if not
specified.
The parameter value is a compile-time constant expression, but it may
require folding to get the final value. Since name resolution happens
before folding, the argument expression needs to be analyzed by hand.
The determination of the value needs to happen during name resolution
because the requirement directives need to be available through module
files (and the module reader doesn't to semantic checks beyond name
resolution).
Audit the use of std::optional<bool> as a tri-state logical value in
flang, correct a couple cases that need ".value_or()", add some explicit
".has_value()" calls, and document the possible pitfalls.
Add support for the standalone OpenMP tile construct:
```f90
!$omp tile sizes(...)
DO i = 1, 100
...
```
This is complementary to #143715 which added support for the tile
construct as part of another loop-associated construct such as
worksharing-loop, distribute, etc.
This change implements the fuse directive, `#pragma omp fuse`, as specified in the OpenMP 6.0, along with the `looprange` clause in clang.
This change also adds minimal stubs so flang keeps compiling (a full implementation in flang of this directive is still pending).
---------
Co-authored-by: Roger Ferrer Ibanez <roger.ferrer@bsc.es>
This verifies the "structural" restrictions on constructs encountered in
a TASKGRAPH construct.
There are also restrictions that apply to list items, specifically in
the following contexts:
- a list item on a clause on a replayable construct,
- data-sharing attributes for a variable on a replayable construct.
These restrictions are not verified, because that would require knowing
which clauses (on a potential compound directive) apply to the task-
generating construct of interest. This information is not available
during semantic checks.
Since ODS doesn't store a list of OmpObjects (i.e. not as
OmpObjectList), some semantics-checking functions needed to be updated
to operate on a single object at a time.
…rective
This makes accessing directive components, such as directive name or the
list of clauses simpler and more uniform across different directives. It
also makes the parser simpler, since it reuses existing parsing
functionality.
The changes are scattered over a number of files, but they all share the
same nature:
- getting the begin/end directive from OpenMPLoopConstruct,
- getting the llvm::omp::Directive enum, and the source location,
- getting the clause list.
This only adds the definitions of the TASKGRAPH directive and the
associated clauses, plus the minimal additional changes to make
everything compile without errors.
…resent
The OpenMP spec 4.5-5.1 defines ORDERED as standalone when a DEPEND
clause is present (with either SOURCE or SINK as argument). The OpenMP
spec 5.2+ defines ORDERED as standalone when a DOACROSS clause is
present.
OpenMPBlockConstruct, somewhat confusingly, represents most but not all
block-associated constructs. It's derived from OmpBlockConstruct, as are
all the remaining block-associated constructs.
It does not correspond to any well-defined group of constructs. It's the
collection of constructs that don't have their own types (and those that
do have their own types do so for their own reasons).
Using the broader OmpBlockConstruct in type-based visitors won't cause
issues, because the specific overloads (for classes derived from it)
will always be preferred.