Skip to content

[flang][OpenMP] Extend common::AtomicDefaultMemOrderType enumeration #136312

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

Merged
merged 3 commits into from
Apr 23, 2025
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
2 changes: 1 addition & 1 deletion flang/examples/FeatureList/FeatureList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -564,11 +564,11 @@ struct NodeVisitor {
READ_FEATURE(OpenMPDeclareReductionConstruct)
READ_FEATURE(OpenMPDeclareSimdConstruct)
READ_FEATURE(OpenMPDeclareTargetConstruct)
READ_FEATURE(OmpMemoryOrderType)
READ_FEATURE(OmpMemoryOrderClause)
READ_FEATURE(OmpAtomicClause)
READ_FEATURE(OmpAtomicClauseList)
READ_FEATURE(OmpAtomicDefaultMemOrderClause)
READ_FEATURE(OmpAtomicDefaultMemOrderType)
READ_FEATURE(OpenMPFlushConstruct)
READ_FEATURE(OpenMPLoopConstruct)
READ_FEATURE(OpenMPExecutableAllocate)
Expand Down
66 changes: 36 additions & 30 deletions flang/include/flang/Lower/DirectivesCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,36 +55,42 @@ static inline void genOmpAtomicHintAndMemoryOrderClauses(
mlir::omp::ClauseMemoryOrderKindAttr &memoryOrder) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
for (const Fortran::parser::OmpAtomicClause &clause : clauseList.v) {
if (const auto *hintClause =
std::get_if<Fortran::parser::OmpHintClause>(&clause.u)) {
const auto *expr = Fortran::semantics::GetExpr(hintClause->v);
uint64_t hintExprValue = *Fortran::evaluate::ToInt64(*expr);
hint = firOpBuilder.getI64IntegerAttr(hintExprValue);
} else if (const auto *ompMemoryOrderClause =
std::get_if<Fortran::parser::OmpMemoryOrderClause>(
&clause.u)) {
if (std::get_if<Fortran::parser::OmpClause::Acquire>(
&ompMemoryOrderClause->v.u)) {
memoryOrder = mlir::omp::ClauseMemoryOrderKindAttr::get(
firOpBuilder.getContext(),
mlir::omp::ClauseMemoryOrderKind::Acquire);
} else if (std::get_if<Fortran::parser::OmpClause::Relaxed>(
&ompMemoryOrderClause->v.u)) {
memoryOrder = mlir::omp::ClauseMemoryOrderKindAttr::get(
firOpBuilder.getContext(),
mlir::omp::ClauseMemoryOrderKind::Relaxed);
} else if (std::get_if<Fortran::parser::OmpClause::SeqCst>(
&ompMemoryOrderClause->v.u)) {
memoryOrder = mlir::omp::ClauseMemoryOrderKindAttr::get(
firOpBuilder.getContext(),
mlir::omp::ClauseMemoryOrderKind::Seq_cst);
} else if (std::get_if<Fortran::parser::OmpClause::Release>(
&ompMemoryOrderClause->v.u)) {
memoryOrder = mlir::omp::ClauseMemoryOrderKindAttr::get(
firOpBuilder.getContext(),
mlir::omp::ClauseMemoryOrderKind::Release);
}
}
common::visit(
common::visitors{
[&](const parser::OmpMemoryOrderClause &s) {
auto kind = common::visit(
common::visitors{
[&](const parser::OmpClause::AcqRel &) {
return mlir::omp::ClauseMemoryOrderKind::Acq_rel;
},
[&](const parser::OmpClause::Acquire &) {
return mlir::omp::ClauseMemoryOrderKind::Acquire;
},
[&](const parser::OmpClause::Relaxed &) {
return mlir::omp::ClauseMemoryOrderKind::Relaxed;
},
[&](const parser::OmpClause::Release &) {
return mlir::omp::ClauseMemoryOrderKind::Release;
},
[&](const parser::OmpClause::SeqCst &) {
return mlir::omp::ClauseMemoryOrderKind::Seq_cst;
},
[&](auto &&) -> mlir::omp::ClauseMemoryOrderKind {
llvm_unreachable("Unexpected clause");
},
},
s.v.u);
memoryOrder = mlir::omp::ClauseMemoryOrderKindAttr::get(
firOpBuilder.getContext(), kind);
},
[&](const parser::OmpHintClause &s) {
const auto *expr = Fortran::semantics::GetExpr(s.v);
uint64_t hintExprValue = *Fortran::evaluate::ToInt64(*expr);
hint = firOpBuilder.getI64IntegerAttr(hintExprValue);
},
[&](const parser::OmpFailClause &) {},
},
clause.u);
}
}

