2020-02-25 23:11:52 +08:00
|
|
|
//===-- lib/Semantics/check-omp-structure.h ---------------------*- C++ -*-===//
|
2019-06-26 07:18:51 +08:00
|
|
|
//
|
2019-12-21 04:52:07 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2019-06-26 07:18:51 +08:00
|
|
|
//
|
2020-01-11 04:12:03 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2019-06-26 07:18:51 +08:00
|
|
|
|
|
|
|
// OpenMP structure validity check list
|
|
|
|
// 1. invalid clauses on directive
|
|
|
|
// 2. invalid repeated clauses on directive
|
|
|
|
// 3. TODO: invalid nesting of regions
|
|
|
|
|
|
|
|
#ifndef FORTRAN_SEMANTICS_CHECK_OMP_STRUCTURE_H_
|
|
|
|
#define FORTRAN_SEMANTICS_CHECK_OMP_STRUCTURE_H_
|
|
|
|
|
2020-08-06 02:20:26 +08:00
|
|
|
#include "check-directive-structure.h"
|
2020-02-25 23:11:52 +08:00
|
|
|
#include "flang/Common/enum-set.h"
|
|
|
|
#include "flang/Parser/parse-tree.h"
|
|
|
|
#include "flang/Semantics/semantics.h"
|
[flang][openmp] Use common Directive and Clause enum from llvm/Frontend
Summary:
This patch is removing the custom enumeration for OpenMP Directives and Clauses and replace them
with the newly tablegen generated one from llvm/Frontend. This is a first patch and some will follow to share the same
infrastructure where possible. The next patch should use the clauses allowance defined in the tablegen file.
Reviewers: jdoerfert, DavidTruby, sscalpone, kiranchandramohan, ichoyjx
Reviewed By: DavidTruby, ichoyjx
Subscribers: jholewinski, cfe-commits, dblaikie, MaskRay, ymandel, ichoyjx, mgorny, yaxunl, guansong, jfb, sstefan1, aaron.ballman, llvm-commits
Tags: #llvm, #flang, #clang
Differential Revision: https://reviews.llvm.org/D82906
2020-07-02 08:57:11 +08:00
|
|
|
#include "llvm/Frontend/OpenMP/OMPConstants.h"
|
|
|
|
|
|
|
|
using OmpDirectiveSet = Fortran::common::EnumSet<llvm::omp::Directive,
|
|
|
|
llvm::omp::Directive_enumSize>;
|
|
|
|
|
|
|
|
using OmpClauseSet =
|
|
|
|
Fortran::common::EnumSet<llvm::omp::Clause, llvm::omp::Clause_enumSize>;
|
|
|
|
|
[flang][openmp] Check clauses allowed semantic with tablegen generated map
Summary:
This patch is enabling the generation of clauses enum sets for semantics check in Flang through
tablegen. Enum sets and directive - sets map is generated by the new tablegen infrsatructure for OpenMP
and other directive languages.
The semantic checks for OpenMP are modified to use this newly generated map.
Reviewers: DavidTruby, sscalpone, kiranchandramohan, ichoyjx, jdoerfert
Reviewed By: DavidTruby, ichoyjx
Subscribers: mgorny, yaxunl, hiraditya, guansong, sstefan1, aaron.ballman, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D83326
2020-07-12 00:42:05 +08:00
|
|
|
#define GEN_FLANG_DIRECTIVE_CLAUSE_SETS
|
|
|
|
#include "llvm/Frontend/OpenMP/OMP.cpp.inc"
|
|
|
|
|
[flang][openmp] Use common Directive and Clause enum from llvm/Frontend
Summary:
This patch is removing the custom enumeration for OpenMP Directives and Clauses and replace them
with the newly tablegen generated one from llvm/Frontend. This is a first patch and some will follow to share the same
infrastructure where possible. The next patch should use the clauses allowance defined in the tablegen file.
Reviewers: jdoerfert, DavidTruby, sscalpone, kiranchandramohan, ichoyjx
Reviewed By: DavidTruby, ichoyjx
Subscribers: jholewinski, cfe-commits, dblaikie, MaskRay, ymandel, ichoyjx, mgorny, yaxunl, guansong, jfb, sstefan1, aaron.ballman, llvm-commits
Tags: #llvm, #flang, #clang
Differential Revision: https://reviews.llvm.org/D82906
2020-07-02 08:57:11 +08:00
|
|
|
namespace llvm {
|
|
|
|
namespace omp {
|
|
|
|
static OmpDirectiveSet parallelSet{Directive::OMPD_distribute_parallel_do,
|
|
|
|
Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel,
|
|
|
|
Directive::OMPD_parallel_do, Directive::OMPD_parallel_do_simd,
|
|
|
|
Directive::OMPD_parallel_sections, Directive::OMPD_parallel_workshare,
|
|
|
|
Directive::OMPD_target_parallel, Directive::OMPD_target_parallel_do,
|
|
|
|
Directive::OMPD_target_parallel_do_simd,
|
|
|
|
Directive::OMPD_target_teams_distribute_parallel_do,
|
|
|
|
Directive::OMPD_target_teams_distribute_parallel_do_simd,
|
|
|
|
Directive::OMPD_teams_distribute_parallel_do,
|
|
|
|
Directive::OMPD_teams_distribute_parallel_do_simd};
|
|
|
|
static OmpDirectiveSet doSet{Directive::OMPD_distribute_parallel_do,
|
|
|
|
Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel,
|
|
|
|
Directive::OMPD_parallel_do, Directive::OMPD_parallel_do_simd,
|
|
|
|
Directive::OMPD_do, Directive::OMPD_do_simd,
|
|
|
|
Directive::OMPD_target_parallel_do, Directive::OMPD_target_parallel_do_simd,
|
|
|
|
Directive::OMPD_target_teams_distribute_parallel_do,
|
|
|
|
Directive::OMPD_target_teams_distribute_parallel_do_simd,
|
|
|
|
Directive::OMPD_teams_distribute_parallel_do,
|
|
|
|
Directive::OMPD_teams_distribute_parallel_do_simd};
|
|
|
|
static OmpDirectiveSet doSimdSet{Directive::OMPD_distribute_parallel_do_simd,
|
|
|
|
Directive::OMPD_parallel_do_simd, Directive::OMPD_do_simd,
|
|
|
|
Directive::OMPD_target_parallel_do_simd,
|
|
|
|
Directive::OMPD_target_teams_distribute_parallel_do_simd,
|
|
|
|
Directive::OMPD_teams_distribute_parallel_do_simd};
|
|
|
|
static OmpDirectiveSet taskloopSet{
|
|
|
|
Directive::OMPD_taskloop, Directive::OMPD_taskloop_simd};
|
|
|
|
static OmpDirectiveSet targetSet{Directive::OMPD_target,
|
|
|
|
Directive::OMPD_target_parallel, Directive::OMPD_target_parallel_do,
|
|
|
|
Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_simd,
|
|
|
|
Directive::OMPD_target_teams, Directive::OMPD_target_teams_distribute,
|
|
|
|
Directive::OMPD_target_teams_distribute_simd};
|
|
|
|
static OmpDirectiveSet simdSet{Directive::OMPD_distribute_parallel_do_simd,
|
|
|
|
Directive::OMPD_distribute_simd, Directive::OMPD_parallel_do_simd,
|
|
|
|
Directive::OMPD_do_simd, Directive::OMPD_simd,
|
|
|
|
Directive::OMPD_target_parallel_do_simd,
|
|
|
|
Directive::OMPD_target_teams_distribute_parallel_do_simd,
|
|
|
|
Directive::OMPD_target_teams_distribute_simd, Directive::OMPD_target_simd,
|
|
|
|
Directive::OMPD_taskloop_simd,
|
|
|
|
Directive::OMPD_teams_distribute_parallel_do_simd,
|
|
|
|
Directive::OMPD_teams_distribute_simd};
|
|
|
|
static OmpDirectiveSet taskGeneratingSet{
|
|
|
|
OmpDirectiveSet{Directive::OMPD_task} | taskloopSet};
|
|
|
|
} // namespace omp
|
|
|
|
} // namespace llvm
|
2019-06-26 07:18:51 +08:00
|
|
|
|
|
|
|
namespace Fortran::semantics {
|
|
|
|
|
2020-08-06 02:20:26 +08:00
|
|
|
class OmpStructureChecker
|
|
|
|
: public DirectiveStructureChecker<llvm::omp::Directive, llvm::omp::Clause,
|
|
|
|
parser::OmpClause, llvm::omp::Clause_enumSize> {
|
2019-06-26 07:18:51 +08:00
|
|
|
public:
|
2020-08-06 02:20:26 +08:00
|
|
|
OmpStructureChecker(SemanticsContext &context)
|
|
|
|
: DirectiveStructureChecker(context,
|
|
|
|
#define GEN_FLANG_DIRECTIVE_CLAUSE_MAP
|
|
|
|
#include "llvm/Frontend/OpenMP/OMP.cpp.inc"
|
|
|
|
) {
|
|
|
|
}
|
2019-06-26 07:18:51 +08:00
|
|
|
|
2019-07-10 05:08:50 +08:00
|
|
|
void Enter(const parser::OpenMPConstruct &);
|
2019-06-26 07:18:51 +08:00
|
|
|
void Enter(const parser::OpenMPLoopConstruct &);
|
|
|
|
void Leave(const parser::OpenMPLoopConstruct &);
|
[flang] [OpenMP] parse tree changes for `OpenMPLoopConstruct` (flang-compiler/f18#656)
1. Following Block and Sections constructs, re-structure loop related
constructs into `{Begin, Loop, End}`. Being part of the work in
PR flang-compiler/f18#599, the `Loop` and `End` nodes are optional during parser. They
should be filled in during the phase of `CanonicalizationOfOmp`. This
commit is solely for the parse tree change. So, after this commit,
PR flang-compiler/f18#599 needs to be changed accordingly.
2. Removed parse tree nodes for `END DO` and `END DO SIMD`. Similar to
Block and Sections constructs, `End` node now accepts clauses too,
the validity checks are deferred into Semantics. This is more genernal
and error message could be better.
3. With this commit alone, assertion error would occur when `End` directive
is present, for example `!$OMP END DO` because the `End` node is not
moved into `OpenMPLoopConstruct` yet. Again, PR flang-compiler/f18#599 will handle that.
More tests will be added in PR flang-compiler/f18#599 and during the future Semantics work.
Original-commit: flang-compiler/f18@8cd1932fd61fa67f8ad5abfd337cf7a223ea89f4
Reviewed-on: https://github.com/flang-compiler/f18/pull/656
2019-08-15 06:16:27 +08:00
|
|
|
void Enter(const parser::OmpEndLoopDirective &);
|
2019-06-26 07:18:51 +08:00
|
|
|
|
|
|
|
void Enter(const parser::OpenMPBlockConstruct &);
|
|
|
|
void Leave(const parser::OpenMPBlockConstruct &);
|
[flang] [OpenMP] parse tree changes for `OpenMPBlockConstruct` (flang-compiler/f18#632)
* [OpenMP] parse tree changes for `OpenMPBlockConstruct`
1. merge `Workshare` and `Single` into `OpenMPBlockConstruct` because
they both accept structured-block and syntax is similar to other block
directives.
2. `OpenMPBlockConstruct` changes to structure like `{Begin, Block, End}`,
where `Begin` and `End` are tuple of `{Directive, ClauseList}`.
3. Updated the check-omp-structure.* for necessary parts. Added all the END
directive enumeration types that may have clauses.
More tests will be added during Semantics.
* [OpenMP] Update on Tim's suggestion
1. Fix unspecified enumeration for `OmpDirective` in the `OmpContext`.
This is through getting rid of `PushContext(source)` function to
make sure whenever it is about to push a NEW context, directive
source location and enumeration are available. To do that, I moved
around all the switches for directive into high level `Construct`'s
`Enter` node. Besides fixing the issue, the side benefit is that
whenever we call `GetContext().directive`, we are sure that the
`directive` here was set already.
2. When `Enter` the `OmpEndBlockDirective` node, partial context
information, such as directive source location or legal clause lists,
needs to be reset. The new directive source location should be
`OmpEndBlockDirective`'s `source`. The enumeration `directive`
should not be reset for the END directives that do not accept
clauses because nothing needs to be checked (for example any clause
that is on `END PARALLEL` is illegal).
Original-commit: flang-compiler/f18@e5bd6b7ba0fbe9006f3e431260428b194f2d2616
Reviewed-on: https://github.com/flang-compiler/f18/pull/632
2019-08-10 06:11:20 +08:00
|
|
|
void Enter(const parser::OmpEndBlockDirective &);
|
2019-06-26 07:18:51 +08:00
|
|
|
|
2019-08-02 05:32:33 +08:00
|
|
|
void Enter(const parser::OpenMPSectionsConstruct &);
|
|
|
|
void Leave(const parser::OpenMPSectionsConstruct &);
|
2019-08-14 23:42:28 +08:00
|
|
|
void Enter(const parser::OmpEndSectionsDirective &);
|
2019-08-02 05:32:33 +08:00
|
|
|
|
2019-08-06 05:51:02 +08:00
|
|
|
void Enter(const parser::OpenMPDeclareSimdConstruct &);
|
|
|
|
void Leave(const parser::OpenMPDeclareSimdConstruct &);
|
2019-08-21 01:23:56 +08:00
|
|
|
void Enter(const parser::OpenMPDeclareTargetConstruct &);
|
|
|
|
void Leave(const parser::OpenMPDeclareTargetConstruct &);
|
2019-08-02 05:32:33 +08:00
|
|
|
|
2019-08-07 02:59:40 +08:00
|
|
|
void Enter(const parser::OpenMPSimpleStandaloneConstruct &);
|
|
|
|
void Leave(const parser::OpenMPSimpleStandaloneConstruct &);
|
|
|
|
void Enter(const parser::OpenMPFlushConstruct &);
|
|
|
|
void Leave(const parser::OpenMPFlushConstruct &);
|
|
|
|
void Enter(const parser::OpenMPCancelConstruct &);
|
|
|
|
void Leave(const parser::OpenMPCancelConstruct &);
|
|
|
|
void Enter(const parser::OpenMPCancellationPointConstruct &);
|
|
|
|
void Leave(const parser::OpenMPCancellationPointConstruct &);
|
|
|
|
|
2019-07-02 04:55:06 +08:00
|
|
|
void Leave(const parser::OmpClauseList &);
|
2019-06-26 07:18:51 +08:00
|
|
|
void Enter(const parser::OmpClause &);
|
2019-08-02 05:32:33 +08:00
|
|
|
void Enter(const parser::OmpNowait &);
|
2019-06-26 07:18:51 +08:00
|
|
|
void Enter(const parser::OmpClause::Inbranch &);
|
|
|
|
void Enter(const parser::OmpClause::Mergeable &);
|
|
|
|
void Enter(const parser::OmpClause::Nogroup &);
|
|
|
|
void Enter(const parser::OmpClause::Notinbranch &);
|
|
|
|
void Enter(const parser::OmpClause::Untied &);
|
|
|
|
void Enter(const parser::OmpClause::Collapse &);
|
|
|
|
void Enter(const parser::OmpClause::Copyin &);
|
|
|
|
void Enter(const parser::OmpClause::Copyprivate &);
|
|
|
|
void Enter(const parser::OmpClause::Device &);
|
|
|
|
void Enter(const parser::OmpClause::Final &);
|
|
|
|
void Enter(const parser::OmpClause::Firstprivate &);
|
|
|
|
void Enter(const parser::OmpClause::From &);
|
|
|
|
void Enter(const parser::OmpClause::Grainsize &);
|
|
|
|
void Enter(const parser::OmpClause::Lastprivate &);
|
|
|
|
void Enter(const parser::OmpClause::NumTasks &);
|
|
|
|
void Enter(const parser::OmpClause::NumTeams &);
|
|
|
|
void Enter(const parser::OmpClause::NumThreads &);
|
|
|
|
void Enter(const parser::OmpClause::Ordered &);
|
|
|
|
void Enter(const parser::OmpClause::Priority &);
|
|
|
|
void Enter(const parser::OmpClause::Private &);
|
|
|
|
void Enter(const parser::OmpClause::Safelen &);
|
|
|
|
void Enter(const parser::OmpClause::Shared &);
|
|
|
|
void Enter(const parser::OmpClause::Simdlen &);
|
|
|
|
void Enter(const parser::OmpClause::ThreadLimit &);
|
|
|
|
void Enter(const parser::OmpClause::To &);
|
|
|
|
void Enter(const parser::OmpClause::Link &);
|
|
|
|
void Enter(const parser::OmpClause::Uniform &);
|
|
|
|
void Enter(const parser::OmpClause::UseDevicePtr &);
|
|
|
|
void Enter(const parser::OmpClause::IsDevicePtr &);
|
|
|
|
|
|
|
|
void Enter(const parser::OmpAlignedClause &);
|
2020-09-09 18:50:13 +08:00
|
|
|
void Enter(const parser::OmpAllocateClause &);
|
2019-06-26 07:18:51 +08:00
|
|
|
void Enter(const parser::OmpDefaultClause &);
|
2019-09-09 05:52:43 +08:00
|
|
|
void Enter(const parser::OmpDefaultmapClause &);
|
2019-06-26 07:18:51 +08:00
|
|
|
void Enter(const parser::OmpDependClause &);
|
2020-08-18 02:22:01 +08:00
|
|
|
void Enter(const parser::OmpDistScheduleClause &);
|
2019-06-26 07:18:51 +08:00
|
|
|
void Enter(const parser::OmpIfClause &);
|
|
|
|
void Enter(const parser::OmpLinearClause &);
|
|
|
|
void Enter(const parser::OmpMapClause &);
|
|
|
|
void Enter(const parser::OmpProcBindClause &);
|
|
|
|
void Enter(const parser::OmpReductionClause &);
|
|
|
|
void Enter(const parser::OmpScheduleClause &);
|
|
|
|
|
|
|
|
private:
|
[flang][openmp] Check clauses allowed semantic with tablegen generated map
Summary:
This patch is enabling the generation of clauses enum sets for semantics check in Flang through
tablegen. Enum sets and directive - sets map is generated by the new tablegen infrsatructure for OpenMP
and other directive languages.
The semantic checks for OpenMP are modified to use this newly generated map.
Reviewers: DavidTruby, sscalpone, kiranchandramohan, ichoyjx, jdoerfert
Reviewed By: DavidTruby, ichoyjx
Subscribers: mgorny, yaxunl, hiraditya, guansong, sstefan1, aaron.ballman, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D83326
2020-07-12 00:42:05 +08:00
|
|
|
|
2019-06-26 07:18:51 +08:00
|
|
|
bool HasInvalidWorksharingNesting(
|
|
|
|
const parser::CharBlock &, const OmpDirectiveSet &);
|
|
|
|
|
2019-07-02 04:55:06 +08:00
|
|
|
// specific clause related
|
|
|
|
bool ScheduleModifierHasType(const parser::OmpScheduleClause &,
|
|
|
|
const parser::OmpScheduleModifierType::ModType &);
|
|
|
|
|
2020-08-06 02:20:26 +08:00
|
|
|
llvm::StringRef getClauseName(llvm::omp::Clause clause) override;
|
|
|
|
llvm::StringRef getDirectiveName(llvm::omp::Directive directive) override;
|
2019-06-26 07:18:51 +08:00
|
|
|
};
|
2020-03-29 12:00:16 +08:00
|
|
|
} // namespace Fortran::semantics
|
|
|
|
#endif // FORTRAN_SEMANTICS_CHECK_OMP_STRUCTURE_H_
|