Skip to content

Commit

Permalink
[Flang][OpenMP][NFC][1/2] Reorder OmpStructureChecker and simplify it.
Browse files Browse the repository at this point in the history
`OmpStructureChecker` has too much boilerplate code in source file.
It was not easy to figure out the seperation of clauses inside 'OmpClause' and
the ones which had a seperate node in parse-tree.h.

This patch:
1. Removes the boilerplate by defining a few macros.
2. Makes seperation between constructs, directives and clauses(sub classes are seperated).
3. Macros could have been shared between OMP and OACC, template specilizations might have
   been costly hence used macros.
Follows the same strategy used for `AccStructureChecker`.

Next patch in series to simplify OmpStructureChecker would try to simplify
boilerplates inside the functions and either create abstractions or use if
something is available inside check-directive-structure.h

Reviewed By: kiranchandramohan, clementval

Differential Revision: https://reviews.llvm.org/D90324
  • Loading branch information
Sameeranjoshi committed Nov 3, 2020
1 parent ee63acc commit 855a32d
Showing 1 changed file with 76 additions and 120 deletions.
196 changes: 76 additions & 120 deletions flang/lib/Semantics/check-omp-structure.cpp
Expand Up @@ -12,6 +12,30 @@

namespace Fortran::semantics {

// Use when clause falls under 'struct OmpClause' in 'parse-tree.h'.
#define CHECK_SIMPLE_CLAUSE(X, Y) \
void OmpStructureChecker::Enter(const parser::OmpClause::X &) { \
CheckAllowed(llvm::omp::Clause::Y); \
}

#define CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(X, Y) \
void OmpStructureChecker::Enter(const parser::OmpClause::X &c) { \
CheckAllowed(llvm::omp::Clause::Y); \
RequiresConstantPositiveParameter(llvm::omp::Clause::Y, c.v); \
}

#define CHECK_REQ_SCALAR_INT_CLAUSE(X, Y) \
void OmpStructureChecker::Enter(const parser::OmpClause::X &c) { \
CheckAllowed(llvm::omp::Clause::Y); \
RequiresPositiveParameter(llvm::omp::Clause::Y, c.v); \
}

// Use when clause don't falls under 'struct OmpClause' in 'parse-tree.h'.
#define CHECK_SIMPLE_PARSER_CLAUSE(X, Y) \
void OmpStructureChecker::Enter(const parser::X &) { \
CheckAllowed(llvm::omp::Y); \
}

bool OmpStructureChecker::HasInvalidWorksharingNesting(
const parser::CharBlock &source, const OmpDirectiveSet &set) {
// set contains all the invalid closely nested directives
Expand Down Expand Up @@ -242,6 +266,12 @@ void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
}
}

// Clauses
// Mainly categorized as
// 1. Checks on 'OmpClauseList' from 'parse-tree.h'.
// 2. Checks on clauses which fall under 'struct OmpClause' from parse-tree.h.
// 3. Checks on clauses which are not in 'struct OmpClause' from parse-tree.h.

void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
// 2.7 Loop Construct Restriction
if (llvm::omp::doSet.test(GetContext().directive)) {
Expand Down Expand Up @@ -340,73 +370,41 @@ void OmpStructureChecker::Enter(const parser::OmpClause &x) {
SetContextClause(x);
}

void OmpStructureChecker::Enter(const parser::OmpNowait &) {
CheckAllowed(llvm::omp::Clause::OMPC_nowait);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Inbranch &) {
CheckAllowed(llvm::omp::Clause::OMPC_inbranch);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Mergeable &) {
CheckAllowed(llvm::omp::Clause::OMPC_mergeable);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Nogroup &) {
CheckAllowed(llvm::omp::Clause::OMPC_nogroup);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Notinbranch &) {
CheckAllowed(llvm::omp::Clause::OMPC_notinbranch);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Untied &) {
CheckAllowed(llvm::omp::Clause::OMPC_untied);
}

void OmpStructureChecker::Enter(const parser::OmpClause::Collapse &x) {
CheckAllowed(llvm::omp::Clause::OMPC_collapse);
// collapse clause must have a parameter
RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_collapse, x.v);
}

