Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion flang/examples/FeatureList/FeatureList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,6 @@ struct NodeVisitor {
READ_FEATURE(OmpOrderingModifier::Value)
READ_FEATURE(OmpSectionBlocks)
READ_FEATURE(OmpSectionsDirective)
READ_FEATURE(OmpSimpleStandaloneDirective)
READ_FEATURE(Only)
READ_FEATURE(OpenACCAtomicConstruct)
READ_FEATURE(OpenACCBlockConstruct)
Expand Down
15 changes: 11 additions & 4 deletions flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,17 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
Fortran::common::visitors{
[&](const OpenMPStandaloneConstruct &c) -> std::string {
return std::visit(
[&](const auto &c) {
// Get source from the directive or verbatim fields
const CharBlock &source{std::get<0>(c.t).source};
return normalize_construct_name(source.ToString());
Fortran::common::visitors{
[&](const OpenMPSimpleStandaloneConstruct &d) {
const CharBlock &source{
std::get<OmpDirectiveName>(d.v.t).source};
return normalize_construct_name(source.ToString());
},
[&](const auto &c) {
// Get source from the directive or verbatim fields
const CharBlock &source{std::get<0>(c.t).source};
return normalize_construct_name(source.ToString());
},
},
c.u);
},
Expand Down
1 change: 0 additions & 1 deletion flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,6 @@ class ParseTreeDumper {
NODE_ENUM(OmpOrderingModifier, Value)
NODE(parser, OmpSectionBlocks)
NODE(parser, OmpSectionsDirective)
NODE(parser, OmpSimpleStandaloneDirective)
NODE(parser, OmpToClause)
NODE(OmpToClause, Modifier)
NODE(parser, Only)
Expand Down
9 changes: 2 additions & 7 deletions flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -4934,15 +4934,10 @@ struct OpenMPFlushConstruct {
t;
};

struct OmpSimpleStandaloneDirective {
WRAPPER_CLASS_BOILERPLATE(OmpSimpleStandaloneDirective, llvm::omp::Directive);
CharBlock source;
};

struct OpenMPSimpleStandaloneConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPSimpleStandaloneConstruct);
WRAPPER_CLASS_BOILERPLATE(
OpenMPSimpleStandaloneConstruct, OmpDirectiveSpecification);
CharBlock source;
std::tuple<OmpSimpleStandaloneDirective, OmpClauseList> t;
};

struct OpenMPStandaloneConstruct {
Expand Down
17 changes: 7 additions & 10 deletions flang/lib/Lower/OpenMP/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,7 @@ extractOmpDirective(const parser::OpenMPConstruct &ompConstruct) {
return common::visit(
common::visitors{
[](const parser::OpenMPSimpleStandaloneConstruct &c) {
return std::get<parser::OmpSimpleStandaloneDirective>(c.t)
.v;
return c.v.DirId();
},
[](const parser::OpenMPFlushConstruct &c) {
return llvm::omp::OMPD_flush;
Expand Down Expand Up @@ -3286,14 +3285,12 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
// OpenMPStandaloneConstruct visitors
//===----------------------------------------------------------------------===//

static void genOMP(
lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
const parser::OpenMPSimpleStandaloneConstruct &simpleStandaloneConstruct) {
const auto &directive = std::get<parser::OmpSimpleStandaloneDirective>(
simpleStandaloneConstruct.t);
List<Clause> clauses = makeClauses(
std::get<parser::OmpClauseList>(simpleStandaloneConstruct.t), semaCtx);
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
const parser::OpenMPSimpleStandaloneConstruct &construct) {
const auto &directive = std::get<parser::OmpDirectiveName>(construct.v.t);
List<Clause> clauses = makeClauses(construct.v.Clauses(), semaCtx);
mlir::Location currentLocation = converter.genLocation(directive.source);

ConstructQueue queue{
Expand Down
66 changes: 52 additions & 14 deletions flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,34 @@ constexpr auto operator>=(PA checker, PB parser) {
return lookAhead(checker) >> parser;
}

// This parser succeeds if the given parser succeeds, and the result
// satisfies the given condition. Specifically, it succeeds if:
// 1. The parser given as the argument succeeds, and
// 2. The condition function (called with PA::resultType) returns true
// for the result.
template <typename PA, typename CF> struct PredicatedParser {
using resultType = typename PA::resultType;

constexpr PredicatedParser(PA parser, CF condition)
: parser_(parser), condition_(condition) {}

std::optional<resultType> Parse(ParseState &state) const {
if (auto result{parser_.Parse(state)}; result && condition_(*result)) {
return result;
}
return std::nullopt;
}

private:
const PA parser_;
const CF condition_;
};

template <typename PA, typename CF>
constexpr auto predicated(PA parser, CF condition) {
return PredicatedParser(parser, condition);
}

/// Parse OpenMP directive name (this includes compound directives).
struct OmpDirectiveNameParser {
using resultType = OmpDirectiveName;
Expand Down Expand Up @@ -1027,6 +1055,8 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>(

// --- Parsers for directives and constructs --------------------------

TYPE_PARSER(sourced(construct<OmpDirectiveName>(OmpDirectiveNameParser{})))

OmpDirectiveSpecification static makeFlushFromOldSyntax1(Verbatim &&text,
std::optional<OmpClauseList> &&clauses,
std::optional<std::list<OmpArgument>> &&args,
Expand Down Expand Up @@ -1198,24 +1228,32 @@ TYPE_PARSER(sourced( //
verbatim("FLUSH"_tok), maybe(parenthesized(Parser<OmpObjectList>{})),
Parser<OmpClauseList>{}, pure(/*TrailingClauses=*/true))))

// Simple Standalone Directives
TYPE_PARSER(sourced(construct<OmpSimpleStandaloneDirective>(first(
"BARRIER" >> pure(llvm::omp::Directive::OMPD_barrier),
"ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered),
"SCAN" >> pure(llvm::omp::Directive::OMPD_scan),
"TARGET ENTER DATA" >> pure(llvm::omp::Directive::OMPD_target_enter_data),
"TARGET EXIT DATA" >> pure(llvm::omp::Directive::OMPD_target_exit_data),
"TARGET UPDATE" >> pure(llvm::omp::Directive::OMPD_target_update),
"TASKWAIT" >> pure(llvm::omp::Directive::OMPD_taskwait),
"TASKYIELD" >> pure(llvm::omp::Directive::OMPD_taskyield)))))
static bool IsSimpleStandalone(const OmpDirectiveName &name) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that DirectiveName is really more of DirectiveID. Especially as it correspond to DirId in other places - unless I'm missing something. Something called name implies in my head that it's a string...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, internally it's really the numeric id, but it also contains the "source" member, which is the substring of the source code with the actual name, so I have some excuse... :)

The class name comes from the OpenMP spec terminology: for example, in the overview of the directive syntax, the name "directive-name" is used to refer to the directive. There is also "directive-name-modifier" that's used in certain clauses. I try to keep the class names close to what the spec uses, so it's easier to correlate them with the spec.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I just thought I'd mention it before it's a massive nightmare to change, because it sounds like there's more of this to come....

switch (name.v) {
case llvm::omp::Directive::OMPD_barrier:
case llvm::omp::Directive::OMPD_ordered:
case llvm::omp::Directive::OMPD_scan:
case llvm::omp::Directive::OMPD_target_enter_data:
case llvm::omp::Directive::OMPD_target_exit_data:
case llvm::omp::Directive::OMPD_target_update:
case llvm::omp::Directive::OMPD_taskwait:
case llvm::omp::Directive::OMPD_taskyield:
return true;
default:
return false;
}
}

TYPE_PARSER(sourced(construct<OpenMPSimpleStandaloneConstruct>(
Parser<OmpSimpleStandaloneDirective>{}, Parser<OmpClauseList>{})))
TYPE_PARSER(sourced( //
construct<OpenMPSimpleStandaloneConstruct>(
predicated(OmpDirectiveNameParser{}, IsSimpleStandalone) >=
Parser<OmpDirectiveSpecification>{})))

// Standalone Constructs
TYPE_PARSER(
sourced(construct<OpenMPStandaloneConstruct>(
Parser<OpenMPSimpleStandaloneConstruct>{}) ||
sourced( //
construct<OpenMPStandaloneConstruct>(
Parser<OpenMPSimpleStandaloneConstruct>{}) ||
construct<OpenMPStandaloneConstruct>(Parser<OpenMPFlushConstruct>{}) ||
// Try CANCELLATION POINT before CANCEL.
construct<OpenMPStandaloneConstruct>(
Expand Down
34 changes: 1 addition & 33 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2465,37 +2465,6 @@ class UnparseVisitor {
}
}
void Unparse(const OmpObjectList &x) { Walk(x.v, ","); }
void Unparse(const OmpSimpleStandaloneDirective &x) {
switch (x.v) {
case llvm::omp::Directive::OMPD_barrier:
Word("BARRIER ");
break;
case llvm::omp::Directive::OMPD_scan:
Word("SCAN ");
break;
case llvm::omp::Directive::OMPD_taskwait:
Word("TASKWAIT ");
break;
case llvm::omp::Directive::OMPD_taskyield:
Word("TASKYIELD ");
break;
case llvm::omp::Directive::OMPD_target_enter_data:
Word("TARGET ENTER DATA ");
break;
case llvm::omp::Directive::OMPD_target_exit_data:
Word("TARGET EXIT DATA ");
break;
case llvm::omp::Directive::OMPD_target_update:
Word("TARGET UPDATE ");
break;
case llvm::omp::Directive::OMPD_ordered:
Word("ORDERED ");
break;
default:
// Nothing to be done
break;
}
}
void Unparse(const OmpBlockDirective &x) {
switch (x.v) {
case llvm::omp::Directive::OMPD_masked:
Expand Down Expand Up @@ -2924,8 +2893,7 @@ class UnparseVisitor {
void Unparse(const OpenMPSimpleStandaloneConstruct &x) {
BeginOpenMP();
Word("!$OMP ");
Walk(std::get<OmpSimpleStandaloneDirective>(x.t));
Walk(std::get<OmpClauseList>(x.t));
Walk(x.v);
Put("\n");
EndOpenMP();
}
Expand Down
38 changes: 17 additions & 21 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -878,21 +878,17 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
}
},
[&](const parser::OpenMPStandaloneConstruct &c) {
if (const auto &simpleConstruct =
std::get_if<parser::OpenMPSimpleStandaloneConstruct>(
&c.u)) {
const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(
simpleConstruct->t)};
if (dir.v == llvm::omp::Directive::OMPD_ordered) {
const auto &clauses{
std::get<parser::OmpClauseList>(simpleConstruct->t)};
for (const auto &clause : clauses.v) {
if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
if (auto *ssc{std::get_if<parser::OpenMPSimpleStandaloneConstruct>(
&c.u)}) {
llvm::omp::Directive dirId{ssc->v.DirId()};
if (dirId == llvm::omp::Directive::OMPD_ordered) {
for (const parser::OmpClause &x : ssc->v.Clauses().v) {
if (x.Id() == llvm::omp::Clause::OMPC_simd) {
eligibleSIMD = true;
break;
}
}
} else if (dir.v == llvm::omp::Directive::OMPD_scan) {
} else if (dirId == llvm::omp::Directive::OMPD_scan) {
eligibleSIMD = true;
}
}
Expand Down Expand Up @@ -944,15 +940,15 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
common::visit(
common::visitors{
[&](const parser::OpenMPSimpleStandaloneConstruct &c) {
const auto &dir{
std::get<parser::OmpSimpleStandaloneDirective>(c.t)};
if (dir.v == llvm::omp::Directive::OMPD_target_update ||
dir.v ==
llvm::omp::Directive::OMPD_target_enter_data ||
dir.v ==
llvm::omp::Directive::OMPD_target_exit_data) {
switch (llvm::omp::Directive dirId{c.v.DirId()}) {
case llvm::omp::Directive::OMPD_target_update:
case llvm::omp::Directive::OMPD_target_enter_data:
case llvm::omp::Directive::OMPD_target_exit_data:
eligibleTarget = false;
ineligibleTargetDir = dir.v;
ineligibleTargetDir = dirId;
break;
default:
break;
}
},
[&](const auto &c) {},
Expand Down Expand Up @@ -1978,7 +1974,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPAllocatorsConstruct &x) {

void OmpStructureChecker::CheckScan(
const parser::OpenMPSimpleStandaloneConstruct &x) {
if (std::get<parser::OmpClauseList>(x.t).v.size() != 1) {
if (x.v.Clauses().v.size() != 1) {
context_.Say(x.source,
"Exactly one of EXCLUSIVE or INCLUSIVE clause is expected"_err_en_US);
}
Expand Down Expand Up @@ -2183,7 +2179,7 @@ void OmpStructureChecker::CheckDependenceType(

void OmpStructureChecker::Enter(
const parser::OpenMPSimpleStandaloneConstruct &x) {
const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(x.t)};
const auto &dir{std::get<parser::OmpDirectiveName>(x.v.t)};
PushContextAndClauseSets(dir.source, dir.v);
switch (dir.v) {
case llvm::omp::Directive::OMPD_barrier:
Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
return true;
}
void Post(const parser::OmpDirectiveSpecification &) { PopContext(); }

bool Pre(const parser::OmpMetadirectiveDirective &x) {
PushContext(x.source, llvm::omp::Directive::OMPD_metadirective);
return true;
Expand Down Expand Up @@ -1652,8 +1653,7 @@ void OmpAttributeVisitor::Post(const parser::OpenMPBlockConstruct &x) {

bool OmpAttributeVisitor::Pre(
const parser::OpenMPSimpleStandaloneConstruct &x) {
const auto &standaloneDir{
std::get<parser::OmpSimpleStandaloneDirective>(x.t)};
const auto &standaloneDir{std::get<parser::OmpDirectiveName>(x.v.t)};
switch (standaloneDir.v) {
case llvm::omp::Directive::OMPD_barrier:
case llvm::omp::Directive::OMPD_ordered:
Expand Down
23 changes: 15 additions & 8 deletions flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1440,11 +1440,13 @@ class OmpVisitor : public virtual DeclarationVisitor {
static bool NeedsScope(const parser::OpenMPBlockConstruct &);
static bool NeedsScope(const parser::OmpClause &);

bool Pre(const parser::OpenMPRequiresConstruct &x) {
AddOmpSourceRange(x.source);
bool Pre(const parser::OmpMetadirectiveDirective &) {
++metaLevel_;
return true;
}
bool Pre(const parser::OmpSimpleStandaloneDirective &x) {
void Post(const parser::OmpMetadirectiveDirective &) { --metaLevel_; }

bool Pre(const parser::OpenMPRequiresConstruct &x) {
AddOmpSourceRange(x.source);
return true;
}
Expand Down Expand Up @@ -1656,6 +1658,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
const parser::OmpClauseList &clauses);
void ProcessReductionSpecifier(const parser::OmpReductionSpecifier &spec,
const std::optional<parser::OmpClauseList> &clauses);
int metaLevel_{0};
};

bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) {
Expand Down Expand Up @@ -1801,12 +1804,16 @@ void OmpVisitor::ProcessReductionSpecifier(
}

bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) {
// OmpDirectiveSpecification is only used in METADIRECTIVE at the moment.
// Since it contains directives and clauses, some semantic checks may
// not be applicable.
// Disable the semantic analysis for it for now to allow the compiler to
// parse METADIRECTIVE without flagging errors.
AddOmpSourceRange(x.source);
if (metaLevel_ == 0) {
// Not in METADIRECTIVE.
return true;
}

// If OmpDirectiveSpecification (which contains clauses) is a part of
// METADIRECTIVE, some semantic checks may not be applicable.
// Disable the semantic analysis for it in such cases to allow the compiler
// to parse METADIRECTIVE without flagging errors.
auto &maybeArgs{std::get<std::optional<std::list<parser::OmpArgument>>>(x.t)};
auto &maybeClauses{std::get<std::optional<parser::OmpClauseList>>(x.t)};

Expand Down
8 changes: 4 additions & 4 deletions flang/test/Parser/OpenMP/doacross-clause.f90
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ subroutine f00(x)
!PARSE-TREE: | OmpClauseList -> OmpClause -> Ordered -> Scalar -> Integer -> Constant -> Expr = '2_4'
!PARSE-TREE: | | LiteralConstant -> IntLiteralConstant = '2'
![...]
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct
!PARSE-TREE: | OmpSimpleStandaloneDirective -> llvm::omp::Directive = ordered
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = ordered
!PARSE-TREE: | OmpClauseList -> OmpClause -> Doacross -> OmpDoacrossClause -> OmpDoacross -> Source

subroutine f01(x)
Expand Down Expand Up @@ -65,8 +65,8 @@ subroutine f01(x)
!PARSE-TREE: | OmpClauseList -> OmpClause -> Ordered -> Scalar -> Integer -> Constant -> Expr = '2_4'
!PARSE-TREE: | | LiteralConstant -> IntLiteralConstant = '2'
![...]
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct
!PARSE-TREE: | OmpSimpleStandaloneDirective -> llvm::omp::Directive = ordered
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = ordered
!PARSE-TREE: | OmpClauseList -> OmpClause -> Doacross -> OmpDoacrossClause -> OmpDoacross -> Sink -> OmpIterationVector -> OmpIteration
!PARSE-TREE: | | Name = 'i'
!PARSE-TREE: | | OmpIterationOffset
Expand Down
Loading