Expand Down
2 changes: 1 addition & 1 deletion flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -707,11 +707,11 @@ class ParseTreeDumper {
NODE(parser, OpenMPDeclareSimdConstruct)
NODE(parser, OpenMPDeclareTargetConstruct)
NODE(parser, OpenMPDeclareMapperConstruct)
NODE_ENUM(common, OmpMemoryOrderType)
NODE(parser, OmpMemoryOrderClause)
NODE(parser, OmpAtomicClause)
NODE(parser, OmpAtomicClauseList)
NODE(parser, OmpAtomicDefaultMemOrderClause)
NODE_ENUM(common, OmpAtomicDefaultMemOrderType)
NODE(parser, OpenMPDepobjConstruct)
NODE(parser, OpenMPUtilityConstruct)
NODE(parser, OpenMPDispatchConstruct)
Expand Down
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 @@ -4071,7 +4071,7 @@ struct OmpAtClause {
// SEQ_CST | ACQ_REL | RELAXED | // since 5.0
// ACQUIRE | RELEASE // since 5.2
struct OmpAtomicDefaultMemOrderClause {
using MemoryOrder = common::OmpAtomicDefaultMemOrderType;
using MemoryOrder = common::OmpMemoryOrderType;
WRAPPER_CLASS_BOILERPLATE(OmpAtomicDefaultMemOrderClause, MemoryOrder);
};

Expand Down Expand Up @@ -4822,10 +4822,10 @@ struct OpenMPAllocatorsConstruct {

// 2.17.7 Atomic construct/2.17.8 Flush construct [OpenMP 5.0]
// memory-order-clause -> acq_rel
// release
// acquire
// seq_cst
// release
// relaxed
// seq_cst
struct OmpMemoryOrderClause {
WRAPPER_CLASS_BOILERPLATE(OmpMemoryOrderClause, OmpClause);
CharBlock source;
Expand Down
2 changes: 1 addition & 1 deletion flang/include/flang/Semantics/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ using MutableSymbolVector = std::vector<MutableSymbolRef>;

// Mixin for details with OpenMP declarative constructs.
class WithOmpDeclarative {
using OmpAtomicOrderType = common::OmpAtomicDefaultMemOrderType;
using OmpAtomicOrderType = common::OmpMemoryOrderType;

public:
ENUM_CLASS(RequiresFlag, ReverseOffload, UnifiedAddress, UnifiedSharedMemory,
Expand Down
4 changes: 2 additions & 2 deletions flang/include/flang/Support/Fortran.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ ENUM_CLASS(
ENUM_CLASS(
OpenACCDeviceType, Star, Default, Nvidia, Radeon, Host, Multicore, None)

// OpenMP atomic_default_mem_order clause allowed values
ENUM_CLASS(OmpAtomicDefaultMemOrderType, SeqCst, AcqRel, Relaxed)
// OpenMP memory-order types
ENUM_CLASS(OmpMemoryOrderType, Acq_Rel, Acquire, Relaxed, Release, Seq_Cst)

// Fortran names may have up to 63 characters (See Fortran 2018 C601).
static constexpr int maxNameLen{63};
Expand Down
9 changes: 5 additions & 4 deletions flang/lib/Lower/OpenMP/Clauses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,12 +494,13 @@ AtomicDefaultMemOrder make(const parser::OmpClause::AtomicDefaultMemOrder &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpAtomicDefaultMemOrderClause
CLAUSET_ENUM_CONVERT( //
convert, common::OmpAtomicDefaultMemOrderType,
AtomicDefaultMemOrder::MemoryOrder,
convert, common::OmpMemoryOrderType, AtomicDefaultMemOrder::MemoryOrder,
// clang-format off
MS(AcqRel, AcqRel)
MS(Acq_Rel, AcqRel)
MS(Acquire, Acquire)
MS(Relaxed, Relaxed)
MS(SeqCst, SeqCst)
MS(Release, Release)
MS(Seq_Cst, SeqCst)
// clang-format on
);

Expand Down
36 changes: 20 additions & 16 deletions flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,20 @@ TYPE_PARSER(construct<OmpAffinityClause>(
maybe(nonemptyList(Parser<OmpAffinityClause::Modifier>{}) / ":"),
Parser<OmpObjectList>{}))

// 2.4 Requires construct [OpenMP 5.0]
// atomic-default-mem-order-clause ->
// acq_rel
// acquire
// relaxed
// release
// seq_cst
TYPE_PARSER(construct<OmpAtomicDefaultMemOrderClause>(
"ACQ_REL" >> pure(common::OmpMemoryOrderType::Acq_Rel) ||
"ACQUIRE" >> pure(common::OmpMemoryOrderType::Acquire) ||
"RELAXED" >> pure(common::OmpMemoryOrderType::Relaxed) ||
"RELEASE" >> pure(common::OmpMemoryOrderType::Release) ||
"SEQ_CST" >> pure(common::OmpMemoryOrderType::Seq_Cst)))

TYPE_PARSER(construct<OmpCancellationConstructTypeClause>(
OmpDirectiveNameParser{}, maybe(parenthesized(scalarLogicalExpr))))

Expand Down Expand Up @@ -1192,27 +1206,17 @@ TYPE_PARSER(sourced(construct<OmpFailClause>(

// 2.17.7 Atomic construct/2.17.8 Flush construct [OpenMP 5.0]
// memory-order-clause ->
// seq_cst
// acq_rel
// release
// acquire
// relaxed
// release
// seq_cst
TYPE_PARSER(sourced(construct<OmpMemoryOrderClause>(
sourced("SEQ_CST" >> construct<OmpClause>(construct<OmpClause::SeqCst>()) ||
"ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
"RELEASE" >> construct<OmpClause>(construct<OmpClause::Release>()) ||
sourced("ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
"RELAXED" >> construct<OmpClause>(construct<OmpClause::Relaxed>())))))

// 2.4 Requires construct [OpenMP 5.0]
// atomic-default-mem-order-clause ->
// seq_cst
// acq_rel
// relaxed
TYPE_PARSER(construct<OmpAtomicDefaultMemOrderClause>(
"SEQ_CST" >> pure(common::OmpAtomicDefaultMemOrderType::SeqCst) ||
"ACQ_REL" >> pure(common::OmpAtomicDefaultMemOrderType::AcqRel) ||
"RELAXED" >> pure(common::OmpAtomicDefaultMemOrderType::Relaxed)))
"RELAXED" >> construct<OmpClause>(construct<OmpClause::Relaxed>()) ||
"RELEASE" >> construct<OmpClause>(construct<OmpClause::Release>()) ||
"SEQ_CST" >> construct<OmpClause>(construct<OmpClause::SeqCst>())))))

// 2.17.7 Atomic construct
// atomic-clause -> memory-order-clause | HINT(hint-expression)
Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2558,8 +2558,8 @@ class UnparseVisitor {
}
}

void Unparse(const OmpAtomicDefaultMemOrderClause &x) {
Word(ToUpperCaseLetters(common::EnumToString(x.v)));
void Unparse(const common::OmpMemoryOrderType &x) {
Word(ToUpperCaseLetters(common::EnumToString(x)));
}

void Unparse(const OmpAtomicClauseList &x) { Walk(" ", x.v, " "); }
Expand Down
10 changes: 5 additions & 5 deletions flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {

// Gather information from the clauses.
Flags flags;
std::optional<common::OmpAtomicDefaultMemOrderType> memOrder;
std::optional<common::OmpMemoryOrderType> memOrder;
for (const auto &clause : std::get<parser::OmpClauseList>(x.t).v) {
flags |= common::visit(
common::visitors{
Expand Down Expand Up @@ -799,7 +799,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
std::int64_t ordCollapseLevel{0};

void AddOmpRequiresToScope(Scope &, WithOmpDeclarative::RequiresFlags,
std::optional<common::OmpAtomicDefaultMemOrderType>);
std::optional<common::OmpMemoryOrderType>);
void IssueNonConformanceWarning(
llvm::omp::Directive D, parser::CharBlock source);

Expand Down Expand Up @@ -2721,7 +2721,7 @@ void ResolveOmpTopLevelParts(
// program units. Modules are skipped because their REQUIRES clauses should be
// propagated via USE statements instead.
WithOmpDeclarative::RequiresFlags combinedFlags;
std::optional<common::OmpAtomicDefaultMemOrderType> combinedMemOrder;
std::optional<common::OmpMemoryOrderType> combinedMemOrder;

// Function to go through non-module top level program units and extract
// REQUIRES information to be processed by a function-like argument.
Expand Down Expand Up @@ -2764,7 +2764,7 @@ void ResolveOmpTopLevelParts(
flags{details.ompRequires()}) {
combinedFlags |= *flags;
}
if (const common::OmpAtomicDefaultMemOrderType *
if (const common::OmpMemoryOrderType *
memOrder{details.ompAtomicDefaultMemOrder()}) {
if (combinedMemOrder && *combinedMemOrder != *memOrder) {
context.Say(symbol.scope()->sourceRange(),
Expand Down Expand Up @@ -2983,7 +2983,7 @@ void OmpAttributeVisitor::CheckNameInAllocateStmt(

void OmpAttributeVisitor::AddOmpRequiresToScope(Scope &scope,
WithOmpDeclarative::RequiresFlags flags,
std::optional<common::OmpAtomicDefaultMemOrderType> memOrder) {
std::optional<common::OmpMemoryOrderType> memOrder) {
Scope *scopeIter = &scope;
do {
if (Symbol * symbol{scopeIter->symbol()}) {
Expand Down
12 changes: 8 additions & 4 deletions flang/lib/Semantics/rewrite-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ bool OmpRewriteMutator::Pre(parser::OpenMPAtomicConstruct &x) {
x.u)};

// Get the `atomic_default_mem_order` clause from the top-level parent.
std::optional<common::OmpAtomicDefaultMemOrderType> defaultMemOrder;
std::optional<common::OmpMemoryOrderType> defaultMemOrder;
common::visit(
[&](auto &details) {
if constexpr (std::is_convertible_v<decltype(&details),
Expand Down Expand Up @@ -119,7 +119,7 @@ bool OmpRewriteMutator::Pre(parser::OpenMPAtomicConstruct &x) {
if (clauseList) {
atomicDirectiveDefaultOrderFound_ = true;
switch (*defaultMemOrder) {
case common::OmpAtomicDefaultMemOrderType::AcqRel:
case common::OmpMemoryOrderType::Acq_Rel:
clauseList->emplace_back<parser::OmpMemoryOrderClause>(common::visit(
common::visitors{[](parser::OmpAtomicRead &) -> parser::OmpClause {
return parser::OmpClause::Acquire{};
Expand All @@ -133,14 +133,18 @@ bool OmpRewriteMutator::Pre(parser::OpenMPAtomicConstruct &x) {
}},
x.u));
break;
case common::OmpAtomicDefaultMemOrderType::Relaxed:
case common::OmpMemoryOrderType::Relaxed:
clauseList->emplace_back<parser::OmpMemoryOrderClause>(
parser::OmpClause{parser::OmpClause::Relaxed{}});
break;
case common::OmpAtomicDefaultMemOrderType::SeqCst:
case common::OmpMemoryOrderType::Seq_Cst:
clauseList->emplace_back<parser::OmpMemoryOrderClause>(
parser::OmpClause{parser::OmpClause::SeqCst{}});
break;
default:
// FIXME: Don't process other values at the moment since their validity
// depends on the OpenMP version (which is unavailable here).
break;
}
}

Expand Down
Loading