void OmpStructureChecker::Enter(const parser::OmpClause::Copyin &) {
CheckAllowed(llvm::omp::Clause::OMPC_copyin);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Copyprivate &) {
CheckAllowed(llvm::omp::Clause::OMPC_copyprivate);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Device &) {
CheckAllowed(llvm::omp::Clause::OMPC_device);
}
void OmpStructureChecker::Enter(const parser::OmpDistScheduleClause &) {
CheckAllowed(llvm::omp::Clause::OMPC_dist_schedule);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Final &) {
CheckAllowed(llvm::omp::Clause::OMPC_final);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Firstprivate &) {
CheckAllowed(llvm::omp::Clause::OMPC_firstprivate);
}
void OmpStructureChecker::Enter(const parser::OmpClause::From &) {
CheckAllowed(llvm::omp::Clause::OMPC_from);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Grainsize &x) {
CheckAllowed(llvm::omp::Clause::OMPC_grainsize);
RequiresPositiveParameter(llvm::omp::Clause::OMPC_grainsize, x.v);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &) {
CheckAllowed(llvm::omp::Clause::OMPC_lastprivate);
}
void OmpStructureChecker::Enter(const parser::OmpClause::NumTasks &x) {
CheckAllowed(llvm::omp::Clause::OMPC_num_tasks);
RequiresPositiveParameter(llvm::omp::Clause::OMPC_num_tasks, x.v);
}
void OmpStructureChecker::Enter(const parser::OmpClause::NumTeams &x) {
CheckAllowed(llvm::omp::Clause::OMPC_num_teams);
RequiresPositiveParameter(llvm::omp::Clause::OMPC_num_teams, x.v);
}
void OmpStructureChecker::Enter(const parser::OmpClause::NumThreads &x) {
CheckAllowed(llvm::omp::Clause::OMPC_num_threads);
RequiresPositiveParameter(llvm::omp::Clause::OMPC_num_threads, x.v);
// if parameter is variable, defer to Expression Analysis
}

// Following clauses do not have a seperate node in parse-tree.h.
// They fall under 'struct OmpClause' in parse-tree.h.
CHECK_SIMPLE_CLAUSE(Copyin, OMPC_copyin)
CHECK_SIMPLE_CLAUSE(Copyprivate, OMPC_copyprivate)
CHECK_SIMPLE_CLAUSE(Device, OMPC_device)
CHECK_SIMPLE_CLAUSE(Final, OMPC_final)
CHECK_SIMPLE_CLAUSE(Firstprivate, OMPC_firstprivate)
CHECK_SIMPLE_CLAUSE(From, OMPC_from)
CHECK_SIMPLE_CLAUSE(Inbranch, OMPC_inbranch)
CHECK_SIMPLE_CLAUSE(IsDevicePtr, OMPC_is_device_ptr)
CHECK_SIMPLE_CLAUSE(Lastprivate, OMPC_lastprivate)
CHECK_SIMPLE_CLAUSE(Link, OMPC_link)
CHECK_SIMPLE_CLAUSE(Mergeable, OMPC_mergeable)
CHECK_SIMPLE_CLAUSE(Nogroup, OMPC_nogroup)
CHECK_SIMPLE_CLAUSE(Notinbranch, OMPC_notinbranch)
CHECK_SIMPLE_CLAUSE(Private, OMPC_private)
CHECK_SIMPLE_CLAUSE(Shared, OMPC_shared)
CHECK_SIMPLE_CLAUSE(To, OMPC_to)
CHECK_SIMPLE_CLAUSE(Uniform, OMPC_uniform)
CHECK_SIMPLE_CLAUSE(Untied, OMPC_untied)
CHECK_SIMPLE_CLAUSE(UseDevicePtr, OMPC_use_device_ptr)

CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize)
CHECK_REQ_SCALAR_INT_CLAUSE(NumTasks, OMPC_num_tasks)
CHECK_REQ_SCALAR_INT_CLAUSE(NumTeams, OMPC_num_teams)
CHECK_REQ_SCALAR_INT_CLAUSE(NumThreads, OMPC_num_threads)
CHECK_REQ_SCALAR_INT_CLAUSE(Priority, OMPC_priority)
CHECK_REQ_SCALAR_INT_CLAUSE(ThreadLimit, OMPC_thread_limit)

CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Collapse, OMPC_collapse)
CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Safelen, OMPC_safelen)
CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Simdlen, OMPC_simdlen)

