Skip to content

Commit 9261cd4

Browse files
committed
Revert "[flang][OpenMP] Overhaul implementation of ATOMIC construct (llvm#137852)"
breaks sollve50 test_requires_atomic_default_mem_order_acq_rel.F90 and the 3 lit tests flang/test/Lower/OpenMP/atomic-implicit-cast.f90 flang/test/Lower/OpenMP/common-atomic-lowering.f90 flang/test/Semantics/OpenMP/atomic.f90 This reverts commit 141d390.
1 parent 7f46a4c commit 9261cd4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1998
-3757
lines changed

flang/docs/OpenMPSupport.md

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,3 @@ Note : No distinction is made between the support in Parser/Semantics, MLIR, Low
6060
| target teams distribute parallel loop construct | P | device, reduction and dist_schedule clauses are not supported |
6161
| teams distribute parallel loop simd construct | P | reduction, dist_schedule, and linear clauses are not supported |
6262
| target teams distribute parallel loop simd construct | P | device, reduction, dist_schedule and linear clauses are not supported |
63-
64-
## Extensions
65-
### ATOMIC construct
66-
The implementation of the ATOMIC construct follows OpenMP 6.0 with the following extensions:
67-
- `x = x` is an allowed form of ATOMIC UPDATE.
68-
This is motivated by the fact that the equivalent forms `x = x+0` or `x = x*1` are allowed.
69-
- Explicit type conversions are allowed in ATOMIC READ, WRITE or UPDATE constructs, and in the capture statement in ATOMIC UPDATE CAPTURE.
70-
The OpenMP spec requires intrinsic- or pointer-assignments, which include (as per the Fortran standard) implicit type conversions. Since such conversions need to be handled, allowing explicit conversions comes at no extra cost.
71-
- A literal `.true.` or `.false.` is an allowed condition in ATOMIC UPDATE COMPARE. [1]
72-
- A logical variable is an allowed form of the condition even if its value is not computed within the ATOMIC UPDATE COMPARE construct [1].
73-
- `expr equalop x` is an allowed condition in ATOMIC UPDATE COMPARE. [1]
74-
75-
[1] Code generation for ATOMIC UPDATE COMPARE is not implemented yet.

