This patch introduce the separate parser for the memory-order-clause from the general
OmpClauseList. This parser still creates OmpClause node and therefore can use all the feature
from TableGen and the OmpStructureChecker.
This is applied only for the Flush construct in this patch and it should be applied for
atomic as well.
This is the approach we disscussed several time during the weekly call.
Reviewed By: kiranchandramohan, sameeranjoshi
Differential Revision: https://reviews.llvm.org/D91839
NODE(parser, OpenMPDeclareReductionConstruct)
NODE(parser, OpenMPDeclareSimdConstruct)
NODE(parser, OpenMPDeclareTargetConstruct)
- NODE(parser, OmpFlushMemoryClause)
+ NODE(parser, OmpMemoryOrderClause)
NODE(parser, OpenMPFlushConstruct)
NODE(parser, OpenMPLoopConstruct)
NODE(parser, OpenMPSimpleStandaloneConstruct)
// memory-order-clause -> acq_rel
// release
// acquire
-struct OmpFlushMemoryClause {
- WRAPPER_CLASS_BOILERPLATE(OmpFlushMemoryClause, llvm::omp::Clause);
+struct OmpMemoryOrderClause {
+ WRAPPER_CLASS_BOILERPLATE(OmpMemoryOrderClause, OmpClause);
CharBlock source;
};
struct OpenMPFlushConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct);
CharBlock source;
- std::tuple<Verbatim, std::optional<OmpFlushMemoryClause>,
+ std::tuple<Verbatim, std::optional<OmpMemoryOrderClause>,
std::optional<OmpObjectList>>
t;
};
std::get<std::optional<Fortran::parser::OmpObjectList>>(
flushConstruct.t))
genObjectList(*ompObjectList, converter, operandRange);
- if (std::get<std::optional<Fortran::parser::OmpFlushMemoryClause>>(
+ if (std::get<std::optional<Fortran::parser::OmpMemoryOrderClause>>(
flushConstruct.t))
- TODO("Handle OmpFlushMemoryClause");
+ TODO("Handle OmpMemoryOrderClause");
converter.getFirOpBuilder().create<mlir::omp::FlushOp>(
converter.getCurrentLocation(), operandRange);
},
TYPE_PARSER(sourced(construct<OpenMPCancelConstruct>(verbatim("CANCEL"_tok),
Parser<OmpCancelType>{}, maybe("IF" >> parenthesized(scalarLogicalExpr)))))
-// 2.17.8 Flush construct [OpenMP 5.0]
-// flush -> FLUSH [memory-order-clause] [(variable-name-list)]
-// memory-order-clause -> acq_rel
+// 2.17.7 Atomtic construct/2.17.8 Flush construct [OpenMP 5.0]
+// memory-order-clause ->
+// seq_cst
+// acq_rel
// release
// acquire
-TYPE_PARSER(sourced(construct<OmpFlushMemoryClause>(
- "ACQ_REL" >> pure(llvm::omp::Clause::OMPC_acq_rel) ||
- "RELEASE" >> pure(llvm::omp::Clause::OMPC_release) ||
- "ACQUIRE" >> pure(llvm::omp::Clause::OMPC_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>())))))
TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(verbatim("FLUSH"_tok),
- maybe(Parser<OmpFlushMemoryClause>{}),
+ maybe(Parser<OmpMemoryOrderClause>{}),
maybe(parenthesized(Parser<OmpObjectList>{})))))
// Simple Standalone Directives
Put("\n");
EndOpenMP();
}
- void Unparse(const OmpFlushMemoryClause &x) {
- switch (x.v) {
- case llvm::omp::Clause::OMPC_acq_rel:
- Word("ACQ_REL ");
- break;
- case llvm::omp::Clause::OMPC_release:
- Word("RELEASE ");
- break;
- case llvm::omp::Clause::OMPC_acquire:
- Word("ACQUIRE ");
- break;
- default:
- break;
- }
- }
+ void Unparse(const OmpMemoryOrderClause &x) { Walk(x.v); }
void Unparse(const OpenMPFlushConstruct &x) {
BeginOpenMP();
Word("!$OMP FLUSH ");
- Walk(std::get<std::optional<OmpFlushMemoryClause>>(x.t));
+ Walk(std::get<std::optional<OmpMemoryOrderClause>>(x.t));
Walk(" (", std::get<std::optional<OmpObjectList>>(x.t), ")");
Put("\n");
EndOpenMP();
CHECK_SIMPLE_CLAUSE(Uniform, OMPC_uniform)
CHECK_SIMPLE_CLAUSE(Untied, OMPC_untied)
CHECK_SIMPLE_CLAUSE(UseDevicePtr, OMPC_use_device_ptr)
+CHECK_SIMPLE_CLAUSE(AcqRel, OMPC_acq_rel)
+CHECK_SIMPLE_CLAUSE(Acquire, OMPC_acquire)
+CHECK_SIMPLE_CLAUSE(SeqCst, OMPC_seq_cst)
+CHECK_SIMPLE_CLAUSE(Release, OMPC_release)
+CHECK_SIMPLE_CLAUSE(Relaxed, OMPC_relaxed)
CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize)
CHECK_REQ_SCALAR_INT_CLAUSE(NumTasks, OMPC_num_tasks)
void Enter(const parser::OmpClause::Uniform &);
void Enter(const parser::OmpClause::UseDevicePtr &);
void Enter(const parser::OmpClause::IsDevicePtr &);
+ // Memory-order-clause
+ void Enter(const parser::OmpClause::SeqCst &);
+ void Enter(const parser::OmpClause::AcqRel &);
+ void Enter(const parser::OmpClause::Release &);
+ void Enter(const parser::OmpClause::Acquire &);
+ void Enter(const parser::OmpClause::Relaxed &);
void Enter(const parser::OmpAlignedClause &);
void Enter(const parser::OmpAllocateClause &);
a = 3.14
enddo
!$omp end parallel
-
+
!$omp task private(b) allocate(b)
do i = 1, N
z = 2
z = 2
end do
!$omp end target
-
+
!ERROR: ALLOCATE clause is not allowed on the TARGET DATA directive
!$omp target data map(from: b) allocate(b)
do i = 1, N
!$omp flush release
!$omp flush acquire
!$omp flush release (c)
+ !ERROR: SEQ_CST clause is not allowed on the FLUSH directive
+ !$omp flush seq_cst
+ !ERROR: RELAXED clause is not allowed on the FLUSH directive
+ !$omp flush relaxed
+
!$omp cancel DO
!$omp cancellation point parallel