[flang] [OpenMP] parse tree changes for standalone directives (flang-compiler/f18#627)
* [OpenMP] parse tree changes for standalone directives 1. Put all standalone directives except FLUSH, CANCEL, and CANCELLATION POINT into one `OpenMPSimpleStandaloneConstruct` (for no-clause directive, validity checks will be deferred to Semantics). A top-level class will include all the standalone directive nodes. This simplies the logic a lot. 2. All the standalone directives now have their own source provenance for directive name itself. 3. Change check-omp-structure.* to avoid assertions 4. Add basic tests for standalone directives, more will be added during the clause validity checks in Semantics * Resolve !$OMP ORDERED ambiguity by attempting block construct first - Peter Original-commit: flang-compiler/f18@a77aa7ed84 Reviewed-on: https://github.com/flang-compiler/f18/pull/627
This commit is contained in:
parent
fb30d812e7
commit
c4e13f6be8
|
@ -512,8 +512,8 @@ public:
|
||||||
NODE(parser, OmpScheduleModifierType)
|
NODE(parser, OmpScheduleModifierType)
|
||||||
NODE_ENUM(parser::OmpScheduleModifierType, ModType)
|
NODE_ENUM(parser::OmpScheduleModifierType, ModType)
|
||||||
NODE(parser, OmpSection)
|
NODE(parser, OmpSection)
|
||||||
NODE(parser, OmpStandaloneDirective)
|
NODE(parser, OmpSimpleStandaloneDirective)
|
||||||
NODE_ENUM(parser::OmpStandaloneDirective, Directive)
|
NODE_ENUM(parser::OmpSimpleStandaloneDirective, Directive)
|
||||||
NODE(parser, Only)
|
NODE(parser, Only)
|
||||||
NODE(parser, OpenMPAtomicConstruct)
|
NODE(parser, OpenMPAtomicConstruct)
|
||||||
NODE(parser, OpenMPBlockConstruct)
|
NODE(parser, OpenMPBlockConstruct)
|
||||||
|
@ -535,8 +535,7 @@ public:
|
||||||
NODE(parser, OpenMPEndLoopDirective)
|
NODE(parser, OpenMPEndLoopDirective)
|
||||||
NODE(parser, OpenMPFlushConstruct)
|
NODE(parser, OpenMPFlushConstruct)
|
||||||
NODE(parser, OpenMPLoopConstruct)
|
NODE(parser, OpenMPLoopConstruct)
|
||||||
NODE(parser, OpenMPSimpleConstruct)
|
NODE(parser, OpenMPSimpleStandaloneConstruct)
|
||||||
NODE_ENUM(parser::OpenMPSimpleConstruct, Directive)
|
|
||||||
NODE(parser, OpenMPStandaloneConstruct)
|
NODE(parser, OpenMPStandaloneConstruct)
|
||||||
NODE(parser, OpenMPSectionsConstruct)
|
NODE(parser, OpenMPSectionsConstruct)
|
||||||
NODE(parser, OpenMPSingleConstruct)
|
NODE(parser, OpenMPSingleConstruct)
|
||||||
|
|
|
@ -297,25 +297,42 @@ TYPE_PARSER(sourced(construct<OmpCancelType>(
|
||||||
"TASKGROUP" >> pure(OmpCancelType::Type::Taskgroup)))))
|
"TASKGROUP" >> pure(OmpCancelType::Type::Taskgroup)))))
|
||||||
|
|
||||||
// Cancellation Point construct
|
// Cancellation Point construct
|
||||||
TYPE_PARSER(construct<OpenMPCancellationPointConstruct>(
|
TYPE_PARSER(sourced(construct<OpenMPCancellationPointConstruct>(
|
||||||
sourced("CANCELLATION POINT" >> Parser<OmpCancelType>{})))
|
verbatim("CANCELLATION POINT"_tok), Parser<OmpCancelType>{})))
|
||||||
|
|
||||||
// Cancel construct
|
// Cancel construct
|
||||||
TYPE_PARSER(construct<OpenMPCancelConstruct>(
|
TYPE_PARSER(sourced(construct<OpenMPCancelConstruct>(verbatim("CANCEL"_tok),
|
||||||
sourced("CANCEL" >> Parser<OmpCancelType>{}),
|
Parser<OmpCancelType>{}, maybe("IF" >> parenthesized(scalarLogicalExpr)))))
|
||||||
maybe("IF" >> parenthesized(scalarLogicalExpr))))
|
|
||||||
|
|
||||||
// Flush construct
|
// Flush construct
|
||||||
TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(
|
TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(
|
||||||
"FLUSH" >> maybe(parenthesized(Parser<OmpObjectList>{})))))
|
verbatim("FLUSH"_tok), maybe(parenthesized(Parser<OmpObjectList>{})))))
|
||||||
|
|
||||||
// Standalone directives
|
// Simple Standalone Directives
|
||||||
TYPE_PARSER(sourced(construct<OmpStandaloneDirective>(first(
|
TYPE_PARSER(sourced(construct<OmpSimpleStandaloneDirective>(first(
|
||||||
|
"BARRIER" >> pure(OmpSimpleStandaloneDirective::Directive::Barrier),
|
||||||
|
"ORDERED" >> pure(OmpSimpleStandaloneDirective::Directive::Ordered),
|
||||||
"TARGET ENTER DATA" >>
|
"TARGET ENTER DATA" >>
|
||||||
pure(OmpStandaloneDirective::Directive::TargetEnterData),
|
pure(OmpSimpleStandaloneDirective::Directive::TargetEnterData),
|
||||||
"TARGET EXIT DATA" >>
|
"TARGET EXIT DATA" >>
|
||||||
pure(OmpStandaloneDirective::Directive::TargetExitData),
|
pure(OmpSimpleStandaloneDirective::Directive::TargetExitData),
|
||||||
"TARGET UPDATE" >> pure(OmpStandaloneDirective::Directive::TargetUpdate)))))
|
"TARGET UPDATE" >>
|
||||||
|
pure(OmpSimpleStandaloneDirective::Directive::TargetUpdate),
|
||||||
|
"TASKWAIT" >> pure(OmpSimpleStandaloneDirective::Directive::Taskwait),
|
||||||
|
"TASKYIELD" >> pure(OmpSimpleStandaloneDirective::Directive::Taskyield)))))
|
||||||
|
|
||||||
|
TYPE_PARSER(sourced(construct<OpenMPSimpleStandaloneConstruct>(
|
||||||
|
Parser<OmpSimpleStandaloneDirective>{}, Parser<OmpClauseList>{})))
|
||||||
|
|
||||||
|
// Standalone Constructs
|
||||||
|
TYPE_PARSER(
|
||||||
|
sourced(construct<OpenMPStandaloneConstruct>(
|
||||||
|
Parser<OpenMPSimpleStandaloneConstruct>{}) ||
|
||||||
|
construct<OpenMPStandaloneConstruct>(Parser<OpenMPFlushConstruct>{}) ||
|
||||||
|
construct<OpenMPStandaloneConstruct>(Parser<OpenMPCancelConstruct>{}) ||
|
||||||
|
construct<OpenMPStandaloneConstruct>(
|
||||||
|
Parser<OpenMPCancellationPointConstruct>{})) /
|
||||||
|
endOfLine)
|
||||||
|
|
||||||
// Directives enclosing structured-block
|
// Directives enclosing structured-block
|
||||||
TYPE_PARSER(sourced(construct<OmpBlockDirective>(
|
TYPE_PARSER(sourced(construct<OmpBlockDirective>(
|
||||||
|
@ -454,17 +471,6 @@ TYPE_PARSER(construct<OpenMPBlockConstruct>(Parser<OmpBlockDirective>{},
|
||||||
Parser<OmpClauseList>{} / endOmpLine, block,
|
Parser<OmpClauseList>{} / endOmpLine, block,
|
||||||
Parser<OmpEndBlockDirective>{}))
|
Parser<OmpEndBlockDirective>{}))
|
||||||
|
|
||||||
// Simple constructs without clauses
|
|
||||||
TYPE_PARSER(
|
|
||||||
sourced(construct<OpenMPSimpleConstruct>(first(
|
|
||||||
"BARRIER" >> pure(OpenMPSimpleConstruct::Directive::Barrier),
|
|
||||||
"TASKWAIT" >> pure(OpenMPSimpleConstruct::Directive::Taskwait),
|
|
||||||
"TASKYIELD" >> pure(OpenMPSimpleConstruct::Directive::Taskyield)))) /
|
|
||||||
endOmpLine)
|
|
||||||
|
|
||||||
TYPE_PARSER(construct<OpenMPStandaloneConstruct>(
|
|
||||||
Parser<OmpStandaloneDirective>{}, Parser<OmpClauseList>{} / endOmpLine))
|
|
||||||
|
|
||||||
// OMP SINGLE
|
// OMP SINGLE
|
||||||
TYPE_PARSER(startOmpLine >> construct<OmpEndSingle>(verbatim("END SINGLE"_tok),
|
TYPE_PARSER(startOmpLine >> construct<OmpEndSingle>(verbatim("END SINGLE"_tok),
|
||||||
Parser<OmpClauseList>{}) /
|
Parser<OmpClauseList>{}) /
|
||||||
|
@ -507,21 +513,18 @@ TYPE_PARSER(construct<OmpSection>(verbatim("SECTION"_tok) / endOmpLine))
|
||||||
|
|
||||||
TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
|
TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
|
||||||
startOmpLine >>
|
startOmpLine >>
|
||||||
first(construct<OpenMPConstruct>(Parser<OpenMPStandaloneConstruct>{}),
|
first(construct<OpenMPConstruct>(Parser<OpenMPSingleConstruct>{}),
|
||||||
construct<OpenMPConstruct>(Parser<OpenMPSimpleConstruct>{}),
|
|
||||||
construct<OpenMPConstruct>(Parser<OpenMPSingleConstruct>{}),
|
|
||||||
construct<OpenMPConstruct>(Parser<OpenMPSectionsConstruct>{}),
|
construct<OpenMPConstruct>(Parser<OpenMPSectionsConstruct>{}),
|
||||||
construct<OpenMPConstruct>(
|
construct<OpenMPConstruct>(
|
||||||
Parser<OpenMPParallelSectionsConstruct>{}),
|
Parser<OpenMPParallelSectionsConstruct>{}),
|
||||||
construct<OpenMPConstruct>(Parser<OpenMPWorkshareConstruct>{}),
|
construct<OpenMPConstruct>(Parser<OpenMPWorkshareConstruct>{}),
|
||||||
construct<OpenMPConstruct>(Parser<OpenMPLoopConstruct>{}),
|
construct<OpenMPConstruct>(Parser<OpenMPLoopConstruct>{}),
|
||||||
construct<OpenMPConstruct>(Parser<OpenMPBlockConstruct>{}),
|
construct<OpenMPConstruct>(Parser<OpenMPBlockConstruct>{}),
|
||||||
|
// OpenMPBlockConstruct is attempted before
|
||||||
|
// OpenMPStandaloneConstruct to resolve !$OMP ORDERED
|
||||||
|
construct<OpenMPConstruct>(Parser<OpenMPStandaloneConstruct>{}),
|
||||||
construct<OpenMPConstruct>(Parser<OpenMPAtomicConstruct>{}),
|
construct<OpenMPConstruct>(Parser<OpenMPAtomicConstruct>{}),
|
||||||
construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}),
|
construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}),
|
||||||
construct<OpenMPConstruct>(Parser<OpenMPCancelConstruct>{}),
|
|
||||||
construct<OpenMPConstruct>(
|
|
||||||
Parser<OpenMPCancellationPointConstruct>{}),
|
|
||||||
construct<OpenMPConstruct>(Parser<OpenMPFlushConstruct>{}),
|
|
||||||
construct<OpenMPConstruct>(Parser<OmpSection>{})))
|
construct<OpenMPConstruct>(Parser<OmpSection>{})))
|
||||||
|
|
||||||
// END OMP Block directives
|
// END OMP Block directives
|
||||||
|
|
|
@ -3666,38 +3666,47 @@ struct OmpCancelType {
|
||||||
};
|
};
|
||||||
|
|
||||||
// CANCELLATION POINT
|
// CANCELLATION POINT
|
||||||
WRAPPER_CLASS(OpenMPCancellationPointConstruct, OmpCancelType);
|
struct OpenMPCancellationPointConstruct {
|
||||||
|
TUPLE_CLASS_BOILERPLATE(OpenMPCancellationPointConstruct);
|
||||||
|
CharBlock source;
|
||||||
|
std::tuple<Verbatim, OmpCancelType> t;
|
||||||
|
};
|
||||||
|
|
||||||
// CANCEL
|
// CANCEL
|
||||||
struct OpenMPCancelConstruct {
|
struct OpenMPCancelConstruct {
|
||||||
TUPLE_CLASS_BOILERPLATE(OpenMPCancelConstruct);
|
TUPLE_CLASS_BOILERPLATE(OpenMPCancelConstruct);
|
||||||
WRAPPER_CLASS(If, ScalarLogicalExpr);
|
WRAPPER_CLASS(If, ScalarLogicalExpr);
|
||||||
std::tuple<OmpCancelType, std::optional<If>> t;
|
CharBlock source;
|
||||||
|
std::tuple<Verbatim, OmpCancelType, std::optional<If>> t;
|
||||||
};
|
};
|
||||||
|
|
||||||
// FLUSH
|
// FLUSH
|
||||||
struct OpenMPFlushConstruct {
|
struct OpenMPFlushConstruct {
|
||||||
WRAPPER_CLASS_BOILERPLATE(OpenMPFlushConstruct, std::optional<OmpObjectList>);
|
TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct);
|
||||||
CharBlock source;
|
CharBlock source;
|
||||||
|
std::tuple<Verbatim, std::optional<OmpObjectList>> t;
|
||||||
};
|
};
|
||||||
|
|
||||||
// These simple constructs do not have clauses.
|
// These simple constructs do not have clauses.
|
||||||
struct OpenMPSimpleConstruct {
|
struct OmpSimpleStandaloneDirective {
|
||||||
ENUM_CLASS(Directive, Barrier, Taskwait, Taskyield)
|
ENUM_CLASS(Directive, Barrier, Taskwait, Taskyield, TargetEnterData,
|
||||||
WRAPPER_CLASS_BOILERPLATE(OpenMPSimpleConstruct, Directive);
|
TargetExitData, TargetUpdate, Ordered)
|
||||||
|
WRAPPER_CLASS_BOILERPLATE(OmpSimpleStandaloneDirective, Directive);
|
||||||
CharBlock source;
|
CharBlock source;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Standalone constructs; these can have clauses.
|
struct OpenMPSimpleStandaloneConstruct {
|
||||||
struct OmpStandaloneDirective {
|
TUPLE_CLASS_BOILERPLATE(OpenMPSimpleStandaloneConstruct);
|
||||||
ENUM_CLASS(Directive, TargetEnterData, TargetExitData, TargetUpdate)
|
|
||||||
WRAPPER_CLASS_BOILERPLATE(OmpStandaloneDirective, Directive);
|
|
||||||
CharBlock source;
|
CharBlock source;
|
||||||
|
std::tuple<OmpSimpleStandaloneDirective, OmpClauseList> t;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OpenMPStandaloneConstruct {
|
struct OpenMPStandaloneConstruct {
|
||||||
TUPLE_CLASS_BOILERPLATE(OpenMPStandaloneConstruct);
|
UNION_CLASS_BOILERPLATE(OpenMPStandaloneConstruct);
|
||||||
std::tuple<OmpStandaloneDirective, OmpClauseList> t;
|
CharBlock source;
|
||||||
|
std::variant<OpenMPSimpleStandaloneConstruct, OpenMPFlushConstruct,
|
||||||
|
OpenMPCancelConstruct, OpenMPCancellationPointConstruct>
|
||||||
|
u;
|
||||||
};
|
};
|
||||||
|
|
||||||
WRAPPER_CLASS(OmpEndBlockDirective, OmpBlockDirective);
|
WRAPPER_CLASS(OmpEndBlockDirective, OmpBlockDirective);
|
||||||
|
@ -3722,13 +3731,10 @@ struct OpenMPLoopConstruct {
|
||||||
|
|
||||||
struct OpenMPConstruct {
|
struct OpenMPConstruct {
|
||||||
UNION_CLASS_BOILERPLATE(OpenMPConstruct);
|
UNION_CLASS_BOILERPLATE(OpenMPConstruct);
|
||||||
std::variant<OpenMPStandaloneConstruct, OpenMPSimpleConstruct,
|
std::variant<OpenMPStandaloneConstruct, OpenMPSingleConstruct,
|
||||||
OpenMPSingleConstruct, OpenMPSectionsConstruct,
|
OpenMPSectionsConstruct, OpenMPParallelSectionsConstruct,
|
||||||
OpenMPParallelSectionsConstruct, OpenMPWorkshareConstruct,
|
OpenMPWorkshareConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct,
|
||||||
OpenMPLoopConstruct, OpenMPBlockConstruct,
|
OpenMPAtomicConstruct, OpenMPCriticalConstruct, OmpSection>
|
||||||
OpenMPCancellationPointConstruct, OpenMPCancelConstruct,
|
|
||||||
OpenMPFlushConstruct, OpenMPAtomicConstruct, OpenMPCriticalConstruct,
|
|
||||||
OmpSection>
|
|
||||||
u;
|
u;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2046,17 +2046,29 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Unparse(const OmpObjectList &x) { Walk(x.v, ","); }
|
void Unparse(const OmpObjectList &x) { Walk(x.v, ","); }
|
||||||
void Unparse(const OmpStandaloneDirective &x) {
|
void Unparse(const OmpSimpleStandaloneDirective &x) {
|
||||||
switch (x.v) {
|
switch (x.v) {
|
||||||
case OmpStandaloneDirective::Directive::TargetEnterData:
|
case OmpSimpleStandaloneDirective::Directive::Barrier:
|
||||||
|
Word("BARRIER ");
|
||||||
|
break;
|
||||||
|
case OmpSimpleStandaloneDirective::Directive::Taskwait:
|
||||||
|
Word("TASKWAIT ");
|
||||||
|
break;
|
||||||
|
case OmpSimpleStandaloneDirective::Directive::Taskyield:
|
||||||
|
Word("TASKYIELD ");
|
||||||
|
break;
|
||||||
|
case OmpSimpleStandaloneDirective::Directive::TargetEnterData:
|
||||||
Word("TARGET ENTER DATA ");
|
Word("TARGET ENTER DATA ");
|
||||||
break;
|
break;
|
||||||
case OmpStandaloneDirective::Directive::TargetExitData:
|
case OmpSimpleStandaloneDirective::Directive::TargetExitData:
|
||||||
Word("TARGET EXIT DATA ");
|
Word("TARGET EXIT DATA ");
|
||||||
break;
|
break;
|
||||||
case OmpStandaloneDirective::Directive::TargetUpdate:
|
case OmpSimpleStandaloneDirective::Directive::TargetUpdate:
|
||||||
Word("TARGET UPDATE ");
|
Word("TARGET UPDATE ");
|
||||||
break;
|
break;
|
||||||
|
case OmpSimpleStandaloneDirective::Directive::Ordered:
|
||||||
|
Word("ORDERED ");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Unparse(const OmpBlockDirective &x) {
|
void Unparse(const OmpBlockDirective &x) {
|
||||||
|
@ -2305,7 +2317,7 @@ public:
|
||||||
void Unparse(const OpenMPCancellationPointConstruct &x) {
|
void Unparse(const OpenMPCancellationPointConstruct &x) {
|
||||||
BeginOpenMP();
|
BeginOpenMP();
|
||||||
Word("!$OMP CANCELLATION POINT ");
|
Word("!$OMP CANCELLATION POINT ");
|
||||||
Walk(x.v);
|
Walk(std::get<OmpCancelType>(x.t));
|
||||||
Put("\n");
|
Put("\n");
|
||||||
EndOpenMP();
|
EndOpenMP();
|
||||||
}
|
}
|
||||||
|
@ -2320,11 +2332,7 @@ public:
|
||||||
void Unparse(const OpenMPFlushConstruct &x) {
|
void Unparse(const OpenMPFlushConstruct &x) {
|
||||||
BeginOpenMP();
|
BeginOpenMP();
|
||||||
Word("!$OMP FLUSH");
|
Word("!$OMP FLUSH");
|
||||||
if ((x.v).has_value()) {
|
Walk("(", std::get<std::optional<OmpObjectList>>(x.t), ")");
|
||||||
Put("(");
|
|
||||||
Walk(x.v);
|
|
||||||
Put(")");
|
|
||||||
}
|
|
||||||
Put("\n");
|
Put("\n");
|
||||||
EndOpenMP();
|
EndOpenMP();
|
||||||
}
|
}
|
||||||
|
@ -2338,21 +2346,10 @@ public:
|
||||||
EndOpenMP();
|
EndOpenMP();
|
||||||
}
|
}
|
||||||
void Unparse(const OmpClauseList &x) { Walk(" ", x.v, " "); }
|
void Unparse(const OmpClauseList &x) { Walk(" ", x.v, " "); }
|
||||||
void Unparse(const OpenMPSimpleConstruct &x) {
|
void Unparse(const OpenMPSimpleStandaloneConstruct &x) {
|
||||||
BeginOpenMP();
|
BeginOpenMP();
|
||||||
Word("!$OMP ");
|
Word("!$OMP ");
|
||||||
switch (x.v) {
|
Walk(std::get<OmpSimpleStandaloneDirective>(x.t));
|
||||||
case OpenMPSimpleConstruct::Directive::Barrier: Word("BARRIER"); break;
|
|
||||||
case OpenMPSimpleConstruct::Directive::Taskwait: Word("TASKWAIT"); break;
|
|
||||||
case OpenMPSimpleConstruct::Directive::Taskyield: Word("TASKYIELD"); break;
|
|
||||||
}
|
|
||||||
Put("\n");
|
|
||||||
EndOpenMP();
|
|
||||||
}
|
|
||||||
void Unparse(const OpenMPStandaloneConstruct &x) {
|
|
||||||
BeginOpenMP();
|
|
||||||
Word("!$OMP ");
|
|
||||||
Walk(std::get<OmpStandaloneDirective>(x.t));
|
|
||||||
Walk(std::get<OmpClauseList>(x.t));
|
Walk(std::get<OmpClauseList>(x.t));
|
||||||
Put("\n");
|
Put("\n");
|
||||||
EndOpenMP();
|
EndOpenMP();
|
||||||
|
|
|
@ -104,7 +104,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
|
||||||
SetContextAllowed(allowed);
|
SetContextAllowed(allowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &x) {
|
void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) {
|
||||||
ompContext_.pop_back();
|
ompContext_.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPSingleConstruct &x) {
|
||||||
SetContextAllowed(allowed);
|
SetContextAllowed(allowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OmpStructureChecker::Leave(const parser::OpenMPSingleConstruct &x) {
|
void OmpStructureChecker::Leave(const parser::OpenMPSingleConstruct &) {
|
||||||
ompContext_.pop_back();
|
ompContext_.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ void OmpStructureChecker::Enter(const parser::OmpEndSingle &x) {
|
||||||
SetContextAllowedOnce(allowedOnce);
|
SetContextAllowedOnce(allowedOnce);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OmpStructureChecker::Leave(const parser::OmpEndSingle &x) {
|
void OmpStructureChecker::Leave(const parser::OmpEndSingle &) {
|
||||||
ompContext_.pop_back();
|
ompContext_.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPWorkshareConstruct &x) {
|
||||||
PushContext(dir.source, OmpDirective::WORKSHARE);
|
PushContext(dir.source, OmpDirective::WORKSHARE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OmpStructureChecker::Leave(const parser::OpenMPWorkshareConstruct &x) {
|
void OmpStructureChecker::Leave(const parser::OpenMPWorkshareConstruct &) {
|
||||||
ompContext_.pop_back();
|
ompContext_.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,10 +158,64 @@ void OmpStructureChecker::Enter(const parser::OpenMPDeclareSimdConstruct &x) {
|
||||||
PushContext(dir.source, OmpDirective::DECLARE_SIMD);
|
PushContext(dir.source, OmpDirective::DECLARE_SIMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &x) {
|
void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
|
||||||
ompContext_.pop_back();
|
ompContext_.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Enter(
|
||||||
|
const parser::OpenMPSimpleStandaloneConstruct &x) {
|
||||||
|
const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(x.t)};
|
||||||
|
PushContext(dir.source);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Leave(
|
||||||
|
const parser::OpenMPSimpleStandaloneConstruct &) {
|
||||||
|
ompContext_.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Enter(const parser::OpenMPFlushConstruct &x) {
|
||||||
|
const auto &dir{std::get<parser::Verbatim>(x.t)};
|
||||||
|
PushContext(dir.source, OmpDirective::FLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &) {
|
||||||
|
ompContext_.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Enter(const parser::OpenMPCancelConstruct &x) {
|
||||||
|
const auto &dir{std::get<parser::Verbatim>(x.t)};
|
||||||
|
PushContext(dir.source, OmpDirective::CANCEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Leave(const parser::OpenMPCancelConstruct &) {
|
||||||
|
ompContext_.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Enter(
|
||||||
|
const parser::OpenMPCancellationPointConstruct &x) {
|
||||||
|
const auto &dir{std::get<parser::Verbatim>(x.t)};
|
||||||
|
PushContext(dir.source, OmpDirective::CANCELLATION_POINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Leave(
|
||||||
|
const parser::OpenMPCancellationPointConstruct &) {
|
||||||
|
ompContext_.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Enter(const parser::OmpSimpleStandaloneDirective &x) {
|
||||||
|
switch (x.v) {
|
||||||
|
case parser::OmpSimpleStandaloneDirective::Directive::Ordered: {
|
||||||
|
// 2.13.8 ordered-construct-clause -> depend-clause
|
||||||
|
SetContextDirectiveEnum(OmpDirective::ORDERED);
|
||||||
|
OmpClauseSet allowed{OmpClause::DEPEND};
|
||||||
|
SetContextAllowed(allowed);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// TODO others
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OmpStructureChecker::Enter(const parser::OmpBlockDirective &x) {
|
void OmpStructureChecker::Enter(const parser::OmpBlockDirective &x) {
|
||||||
switch (x.v) {
|
switch (x.v) {
|
||||||
// 2.5 parallel-clause -> if-clause |
|
// 2.5 parallel-clause -> if-clause |
|
||||||
|
|
|
@ -79,6 +79,16 @@ public:
|
||||||
void Enter(const parser::OpenMPDeclareSimdConstruct &);
|
void Enter(const parser::OpenMPDeclareSimdConstruct &);
|
||||||
void Leave(const parser::OpenMPDeclareSimdConstruct &);
|
void Leave(const parser::OpenMPDeclareSimdConstruct &);
|
||||||
|
|
||||||
|
void Enter(const parser::OpenMPSimpleStandaloneConstruct &);
|
||||||
|
void Leave(const parser::OpenMPSimpleStandaloneConstruct &);
|
||||||
|
void Enter(const parser::OmpSimpleStandaloneDirective &);
|
||||||
|
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 &);
|
||||||
|
|
||||||
void Leave(const parser::OmpClauseList &);
|
void Leave(const parser::OmpClauseList &);
|
||||||
void Enter(const parser::OmpClause &);
|
void Enter(const parser::OmpClause &);
|
||||||
void Enter(const parser::OmpNowait &);
|
void Enter(const parser::OmpNowait &);
|
||||||
|
|
|
@ -25,6 +25,10 @@
|
||||||
integer :: b = 128
|
integer :: b = 128
|
||||||
integer :: c = 32
|
integer :: c = 32
|
||||||
integer, parameter :: num = 16
|
integer, parameter :: num = 16
|
||||||
|
real(8) :: arrayA(256), arrayB(512)
|
||||||
|
|
||||||
|
arrayA = 1.414
|
||||||
|
arrayB = 3.14
|
||||||
N = 1024
|
N = 1024
|
||||||
|
|
||||||
! 2.5 parallel-clause -> if-clause |
|
! 2.5 parallel-clause -> if-clause |
|
||||||
|
@ -276,4 +280,19 @@
|
||||||
a = 3.14
|
a = 3.14
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
end
|
|
||||||
|
! Standalone Directives (basic)
|
||||||
|
|
||||||
|
!$omp taskyield
|
||||||
|
!$omp barrier
|
||||||
|
!$omp taskwait
|
||||||
|
! !$omp target enter data map(to:arrayA) map(alloc:arrayB)
|
||||||
|
! !$omp target update from(arrayA) to(arrayB)
|
||||||
|
! !$omp target exit data map(from:arrayA) map(delete:arrayB)
|
||||||
|
!$omp ordered depend(source)
|
||||||
|
!ERROR: Internal: no symbol found for 'i'
|
||||||
|
!$omp ordered depend(sink:i-1)
|
||||||
|
!$omp flush (c)
|
||||||
|
!$omp cancel DO
|
||||||
|
!$omp cancellation point parallel
|
||||||
|
end program
|
||||||
|
|
Loading…
Reference in a new issue