mirror of
https://github.com/intel/llvm.git
synced 2026-01-15 12:25:46 +08:00
[flang][OpenMP] Extend common::AtomicDefaultMemOrderType enumeration (#136312)
Add "Acquire" and "Release", and rename it to OmpMemoryOrderType, since memory order type is a concept extending beyond the ATOMIC_DEFAULT_MEM_ORDER clause. When processing a REQUIRES directive (in rewrite-directives.cpp), do not add Acquire or Release to ATOMIC constructs, because handling of those types depends on the OpenMP version, which is not available in that file. This issue will be addressed later.
This commit is contained in:
committed by
GitHub
parent
71ce9e26ae
commit
05b7e97c78
@@ -564,11 +564,11 @@ public:
|
||||
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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -707,11 +707,11 @@ public:
|
||||
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)
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
|
||||
@@ -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))))
|
||||
|
||||
@@ -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
|
||||
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>()) ||
|
||||
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
|
||||
"RELAXED" >> construct<OmpClause>(construct<OmpClause::Relaxed>())))))
|
||||
|
||||
// 2.4 Requires construct [OpenMP 5.0]
|
||||
// atomic-default-mem-order-clause ->
|
||||
// release
|
||||
// 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)))
|
||||
TYPE_PARSER(sourced(construct<OmpMemoryOrderClause>(
|
||||
sourced("ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
|
||||
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
|
||||
"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)
|
||||
|
||||
@@ -2558,8 +2558,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
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, " "); }
|
||||
|
||||
@@ -416,7 +416,7 @@ public:
|
||||
|
||||
// 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{
|
||||
@@ -799,7 +799,7 @@ private:
|
||||
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);
|
||||
|
||||
@@ -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.
|
||||
@@ -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(),
|
||||
@@ -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()}) {
|
||||
|
||||
@@ -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),
|
||||
@@ -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{};
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user