forked from OSchip/llvm-project
[flang] Create OpenMP-semantics.md
Initial markdown document. Original-commit: flang-compiler/f18@787a0ca058 Reviewed-on: https://github.com/flang-compiler/f18/pull/692 Tree-same-pre-rewrite: false
This commit is contained in:
parent
23a7f38741
commit
6e4c8b88c5
|
@ -0,0 +1,650 @@
|
|||
# OpenMP Semantic Analysis
|
||||
|
||||
## F18 for OpenMP
|
||||
|
||||
1. Define and document the parse tree representation for
|
||||
* Directives (listed below)
|
||||
* Clauses (listed below)
|
||||
* Documentation
|
||||
1. All the directives and clauses need source provenance for messages
|
||||
1. Define and document how an OpenMP directive in the parse tree
|
||||
will be represented as the parent of the statement(s)
|
||||
to which the directive applies.
|
||||
The parser itself will not be able to construct this representation;
|
||||
there will be subsequent passes that do so
|
||||
just like for example _do-stmt_ and _do-construct_.
|
||||
1. Define and document the symbol table extensions
|
||||
1. Define and document the module file extensions
|
||||
|
||||
|
||||
### Directives
|
||||
|
||||
OpenMP divides directives into three categories as follows.
|
||||
The directives that are in the same categories share some characteristics.
|
||||
|
||||
|
||||
|
||||
#### Declarative directives
|
||||
|
||||
An OpenMP directive that may only be placed in a declarative context.
|
||||
A declarative directive results in one or more declarations only;
|
||||
it is not associated with the immediate execution of any user code.
|
||||
|
||||
List of existing ones:
|
||||
* declare simd
|
||||
* declare target
|
||||
* threadprivate
|
||||
* declare reduction
|
||||
|
||||
There is a parser node for each of these directives and
|
||||
the parser node saves information associated with the directive,
|
||||
for example,
|
||||
the name of the procedure-name in the `declare simd` directive.
|
||||
|
||||
Each parse tree node keeps source provenance,
|
||||
one for the directive name itself and
|
||||
one for the entire directive starting from the directive name.
|
||||
|
||||
A top-level class, `OpenMPDeclarativeConstruct`,
|
||||
holds all four of the node types as discriminated unions
|
||||
along with the source provenance for the entire directive
|
||||
starting from `!$OMP`.
|
||||
|
||||
In the `parser-tree.h`,
|
||||
`OpenMPDeclarativeConstruct` is part
|
||||
of the `SpecificationConstruct` and `SpecificationPart`
|
||||
in F18 because
|
||||
a declarative directive can only be placed in the specification part
|
||||
of a Fortran program.
|
||||
|
||||
All the `_Names` or `_Designators` associated
|
||||
with the declarative directive will be resolved in later phases.
|
||||
|
||||
#### Executable directives
|
||||
|
||||
An OpenMP directive that is **not** declarative.
|
||||
That is, it may only be placed in an executable context.
|
||||
It contains stand-alone directives and constructs
|
||||
that are associated with code blocks.
|
||||
The stand-alone directive is described in the next section.
|
||||
|
||||
The constructs associated with code blocks listed below
|
||||
share a similar structure:
|
||||
_Begin Directive_, _Clause List_, _Code Block_, _End Directive_.
|
||||
The _End Directive_ is optional for constructs
|
||||
like Loop-associated constructs.
|
||||
|
||||
* Block-associated constructs (`OpenMPBlockConstruct`)
|
||||
* Loop-associated constructs (`OpenMPLoopConstruct`)
|
||||
* Atomic construct (`OpenMPAtomicConstruct`)
|
||||
* Sections Construct (`OpenMPSectionsConstruct`,
|
||||
contains Sections/Parallel Sections constructs)
|
||||
* Critical Construct (`OpenMPCriticalConstruct`)
|
||||
|
||||
A top-level class, `OpenMPConstruct`,
|
||||
includes stand-alone directive and constructs
|
||||
listed above as discriminated unions.
|
||||
|
||||
In the `parse-tree.h`, `OpenMPConstruct` is an element
|
||||
of the `ExecutableConstruct`.
|
||||
|
||||
All the `_Names` or `_Designators` associated
|
||||
with the executable directive will be resolved in Semantic Analysis.
|
||||
|
||||
When the backtracking parser can not identify the associated code blocks,
|
||||
the parse tree will be rewritten later in the Semantics Analysis.
|
||||
|
||||
#### Stand-alone Directives
|
||||
|
||||
An OpenMP executable directive that has no associated user code
|
||||
except for that which appears in clauses in the directive.
|
||||
|
||||
List of existing ones:
|
||||
* taskyield
|
||||
* barrier
|
||||
* taskwait
|
||||
* target enter data
|
||||
* target exit data
|
||||
* target update
|
||||
* ordered
|
||||
* flush
|
||||
* cancel
|
||||
* cancellation point
|
||||
|
||||
A higher-level class is created for each categorys
|
||||
which contains directives listed above that share a similar structure:
|
||||
* OpenMPSimpleStandaloneConstruct
|
||||
(taskyield, barrier, taskwait,
|
||||
target enter/exit data, target update, ordered)
|
||||
* OpenMPFlushConstruct
|
||||
* OpenMPCancelConstruct
|
||||
* OpenMPCancellationPointConstruct
|
||||
|
||||
A top-level class, `OpenMPStandaloneConstruct`,
|
||||
holds all four of the node types as discriminated unions
|
||||
along with the source provenance for the entire directive.
|
||||
Also, each parser node for the stand-alone directive saves
|
||||
the source provenance for the directive name itself.
|
||||
|
||||
### Clauses
|
||||
|
||||
Each clause represented as a distinct class in `parse-tree.h`.
|
||||
A top-level class, `OmpClause`, includes all the clauses as discriminated unions. The parser node for `OmpClause` saves the source provenance for the entire clause.
|
||||
|
||||
All the `_Names` or `_Designators` associated
|
||||
with the clauses will be resolved in Semantic Analysis.
|
||||
|
||||
Note that the backtracking parser will not validate
|
||||
that the list of clauses associated
|
||||
with a directive is valid other than to make sure they are well-formed.
|
||||
In particular,
|
||||
the parser does not check that
|
||||
the association between directive and clauses is correct
|
||||
nor check that the values in the directives or clauses are correct.
|
||||
These checks are deferred to later phases of semantics to simplify the parser.
|
||||
|
||||
## Symbol Table Extensions for OpenMP
|
||||
|
||||
Name resolution can be impacted by the OpenMP code.
|
||||
In addition to the regular steps to do the name resolution,
|
||||
new scopes and symbols may need to be created
|
||||
when encountering certain OpenMP constructs.
|
||||
This section describes the extensions
|
||||
for OpenMP during Symbol Table construction.
|
||||
|
||||
OpenMP uses the fork-join model of parallel execution and
|
||||
all OpenMP threads have access to
|
||||
a _shared_ memory place to store and retrieve variables
|
||||
but each thread can also have access to
|
||||
its _threadprivate_ memory that must not be accessed by other threads.
|
||||
|
||||
For the directives and clauses that can control the data environments,
|
||||
compiler needs to determine two kinds of _access_
|
||||
to variables used in the directive’s associated structured block:
|
||||
**shared** and **private**.
|
||||
Each variable referenced in the structured block
|
||||
has an original variable immediately outside of the OpenMP constructs. Reference to a shared variable in the structured block
|
||||
becomes a reference to the original variable.
|
||||
However, each private variable referenced in the structured block,
|
||||
a new version of the original variable (of the same type and size)
|
||||
will be created in the threadprivate memory.
|
||||
|
||||
There are exceptions that directives/clauses
|
||||
need to create a new `Symbol` without creating a new `Scope`,
|
||||
but in general,
|
||||
when encountering each of the data environment controlling directives
|
||||
(discussed in the following sections),
|
||||
a new `Scope` will be created.
|
||||
For each private variable referenced in the structured block,
|
||||
a new `Symbol` is created out of the original variable
|
||||
and the new `Symbol` is associated
|
||||
with original variable’s `Symbol` via `HostAssocDetails`.
|
||||
A new set of OpenMP specific flags are added
|
||||
into `Flag` class in `symbol.h` to indicate the types of
|
||||
associations,
|
||||
data-sharing attributes,
|
||||
and data-mapping attributes
|
||||
in the OpenMP data environments.
|
||||
|
||||
### New Symbol without new Scope
|
||||
|
||||
OpenMP directives that require new `Symbol` to be created
|
||||
but not new `Scope` are listed in the following table
|
||||
in terms of the Symbol Table extensions for OpenMP:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td rowspan="2" colspan="2" >Directives/Clauses
|
||||
</td>
|
||||
<td rowspan="2" >Create New
|
||||
<p>
|
||||
Symbol
|
||||
<p>
|
||||
w/
|
||||
</td>
|
||||
<td colspan="2" >Add Flag
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>on Symbol of
|
||||
</td>
|
||||
<td>Flag
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="4" >Declarative Directives
|
||||
</td>
|
||||
<td>declare simd [(proc-name)]
|
||||
</td>
|
||||
<td>-
|
||||
</td>
|
||||
<td>The name of the enclosing function, subroutine, or interface body to which it applies, or proc-name
|
||||
</td>
|
||||
<td>OmpDeclareSimd
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>declare target
|
||||
</td>
|
||||
<td>-
|
||||
</td>
|
||||
<td>The name of the enclosing function, subroutine, or interface body to which it applies
|
||||
</td>
|
||||
<td>OmpDeclareTarget
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>threadprivate(list)
|
||||
</td>
|
||||
<td>-
|
||||
</td>
|
||||
<td>named variables and named common blocks
|
||||
</td>
|
||||
<td>OmpThreadPrivate
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>declare reduction
|
||||
</td>
|
||||
<td>*
|
||||
</td>
|
||||
<td>reduction-identifier
|
||||
</td>
|
||||
<td>OmpDeclareReduction
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Stand-alone directives
|
||||
</td>
|
||||
<td>flush
|
||||
</td>
|
||||
<td>-
|
||||
</td>
|
||||
<td>variable, array section or common block name
|
||||
</td>
|
||||
<td>OmpFlushed
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" >critical [(name)]
|
||||
</td>
|
||||
<td>-
|
||||
</td>
|
||||
<td>name (user-defined identifier)
|
||||
</td>
|
||||
<td>OmpCriticalLock
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" >if ([ directive-name-modifier :] scalar-logical-expr)
|
||||
</td>
|
||||
<td>-
|
||||
</td>
|
||||
<td>directive-name-modifier
|
||||
</td>
|
||||
<td>OmpIfSpecified
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
- No Action
|
||||
|
||||
* Discussed in “Module File Extensions for OpenMP” section
|
||||
|
||||
|
||||
### New Symbol with new Scope
|
||||
|
||||
For the following OpenMP regions:
|
||||
|
||||
* `target` regions
|
||||
* `teams` regions
|
||||
* `parallel` regions
|
||||
* `simd` regions
|
||||
* task generating regions (created by `task` or `taskloop` constructs)
|
||||
* worksharing regions
|
||||
(created by `do`, `sections`, `single`, or `workshare` constructs)
|
||||
|
||||
A new `Scope` will be created
|
||||
when encountering the above OpenMP constructs
|
||||
to ensure the correct data environment during the Code Generation.
|
||||
To determine whether a variable referenced in these regions
|
||||
needs the creation of a new `Symbol`,
|
||||
all the data-sharing attribute rules
|
||||
described in OpenMP Spec [2.15.1] apply during the Name Resolution.
|
||||
The available data-sharing attributes are:
|
||||
**_shared_**,
|
||||
**_private_**,
|
||||
**_linear_**,
|
||||
**_firstprivate_**,
|
||||
and **_lastprivate_**.
|
||||
The attribute is represented as `Flag` in the `Symbol` object.
|
||||
|
||||
More details are listed in the following table:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td rowspan="2" >Attribute
|
||||
</td>
|
||||
<td rowspan="2" >Create New Symbol
|
||||
</td>
|
||||
<td colspan="2" >Add Flag
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>on Symbol of
|
||||
</td>
|
||||
<td>Flag
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>shared
|
||||
</td>
|
||||
<td>No
|
||||
</td>
|
||||
<td>Original variable
|
||||
</td>
|
||||
<td>OmpShared
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>private
|
||||
</td>
|
||||
<td>Yes
|
||||
</td>
|
||||
<td>New Symbol
|
||||
</td>
|
||||
<td>OmpPrivate
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>linear
|
||||
</td>
|
||||
<td>Yes
|
||||
</td>
|
||||
<td>New Symbol
|
||||
</td>
|
||||
<td>OmpLinear
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>firstprivate
|
||||
</td>
|
||||
<td>Yes
|
||||
</td>
|
||||
<td>New Symbol
|
||||
</td>
|
||||
<td>OmpFirstPrivate
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lastprivate
|
||||
</td>
|
||||
<td>Yes
|
||||
</td>
|
||||
<td>New Symbol
|
||||
</td>
|
||||
<td>OmpLastPrivate
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
To determine the right data-sharing attribute,
|
||||
OpenMP defines that the data-sharing attributes
|
||||
of variables that are referenced in a construct can be
|
||||
_predetermined_, _explicitly determined_, or _implicitly determined_.
|
||||
|
||||
#### Predetermined data-sharing attributes
|
||||
|
||||
* Assumed-size arrays are **shared**
|
||||
* The loop iteration variable(s)
|
||||
in the associated _do-loop(s)_ of a
|
||||
_do_,
|
||||
_parallel do_,
|
||||
_taskloop_,
|
||||
or _distributeconstruct_
|
||||
is (are) **private**
|
||||
* A loop iteration variable
|
||||
for a sequential loop in a _parallel_ or task generating construct
|
||||
is **private** in the innermost such construct that encloses the loop
|
||||
* Implied-do indices and _forall_ indices are **private**
|
||||
* The loop iteration variable in the associated _do-loop_
|
||||
of a _simd_ construct with just one associated _do-_taskloop_
|
||||
is **linear** with a linear-step
|
||||
that is the increment of the associated _do-loop_
|
||||
* The loop iteration variables in the associated _do-loop(s)_ of a _simd_
|
||||
construct with multiple associated _do-loop(s)_ are **lastprivate**
|
||||
|
||||
#### Explicitly determined data-sharing attributes
|
||||
|
||||
Variables with _explicitly determined_ data-sharing attributes are:
|
||||
|
||||
* Variables are referenced in a given construct
|
||||
* Variables are listed in a data-sharing attribute clause on the construct.
|
||||
|
||||
The data-sharing attribute clauses are:
|
||||
* _default_ clause
|
||||
(discussed in “Implicitly determined data-sharing attributes”)
|
||||
* _shared_ clause
|
||||
* _private_ clause
|
||||
* _linear_ clause
|
||||
* _firstprivate_ clause
|
||||
* _lastprivate_ clause
|
||||
* _reduction_ clause
|
||||
(new `Symbol` created with the flag `OmpReduction` set)
|
||||
|
||||
Note that variables with _predetermined_ data-sharing attributes
|
||||
may not be listed (with exceptions) in data-sharing attribute clauses.
|
||||
|
||||
#### Implicitly determined data-sharing attributes
|
||||
|
||||
Variables with implicitly determined data-sharing attributes are:
|
||||
|
||||
* Variables are referenced in a given construct
|
||||
* Variables do not have _predetermined_ data-sharing attributes
|
||||
* Variables are not listed in a data-sharing attribute clause
|
||||
on the construct.
|
||||
|
||||
Rules for variables with _implicitly determined_ data-sharing attributes:
|
||||
|
||||
* In a _parallel_ construct, if no _default_ clause is present,
|
||||
these variables are **shared**
|
||||
* In a task generating construct,
|
||||
if no _default_ clause is present,
|
||||
a variable for which the data-sharing attribute
|
||||
is not determined by the rules above
|
||||
and that in the enclosing context is determined
|
||||
to be shared by all implicit tasks
|
||||
bound to the current team is **shared**
|
||||
* In a _target_ construct,
|
||||
variables that are not mapped after applying data-mapping attribute rules
|
||||
(discussed later) are **firstprivate**
|
||||
* In an orphaned task generating construct,
|
||||
if no _default_ clause is present, dummy arguments are **firstprivate**
|
||||
* In a task generating construct, if no _default_ clause is present,
|
||||
a variable for which the data-sharing attribute is not determined
|
||||
by the rules above is **firstprivate**
|
||||
* For constructs other than task generating constructs or _target_constructs,
|
||||
if no _default_ clause is present,
|
||||
these variables reference the variables with the same names
|
||||
that exist in the enclosing context
|
||||
* In a _parallel_, _teams_, or task generating construct,
|
||||
the data-sharing attributes of these variables are determined
|
||||
by the _default_clause, if present:
|
||||
* _default(shared)_
|
||||
clause causes all variables referenced in the construct
|
||||
that have _implicitly determined_ data-sharing attributes
|
||||
to be **shared**
|
||||
* _default(private)_
|
||||
clause causes all variables referenced in the construct
|
||||
that have _implicitly determined_ data-sharing attributes
|
||||
to be **private**
|
||||
* _default(firstprivate)_
|
||||
clause causes all variables referenced in the construct
|
||||
that have _implicitly determined_ data-sharing attributes
|
||||
to be **firstprivate**
|
||||
* _default(none)_
|
||||
clause requires that each variable
|
||||
that is referenced in the construct,
|
||||
and that does not have a _predetermined_ data-sharing attribute,
|
||||
must have its data-sharing attribute _explicitly determined_
|
||||
by being listed in a data-sharing attribute clause
|
||||
|
||||
|
||||
### Data-mapping Attribute
|
||||
|
||||
When encountering the _target data_ and _target_ directives,
|
||||
the data-mapping attributes of any variable referenced in a target region
|
||||
will be determined and represented as `Flag` in the `Symbol` object
|
||||
of the variable.
|
||||
No `Symbol` or `Scope` will be created.
|
||||
|
||||
The basic steps to determine the data-mapping attribute are:
|
||||
|
||||
1. If _map_ clause is present,
|
||||
the data-mapping attribute is determined by the _map-type_
|
||||
on the clause and its corresponding `Flag` are listed below:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
data-mapping attribute
|
||||
</td>
|
||||
<td>Flag
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>to
|
||||
</td>
|
||||
<td>OmpMapTo
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>from
|
||||
</td>
|
||||
<td>OmpMapFrom
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>tofrom \
|
||||
(default if map-type is not present)
|
||||
</td>
|
||||
<td>OmpMapTo & OmpMapFrom
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>alloc
|
||||
</td>
|
||||
<td>OmpMapAlloc
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>release
|
||||
</td>
|
||||
<td>OmpMapRelease
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>delete
|
||||
</td>
|
||||
<td>OmpMapDelete
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
2. Otherwise, the following data-mapping rules apply
|
||||
for variables referenced in a _target_ construct
|
||||
that are _not_ declared in the construct and
|
||||
do not appear in data-sharing attribute or map clauses:
|
||||
* If a variable appears in a _to _or _link _clause on a _declare target _directive then it is treated as if it had appeared in a _map _clause with a _map-type_ of **tofrom**
|
||||
3. Otherwise, the following implicit data-mapping attribute rules apply:
|
||||
* If a _defaultmap(tofrom:scalar)_ clause is _not_ present
|
||||
then a scalar variable is not mapped,
|
||||
but instead has an implicit data-sharing attribute of **firstprivate**
|
||||
* If a _defaultmap(tofrom:scalar)_ clause is present
|
||||
then a scalar variable is treated as if it had appeared
|
||||
in a map clause with a map-type of **tofrom**
|
||||
* If a variable is not a scalar
|
||||
then it is treated as if it had appeared in a map clause
|
||||
with a _map-type_ of **tofrom**
|
||||
|
||||
After the completion of the Name Resolution phase, all the data-sharing or data-mapping attributes marked for the `Symbols` may be used later in the Semantics Analysis and in the Code Generation.
|
||||
|
||||
## Module File Extensions for OpenMP
|
||||
|
||||
After the successful compilation of modules and submodules that may contain the following Declarative Directives, the entire directive starts from `!$OMP` needs to be written out into `.mod` files in their corresponding Specification Part:
|
||||
|
||||
* _declare simd_ or _declare target_
|
||||
|
||||
In the “New Symbol without new Scope” section,
|
||||
we described that when encountering these two declarative directives,
|
||||
new `Flag` will be applied to the Symbol of the name of
|
||||
the enclosing function, subroutine, or interface body to
|
||||
which it applies, or proc-name.
|
||||
This `Flag` should be part of the API information
|
||||
for the given subroutine or function
|
||||
|
||||
* _declare reduction_
|
||||
|
||||
The _reduction-identifier_ in this directive
|
||||
can be use-associated or host-associated.
|
||||
However, it will not act like other Symbols
|
||||
because user may have a reduction name
|
||||
that is the same as a Fortran entity name in the same scope.
|
||||
Therefore a specific data structure needs to be created
|
||||
to save the _reduction-identifier_ information
|
||||
in the Scope and this directive needs to be written into `.mod` files
|
||||
|
||||
## Phases of OpenMP Analysis
|
||||
|
||||
1. Create the parse tree for OpenMP
|
||||
1. Add types for directives and clauses.
|
||||
1. Add type(s) that will be used for directives
|
||||
2. Add type(s) that will be used for clauses
|
||||
3. Add other types, e.g. wrappers or other containers
|
||||
4. Use std::variant to encapsulate meaningful types
|
||||
2. Implemented in the parser for OpenMP (openmp-grammar.h)
|
||||
2. Create canonical nesting
|
||||
1. Restructure parse tree to reflect the association
|
||||
of directives and stmts
|
||||
1. Associate `OpenMPLoopConstruct`
|
||||
with `DoConstruct` and `OpenMPEndLoopDirective`
|
||||
1. Investigate, and perhaps reuse,
|
||||
the algorithm used to restructure do-loops
|
||||
2. Add a pass near the code that restructures do-loops;
|
||||
but do not extend the code that handles do-loop for OpenMP;
|
||||
keep this code separate.
|
||||
3. Report errors that prevent restructuring
|
||||
(e.g. loop directive not followed by loop)
|
||||
We should abort in case of errors
|
||||
because there is no point to perform further checks
|
||||
if it is not a legal OpenMP construct
|
||||
4. N.B. Consider moving this code and the do-loops code to the parser namespace.
|
||||
3. Validate the structured-block
|
||||
1. Structured-block is a block of executable statements
|
||||
1. Single entry and single exit
|
||||
1. Access to the structured block must not be the result of a branch
|
||||
1. The point of exit cannot be a branch out of the structured block
|
||||
4. Check that directive and clause combinations are legal
|
||||
1. Begin and End directive should match
|
||||
1. Simply check that the clauses are allowed by the directives
|
||||
1. Write as a separate pass for simplicity and correctness of the parse tree
|
||||
5. Write parse tree tests
|
||||
1. At this point, the parse tree should be perfectly formed
|
||||
1. Write tests that check for correct form and provenance information
|
||||
1. Write tests for errors that can occur during the restructuring
|
||||
6. Scope, symbol tables, and name resolution
|
||||
1. Update the existing code to handle names and scopes introduced by OpenMP
|
||||
1. Write tests to make sure names are properly implemented
|
||||
7. Check semantics that is specific to each directive
|
||||
1. Validate the directive and its clauses
|
||||
1. Some clause checks require the result of name resolution,
|
||||
i.e. “A list item may appear in a _linear_ or _firstprivate_ clause
|
||||
but not both.”
|
||||
1. TBD:
|
||||
Validate the nested statement for legality in the scope of the directive
|
||||
1. Check the nesting of regions [OpenMP 4.5 spec 2.17]
|
||||
8. Module file utilities
|
||||
1. Write necessary OpenMP declarative directives to `.mod` files
|
||||
2. Update the existing code
|
||||
to read available OpenMP directives from the `.mod` files
|
Loading…
Reference in New Issue