Skip to content

[flang][OpenMP] Make OpenMPCriticalConstruct follow block structure #152007

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: users/kparzysz/a07-critical-global
Choose a base branch
from
Open
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
6 changes: 3 additions & 3 deletions flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -4986,9 +4986,9 @@ struct OmpEndCriticalDirective {
CharBlock source;
std::tuple<Verbatim, std::optional<Name>> t;
};
struct OpenMPCriticalConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPCriticalConstruct);
std::tuple<OmpCriticalDirective, Block, OmpEndCriticalDirective> t;

struct OpenMPCriticalConstruct : public OmpBlockConstruct {
INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPCriticalConstruct, OmpBlockConstruct);
};

// 2.11.3 allocate -> ALLOCATE [(variable-name-list)] [clause]
Expand Down
24 changes: 18 additions & 6 deletions flang/lib/Lower/OpenMP/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "flang/Parser/openmp-utils.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/openmp-directive-sets.h"
#include "flang/Semantics/openmp-utils.h"
#include "flang/Semantics/tools.h"
#include "flang/Support/Flags.h"
#include "flang/Support/OpenMP-utils.h"
Expand Down Expand Up @@ -3797,18 +3798,29 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
const parser::OpenMPCriticalConstruct &criticalConstruct) {
const auto &cd = std::get<parser::OmpCriticalDirective>(criticalConstruct.t);
List<Clause> clauses =
makeClauses(std::get<parser::OmpClauseList>(cd.t), semaCtx);
const parser::OmpDirectiveSpecification &beginSpec =
criticalConstruct.BeginDir();
List<Clause> clauses = makeClauses(beginSpec.Clauses(), semaCtx);

ConstructQueue queue{buildConstructQueue(
converter.getFirOpBuilder().getModule(), semaCtx, eval, cd.source,
converter.getFirOpBuilder().getModule(), semaCtx, eval, beginSpec.source,
llvm::omp::Directive::OMPD_critical, clauses)};

const auto &name = std::get<std::optional<parser::Name>>(cd.t);
std::optional<parser::Name> critName;
const parser::OmpArgumentList &args = beginSpec.Arguments();
if (!args.v.empty()) {
// All of these things should be guaranteed to exist after semantic checks.
auto *object = parser::Unwrap<parser::OmpObject>(args.v.front());
assert(object && "Expecting object as argument");
auto *designator = semantics::omp::GetDesignatorFromObj(*object);
assert(designator && "Expecting desginator in argument");
auto *name = semantics::getDesignatorNameIfDataRef(*designator);
assert(name && "Expecting dataref in designator");
critName = *name;
}
mlir::Location currentLocation = converter.getCurrentLocation();
genCriticalOp(converter, symTable, semaCtx, eval, currentLocation, queue,
queue.begin(), name);
queue.begin(), critName);
}