flang/examples/FeatureList/FeatureList.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,13 @@ struct NodeVisitor {
445445
READ_FEATURE(ObjectDecl)
446446
READ_FEATURE(OldParameterStmt)
447447
READ_FEATURE(OmpAlignedClause)
448+
READ_FEATURE(OmpAtomic)
449+
READ_FEATURE(OmpAtomicCapture)
450+
READ_FEATURE(OmpAtomicCapture::Stmt1)
451+
READ_FEATURE(OmpAtomicCapture::Stmt2)
452+
READ_FEATURE(OmpAtomicRead)
453+
READ_FEATURE(OmpAtomicUpdate)
454+
READ_FEATURE(OmpAtomicWrite)
448455
READ_FEATURE(OmpBeginBlockDirective)
449456
READ_FEATURE(OmpBeginLoopDirective)
450457
READ_FEATURE(OmpBeginSectionsDirective)
@@ -473,6 +480,7 @@ struct NodeVisitor {
473480
READ_FEATURE(OmpIterationOffset)
474481
READ_FEATURE(OmpIterationVector)
475482
READ_FEATURE(OmpEndAllocators)
483+
READ_FEATURE(OmpEndAtomic)
476484
READ_FEATURE(OmpEndBlockDirective)
477485
READ_FEATURE(OmpEndCriticalDirective)
478486
READ_FEATURE(OmpEndLoopDirective)
@@ -558,6 +566,8 @@ struct NodeVisitor {
558566
READ_FEATURE(OpenMPDeclareTargetConstruct)
559567
READ_FEATURE(OmpMemoryOrderType)
560568
READ_FEATURE(OmpMemoryOrderClause)
569+
READ_FEATURE(OmpAtomicClause)
570+
READ_FEATURE(OmpAtomicClauseList)
561571
READ_FEATURE(OmpAtomicDefaultMemOrderClause)
562572
READ_FEATURE(OpenMPFlushConstruct)
563573
READ_FEATURE(OpenMPLoopConstruct)

flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,25 @@ SourcePosition OpenMPCounterVisitor::getLocation(const OpenMPConstruct &c) {
7474
// the directive field.
7575
[&](const auto &c) -> SourcePosition {
7676
const CharBlock &source{std::get<0>(c.t).source};
77-
return parsing->allCooked().GetSourcePositionRange(source)->first;
77+
return (parsing->allCooked().GetSourcePositionRange(source))->first;
7878
},
7979
[&](const OpenMPAtomicConstruct &c) -> SourcePosition {
80-
const CharBlock &source{c.source};
81-
return parsing->allCooked().GetSourcePositionRange(source)->first;
80+
return std::visit(
81+
[&](const auto &o) -> SourcePosition {
82+
const CharBlock &source{std::get<Verbatim>(o.t).source};
83+
return parsing->allCooked()
84+
.GetSourcePositionRange(source)
85+
->first;
86+
},
87+
c.u);
8288
},
8389
[&](const OpenMPSectionConstruct &c) -> SourcePosition {
8490
const CharBlock &source{c.source};
85-
return parsing->allCooked().GetSourcePositionRange(source)->first;
91+
return (parsing->allCooked().GetSourcePositionRange(source))->first;
8692
},
8793
[&](const OpenMPUtilityConstruct &c) -> SourcePosition {
8894
const CharBlock &source{c.source};
89-
return parsing->allCooked().GetSourcePositionRange(source)->first;
95+
return (parsing->allCooked().GetSourcePositionRange(source))->first;
9096
},
9197
},
9298
c.u);
@@ -151,9 +157,14 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
151157
return normalize_construct_name(source.ToString());
152158
},
153159
[&](const OpenMPAtomicConstruct &c) -> std::string {
154-
auto &dirSpec = std::get<OmpDirectiveSpecification>(c.t);
155-
auto &dirName = std::get<OmpDirectiveName>(dirSpec.t);
156-
return normalize_construct_name(dirName.source.ToString());
160+
return std::visit(
161+
[&](const auto &c) {
162+
// Get source from the verbatim fields
163+
const CharBlock &source{std::get<Verbatim>(c.t).source};
164+
return "atomic-" +
165+
normalize_construct_name(source.ToString());
166+
},
167+
c.u);
157168
},
158169
[&](const OpenMPUtilityConstruct &c) -> std::string {
159170
const CharBlock &source{c.source};

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,15 @@ class ParseTreeDumper {
532532
NODE(parser, OmpAtClause)
533533
NODE_ENUM(OmpAtClause, ActionTime)
534534
NODE_ENUM(OmpSeverityClause, Severity)
535+
NODE(parser, OmpAtomic)
536+
NODE(parser, OmpAtomicCapture)
537+
NODE(OmpAtomicCapture, Stmt1)
538+
NODE(OmpAtomicCapture, Stmt2)
539+
NODE(parser, OmpAtomicCompare)
540+
NODE(parser, OmpAtomicCompareIfStmt)
541+
NODE(parser, OmpAtomicRead)
542+
NODE(parser, OmpAtomicUpdate)
543+
NODE(parser, OmpAtomicWrite)
535544
NODE(parser, OmpBeginBlockDirective)
536545
NODE(parser, OmpBeginLoopDirective)
537546
NODE(parser, OmpBeginSectionsDirective)
@@ -578,6 +587,7 @@ class ParseTreeDumper {
578587
NODE(parser, OmpDoacrossClause)
579588
NODE(parser, OmpDestroyClause)
580589
NODE(parser, OmpEndAllocators)
590+
NODE(parser, OmpEndAtomic)
581591
NODE(parser, OmpEndBlockDirective)
582592
NODE(parser, OmpEndCriticalDirective)
583593
NODE(parser, OmpEndLoopDirective)
@@ -706,6 +716,8 @@ class ParseTreeDumper {
706716
NODE(parser, OpenMPDeclareMapperConstruct)
707717
NODE_ENUM(common, OmpMemoryOrderType)
708718
NODE(parser, OmpMemoryOrderClause)
719+
NODE(parser, OmpAtomicClause)
720+
NODE(parser, OmpAtomicClauseList)
709721
NODE(parser, OmpAtomicDefaultMemOrderClause)
710722
NODE(parser, OpenMPDepobjConstruct)
711723
NODE(parser, OpenMPUtilityConstruct)

flang/include/flang/Parser/parse-tree.h

Lines changed: 84 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4857,37 +4857,94 @@ struct OmpMemoryOrderClause {
48574857
CharBlock source;
48584858
};
48594859

4860-
struct OpenMPAtomicConstruct {
4861-
llvm::omp::Clause GetKind() const;
4862-
bool IsCapture() const;
4863-
bool IsCompare() const;
4864-
TUPLE_CLASS_BOILERPLATE(OpenMPAtomicConstruct);
4860+
// 2.17.7 Atomic construct
4861+
// atomic-clause -> memory-order-clause | HINT(hint-expression) |
4862+
// FAIL(memory-order)
4863+
struct OmpAtomicClause {
4864+
UNION_CLASS_BOILERPLATE(OmpAtomicClause);
4865+
CharBlock source;
4866+
std::variant<OmpMemoryOrderClause, OmpFailClause, OmpHintClause> u;
4867+
};
4868+
4869+
// atomic-clause-list -> [atomic-clause, [atomic-clause], ...]
4870+
struct OmpAtomicClauseList {
4871+
WRAPPER_CLASS_BOILERPLATE(OmpAtomicClauseList, std::list<OmpAtomicClause>);
4872+
CharBlock source;
4873+
};
4874+
4875+
// END ATOMIC
4876+
EMPTY_CLASS(OmpEndAtomic);
4877+
4878+
// ATOMIC READ
4879+
struct OmpAtomicRead {
4880+
TUPLE_CLASS_BOILERPLATE(OmpAtomicRead);
4881+
CharBlock source;
4882+
std::tuple<OmpAtomicClauseList, Verbatim, OmpAtomicClauseList,
4883+
Statement<AssignmentStmt>, std::optional<OmpEndAtomic>>
4884+
t;
4885+
};
4886+
4887+
// ATOMIC WRITE
4888+
struct OmpAtomicWrite {
4889+
TUPLE_CLASS_BOILERPLATE(OmpAtomicWrite);
48654890
CharBlock source;
4866-
std::tuple<OmpDirectiveSpecification, Block,
4867-
std::optional<OmpDirectiveSpecification>>
4891+
std::tuple<OmpAtomicClauseList, Verbatim, OmpAtomicClauseList,
4892+
Statement<AssignmentStmt>, std::optional<OmpEndAtomic>>
48684893
t;
4894+
};
48694895

4870-
// Information filled out during semantic checks to avoid duplication
4871-
// of analyses.
4872-
struct Analysis {
4873-
static constexpr int None = 0;
4874-
static constexpr int Read = 1;
4875-
static constexpr int Write = 2;
4876-
static constexpr int Update = Read | Write;
4877-
static constexpr int Action = 3; // Bitmask for None, Read, Write, Update
4878-
static constexpr int IfTrue = 4;
4879-
static constexpr int IfFalse = 8;
4880-
static constexpr int Condition = 12; // Bitmask for IfTrue, IfFalse
4881-
4882-
struct Op {
4883-
int what;
4884-
AssignmentStmt::TypedAssignment assign;
4885-
};
4886-
TypedExpr atom, cond;
4887-
Op op0, op1;
4888-
};
4896+
// ATOMIC UPDATE
4897+
struct OmpAtomicUpdate {
4898+
TUPLE_CLASS_BOILERPLATE(OmpAtomicUpdate);
4899+
CharBlock source;
4900+
std::tuple<OmpAtomicClauseList, Verbatim, OmpAtomicClauseList,
4901+
Statement<AssignmentStmt>, std::optional<OmpEndAtomic>>
4902+
t;
4903+
};
48894904

4890-
mutable Analysis analysis;
4905+
// ATOMIC CAPTURE
4906+
struct OmpAtomicCapture {
4907+
TUPLE_CLASS_BOILERPLATE(OmpAtomicCapture);
4908+
CharBlock source;
4909+
WRAPPER_CLASS(Stmt1, Statement<AssignmentStmt>);
4910+
WRAPPER_CLASS(Stmt2, Statement<AssignmentStmt>);
4911+
std::tuple<OmpAtomicClauseList, Verbatim, OmpAtomicClauseList, Stmt1, Stmt2,
4912+
OmpEndAtomic>
4913+
t;
4914+
};
4915+
4916+
struct OmpAtomicCompareIfStmt {
4917+
UNION_CLASS_BOILERPLATE(OmpAtomicCompareIfStmt);
4918+
std::variant<common::Indirection<IfStmt>, common::Indirection<IfConstruct>> u;
4919+
};
4920+
4921+
// ATOMIC COMPARE (OpenMP 5.1, OPenMP 5.2 spec: 15.8.4)
4922+
struct OmpAtomicCompare {
4923+
TUPLE_CLASS_BOILERPLATE(OmpAtomicCompare);
4924+
CharBlock source;
4925+
std::tuple<OmpAtomicClauseList, Verbatim, OmpAtomicClauseList,
4926+
OmpAtomicCompareIfStmt, std::optional<OmpEndAtomic>>
4927+
t;
4928+
};
4929+
4930+
// ATOMIC
4931+
struct OmpAtomic {
4932+
TUPLE_CLASS_BOILERPLATE(OmpAtomic);
4933+
CharBlock source;
4934+
std::tuple<Verbatim, OmpAtomicClauseList, Statement<AssignmentStmt>,
4935+
std::optional<OmpEndAtomic>>
4936+
t;
4937+
};
4938+
4939+
// 2.17.7 atomic ->
4940+
// ATOMIC [atomic-clause-list] atomic-construct [atomic-clause-list] |
4941+
// ATOMIC [atomic-clause-list]
4942+
// atomic-construct -> READ | WRITE | UPDATE | CAPTURE | COMPARE
4943+
struct OpenMPAtomicConstruct {
4944+
UNION_CLASS_BOILERPLATE(OpenMPAtomicConstruct);
4945+
std::variant<OmpAtomicRead, OmpAtomicWrite, OmpAtomicCapture, OmpAtomicUpdate,
4946+
OmpAtomicCompare, OmpAtomic>
4947+
u;
48914948
};
48924949

48934950
// OpenMP directives that associate with loop(s)

0 commit comments

Comments
 (0)