// Restrictions specific to each clause are implemented apart from the
// generalized restrictions.
void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
CheckAllowed(llvm::omp::Clause::OMPC_ordered);
// the parameter of ordered clause is optional
Expand All @@ -422,44 +420,18 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
}
}
}
void OmpStructureChecker::Enter(const parser::OmpClause::Priority &x) {
CheckAllowed(llvm::omp::Clause::OMPC_priority);
RequiresPositiveParameter(llvm::omp::Clause::OMPC_priority, x.v);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Private &) {
CheckAllowed(llvm::omp::Clause::OMPC_private);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Safelen &x) {
CheckAllowed(llvm::omp::Clause::OMPC_safelen);
RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_safelen, x.v);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Shared &) {
CheckAllowed(llvm::omp::Clause::OMPC_shared);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Simdlen &x) {
CheckAllowed(llvm::omp::Clause::OMPC_simdlen);
RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_simdlen, x.v);
}
void OmpStructureChecker::Enter(const parser::OmpClause::ThreadLimit &x) {
CheckAllowed(llvm::omp::Clause::OMPC_thread_limit);
RequiresPositiveParameter(llvm::omp::Clause::OMPC_thread_limit, x.v);
}
void OmpStructureChecker::Enter(const parser::OmpClause::To &) {
CheckAllowed(llvm::omp::Clause::OMPC_to);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Link &) {
CheckAllowed(llvm::omp::Clause::OMPC_link);
}
void OmpStructureChecker::Enter(const parser::OmpClause::Uniform &) {
CheckAllowed(llvm::omp::Clause::OMPC_uniform);
}
void OmpStructureChecker::Enter(const parser::OmpClause::UseDevicePtr &) {
CheckAllowed(llvm::omp::Clause::OMPC_use_device_ptr);
}
void OmpStructureChecker::Enter(const parser::OmpClause::IsDevicePtr &) {
CheckAllowed(llvm::omp::Clause::OMPC_is_device_ptr);
}

// Following clauses have a seperate node in parse-tree.h.
CHECK_SIMPLE_PARSER_CLAUSE(OmpAllocateClause, OMPC_allocate)
CHECK_SIMPLE_PARSER_CLAUSE(OmpDefaultClause, OMPC_default)
CHECK_SIMPLE_PARSER_CLAUSE(OmpDependClause, OMPC_depend)
CHECK_SIMPLE_PARSER_CLAUSE(OmpDistScheduleClause, OMPC_dist_schedule)
CHECK_SIMPLE_PARSER_CLAUSE(OmpNowait, OMPC_nowait)
CHECK_SIMPLE_PARSER_CLAUSE(OmpProcBindClause, OMPC_proc_bind)
CHECK_SIMPLE_PARSER_CLAUSE(OmpReductionClause, OMPC_reduction)

// Restrictions specific to each clause are implemented apart from the
// generalized restrictions.
void OmpStructureChecker::Enter(const parser::OmpAlignedClause &x) {
CheckAllowed(llvm::omp::Clause::OMPC_aligned);

Expand All @@ -475,12 +447,6 @@ void OmpStructureChecker::Enter(const parser::OmpAlignedClause &x) {
}
// 2.8.1 TODO: list-item attribute check
}
void OmpStructureChecker::Enter(const parser::OmpAllocateClause &) {
CheckAllowed(llvm::omp::Clause::OMPC_allocate);
}
void OmpStructureChecker::Enter(const parser::OmpDefaultClause &) {
CheckAllowed(llvm::omp::Clause::OMPC_default);
}
void OmpStructureChecker::Enter(const parser::OmpDefaultmapClause &x) {
CheckAllowed(llvm::omp::Clause::OMPC_defaultmap);
using VariableCategory = parser::OmpDefaultmapClause::VariableCategory;
Expand All @@ -490,10 +456,6 @@ void OmpStructureChecker::Enter(const parser::OmpDefaultmapClause &x) {
"clause"_err_en_US);
}
}
void OmpStructureChecker::Enter(const parser::OmpDependClause &) {
CheckAllowed(llvm::omp::Clause::OMPC_depend);
}

void OmpStructureChecker::Enter(const parser::OmpIfClause &x) {
CheckAllowed(llvm::omp::Clause::OMPC_if);

Expand Down Expand Up @@ -582,12 +544,6 @@ void OmpStructureChecker::Enter(const parser::OmpMapClause &x) {
}
}
}
void OmpStructureChecker::Enter(const parser::OmpProcBindClause &) {
CheckAllowed(llvm::omp::Clause::OMPC_proc_bind);
}
void OmpStructureChecker::Enter(const parser::OmpReductionClause &) {
CheckAllowed(llvm::omp::Clause::OMPC_reduction);
}

bool OmpStructureChecker::ScheduleModifierHasType(
const parser::OmpScheduleClause &x,
Expand Down

0 comments on commit 855a32d

Please sign in to comment.