static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
Expand Down
11 changes: 1 addition & 10 deletions flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1758,17 +1758,8 @@ TYPE_PARSER(sourced(construct<OpenMPDeclareMapperConstruct>(
TYPE_PARSER(construct<OmpReductionCombiner>(Parser<AssignmentStmt>{}) ||
construct<OmpReductionCombiner>(Parser<FunctionReference>{}))

// 2.13.2 OMP CRITICAL
TYPE_PARSER(startOmpLine >>
sourced(construct<OmpEndCriticalDirective>(
verbatim("END CRITICAL"_tok), maybe(parenthesized(name)))) /
endOmpLine)
TYPE_PARSER(sourced(construct<OmpCriticalDirective>(verbatim("CRITICAL"_tok),
maybe(parenthesized(name)), Parser<OmpClauseList>{})) /
endOmpLine)

TYPE_PARSER(construct<OpenMPCriticalConstruct>(
Parser<OmpCriticalDirective>{}, block, Parser<OmpEndCriticalDirective>{}))
OmpBlockConstructParser{llvm::omp::Directive::OMPD_critical}))

// 2.11.3 Executable Allocate directive
TYPE_PARSER(
Expand Down
4 changes: 1 addition & 3 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2606,9 +2606,7 @@ class UnparseVisitor {
EndOpenMP();
}
void Unparse(const OpenMPCriticalConstruct &x) {
Walk(std::get<OmpCriticalDirective>(x.t));
Walk(std::get<Block>(x.t), "");
Walk(std::get<OmpEndCriticalDirective>(x.t));
Unparse(static_cast<const OmpBlockConstruct &>(x));
}
void Unparse(const OmpDeclareTargetWithList &x) {
Put("("), Walk(x.v), Put(")");
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Semantics/check-omp-atomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
//===----------------------------------------------------------------------===//

#include "check-omp-structure.h"
#include "openmp-utils.h"

#include "flang/Common/indirection.h"
#include "flang/Evaluate/expression.h"
#include "flang/Evaluate/tools.h"
#include "flang/Parser/char-block.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/openmp-utils.h"
#include "flang/Semantics/symbol.h"
#include "flang/Semantics/tools.h"
#include "flang/Semantics/type.h"
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Semantics/check-omp-loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "check-omp-structure.h"

#include "check-directive-structure.h"
#include "openmp-utils.h"

#include "flang/Common/idioms.h"
#include "flang/Common/visit.h"
Expand All @@ -23,6 +22,7 @@
#include "flang/Parser/parse-tree.h"
#include "flang/Parser/tools.h"
#include "flang/Semantics/openmp-modifiers.h"
#include "flang/Semantics/openmp-utils.h"
#include "flang/Semantics/semantics.h"
#include "flang/Semantics/symbol.h"
#include "flang/Semantics/tools.h"
Expand Down
3 changes: 1 addition & 2 deletions flang/lib/Semantics/check-omp-metadirective.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@

#include "check-omp-structure.h"

#include "openmp-utils.h"

#include "flang/Common/idioms.h"
#include "flang/Common/indirection.h"
#include "flang/Common/visit.h"
#include "flang/Parser/characters.h"
#include "flang/Parser/message.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/openmp-modifiers.h"
#include "flang/Semantics/openmp-utils.h"
#include "flang/Semantics/tools.h"

#include "llvm/Frontend/OpenMP/OMP.h"
Expand Down
124 changes: 81 additions & 43 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

#include "check-directive-structure.h"
#include "definable.h"
#include "openmp-utils.h"
#include "resolve-names-utils.h"

#include "flang/Common/idioms.h"
Expand All @@ -27,6 +26,7 @@
#include "flang/Semantics/expression.h"
#include "flang/Semantics/openmp-directive-sets.h"
#include "flang/Semantics/openmp-modifiers.h"
#include "flang/Semantics/openmp-utils.h"
#include "flang/Semantics/scope.h"
#include "flang/Semantics/semantics.h"
#include "flang/Semantics/symbol.h"
Expand Down Expand Up @@ -537,14 +537,6 @@ template <typename Checker> struct DirectiveSpellingVisitor {
checker_(x.v.source, Directive::OMPD_assume);
return false;
}
bool Pre(const parser::OmpCriticalDirective &x) {
checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_critical);
return false;
}
bool Pre(const parser::OmpEndCriticalDirective &x) {
checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_critical);
return false;
}
bool Pre(const parser::OmpMetadirectiveDirective &x) {
checker_(
std::get<parser::Verbatim>(x.t).source, Directive::OMPD_metadirective);
Expand Down Expand Up @@ -2034,41 +2026,87 @@ void OmpStructureChecker::Leave(const parser::OpenMPCancelConstruct &) {
}

void OmpStructureChecker::Enter(const parser::OpenMPCriticalConstruct &x) {
const auto &dir{std::get<parser::OmpCriticalDirective>(x.t)};
const auto &dirSource{std::get<parser::Verbatim>(dir.t).source};
const auto &endDir{std::get<parser::OmpEndCriticalDirective>(x.t)};
PushContextAndClauseSets(dirSource, llvm::omp::Directive::OMPD_critical);
const parser::OmpBeginDirective &beginSpec{x.BeginDir()};
const std::optional<parser::OmpEndDirective> &endSpec{x.EndDir()};
PushContextAndClauseSets(beginSpec.DirName().source, beginSpec.DirName().v);

const auto &block{std::get<parser::Block>(x.t)};
CheckNoBranching(block, llvm::omp::Directive::OMPD_critical, dir.source);
const auto &dirName{std::get<std::optional<parser::Name>>(dir.t)};
const auto &endDirName{std::get<std::optional<parser::Name>>(endDir.t)};
const auto &ompClause{std::get<parser::OmpClauseList>(dir.t)};
if (dirName && endDirName &&
dirName->ToString().compare(endDirName->ToString())) {
context_
.Say(endDirName->source,
parser::MessageFormattedText{
"CRITICAL directive names do not match"_err_en_US})
.Attach(dirName->source, "should be "_en_US);
} else if (dirName && !endDirName) {
context_
.Say(dirName->source,
parser::MessageFormattedText{
"CRITICAL directive names do not match"_err_en_US})
.Attach(dirName->source, "should be NULL"_en_US);
} else if (!dirName && endDirName) {
context_
.Say(endDirName->source,
parser::MessageFormattedText{
"CRITICAL directive names do not match"_err_en_US})
.Attach(endDirName->source, "should be NULL"_en_US);
}
if (!dirName && !ompClause.source.empty() &&
ompClause.source.NULTerminatedToString() != "hint(omp_sync_hint_none)") {
context_.Say(dir.source,
parser::MessageFormattedText{
"Hint clause other than omp_sync_hint_none cannot be specified for "
"an unnamed CRITICAL directive"_err_en_US});
CheckNoBranching(
block, llvm::omp::Directive::OMPD_critical, beginSpec.DirName().source);

auto getNameFromArg{[](const parser::OmpArgument &arg) {
if (auto *object{parser::Unwrap<parser::OmpObject>(arg.u)}) {
if (auto *designator{omp::GetDesignatorFromObj(*object)}) {
return getDesignatorNameIfDataRef(*designator);
}
}
return static_cast<const parser::Name *>(nullptr);
}};

auto checkArgumentList{[&](const parser::OmpArgumentList &args) {
if (args.v.size() > 1) {
context_.Say(args.source,
"Only a single argument is allowed in CRITICAL directive"_err_en_US);
} else if (!args.v.empty()) {
if (!getNameFromArg(args.v.front())) {
context_.Say(args.v.front().source,
"CRITICAL argument should be a name"_err_en_US);
}
}
}};

const parser::Name *beginName{nullptr};
const parser::Name *endName{nullptr};

auto &beginArgs{beginSpec.Arguments()};
checkArgumentList(beginArgs);

if (!beginArgs.v.empty()) {
beginName = getNameFromArg(beginArgs.v.front());
}

if (endSpec) {
auto &endArgs{endSpec->Arguments()};
checkArgumentList(endArgs);

if (beginArgs.v.empty() != endArgs.v.empty()) {
parser::CharBlock source{
beginArgs.v.empty() ? endArgs.source : beginArgs.source};
context_.Say(source,
"Either both CRITICAL and END CRITICAL should have an argument, or none of them should"_err_en_US);
} else if (!beginArgs.v.empty()) {
endName = getNameFromArg(endArgs.v.front());
if (beginName && endName) {
if (beginName->ToString() != endName->ToString()) {
context_.Say(endName->source,
"The names on CRITICAL and END CRITICAL must match"_err_en_US);
}
}
}
}

for (auto &clause : beginSpec.Clauses().v) {
auto *hint{std::get_if<parser::OmpClause::Hint>(&clause.u)};
if (!hint) {
continue;
}
const int64_t OmpSyncHintNone = 0; // omp_sync_hint_none
std::optional<int64_t> hintValue{GetIntValue(hint->v.v)};
if (hintValue && *hintValue != OmpSyncHintNone) {
// Emit a diagnostic if the name is missing, and point to the directive
// with a missing name.
parser::CharBlock source;
if (!beginName) {
source = beginSpec.DirName().source;
} else if (endSpec && !endName) {
source = endSpec->DirName().source;
}

if (!source.empty()) {
context_.Say(source,
"When HINT other than 'omp_sync_hint_none' is present, CRITICAL directive should have a name"_err_en_US);
}
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Semantics/openmp-utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//

#include "openmp-utils.h"
#include "flang/Semantics/openmp-utils.h"

#include "flang/Common/indirection.h"
#include "flang/Common/reference.h"
Expand Down
6 changes: 3 additions & 3 deletions flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

#include "check-acc-structure.h"
#include "check-omp-structure.h"
#include "openmp-utils.h"
#include "resolve-names-utils.h"
#include "flang/Common/idioms.h"
#include "flang/Evaluate/fold.h"
Expand All @@ -22,6 +21,7 @@
#include "flang/Semantics/expression.h"
#include "flang/Semantics/openmp-dsa.h"
#include "flang/Semantics/openmp-modifiers.h"
#include "flang/Semantics/openmp-utils.h"
#include "flang/Semantics/symbol.h"
#include "flang/Semantics/tools.h"
#include "llvm/Frontend/OpenMP/OMP.h.inc"
Expand Down Expand Up @@ -2124,8 +2124,8 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionConstruct &x) {
}

bool OmpAttributeVisitor::Pre(const parser::OpenMPCriticalConstruct &x) {
const auto &beginCriticalDir{std::get<parser::OmpCriticalDirective>(x.t)};
PushContext(beginCriticalDir.source, llvm::omp::Directive::OMPD_critical);
const parser::OmpBeginDirective &beginSpec{x.BeginDir()};
PushContext(beginSpec.DirName().source, beginSpec.DirName().v);
GetContext().withinConstruct = true;
return true;
}
Expand Down
Loading