Skip to content

Commit 572b8ea

Browse files
committed
Revert "Revert "[flang][OpenMP] Overhaul implementation of ATOMIC construct (llvm#137852)""
This reverts commit 9261cd4.
1 parent d1bb1b1 commit 572b8ea

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

+3757
-1998
lines changed

flang/docs/OpenMPSupport.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,16 @@ 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: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -445,13 +445,6 @@ 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)
455448
READ_FEATURE(OmpBeginBlockDirective)
456449
READ_FEATURE(OmpBeginLoopDirective)
457450
READ_FEATURE(OmpBeginSectionsDirective)
@@ -480,7 +473,6 @@ struct NodeVisitor {
480473
READ_FEATURE(OmpIterationOffset)
481474
READ_FEATURE(OmpIterationVector)
482475
READ_FEATURE(OmpEndAllocators)
483-
READ_FEATURE(OmpEndAtomic)
484476
READ_FEATURE(OmpEndBlockDirective)
485477
READ_FEATURE(OmpEndCriticalDirective)
486478
READ_FEATURE(OmpEndLoopDirective)
@@ -566,8 +558,6 @@ struct NodeVisitor {
566558
READ_FEATURE(OpenMPDeclareTargetConstruct)
567559
READ_FEATURE(OmpMemoryOrderType)
568560
READ_FEATURE(OmpMemoryOrderClause)
569-
READ_FEATURE(OmpAtomicClause)
570-
READ_FEATURE(OmpAtomicClauseList)
571561
READ_FEATURE(OmpAtomicDefaultMemOrderClause)
572562
READ_FEATURE(OpenMPFlushConstruct)
573563
READ_FEATURE(OpenMPLoopConstruct)

flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,19 @@ 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-
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);
80+
const CharBlock &source{c.source};
81+
return parsing->allCooked().GetSourcePositionRange(source)->first;
8882
},
8983
[&](const OpenMPSectionConstruct &c) -> SourcePosition {
9084
const CharBlock &source{c.source};
91-
return (parsing->allCooked().GetSourcePositionRange(source))->first;
85+
return parsing->allCooked().GetSourcePositionRange(source)->first;
9286
},
9387
[&](const OpenMPUtilityConstruct &c) -> SourcePosition {
9488
const CharBlock &source{c.source};
95-
return (parsing->allCooked().GetSourcePositionRange(source))->first;
89+
return parsing->allCooked().GetSourcePositionRange(source)->first;
9690
},
9791
},
9892
c.u);
@@ -157,14 +151,9 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
157151
return normalize_construct_name(source.ToString());
158152
},
159153
[&](const OpenMPAtomicConstruct &c) -> std::string {
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);
154+
auto &dirSpec = std::get<OmpDirectiveSpecification>(c.t);
155+
auto &dirName = std::get<OmpDirectiveName>(dirSpec.t);
156+
return normalize_construct_name(dirName.source.ToString());
168157
},
169158
[&](const OpenMPUtilityConstruct &c) -> std::string {
170159
const CharBlock &source{c.source};

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -532,15 +532,6 @@ 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)
544535
NODE(parser, OmpBeginBlockDirective)
545536
NODE(parser, OmpBeginLoopDirective)
546537
NODE(parser, OmpBeginSectionsDirective)
@@ -587,7 +578,6 @@ class ParseTreeDumper {
587578
NODE(parser, OmpDoacrossClause)
588579
NODE(parser, OmpDestroyClause)
589580
NODE(parser, OmpEndAllocators)
590-
NODE(parser, OmpEndAtomic)
591581
NODE(parser, OmpEndBlockDirective)
592582
NODE(parser, OmpEndCriticalDirective)
593583
NODE(parser, OmpEndLoopDirective)
@@ -716,8 +706,6 @@ class ParseTreeDumper {
716706
NODE(parser, OpenMPDeclareMapperConstruct)
717707
NODE_ENUM(common, OmpMemoryOrderType)
718708
NODE(parser, OmpMemoryOrderClause)
719-
NODE(parser, OmpAtomicClause)
720-
NODE(parser, OmpAtomicClauseList)
721709
NODE(parser, OmpAtomicDefaultMemOrderClause)
722710
NODE(parser, OpenMPDepobjConstruct)
723711
NODE(parser, OpenMPUtilityConstruct)

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

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

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);
4890-
CharBlock source;
4891-
std::tuple<OmpAtomicClauseList, Verbatim, OmpAtomicClauseList,
4892-
Statement<AssignmentStmt>, std::optional<OmpEndAtomic>>
4893-
t;
4894-
};
4895-
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-
};
4904-
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);
4860+
struct OpenMPAtomicConstruct {
4861+
llvm::omp::Clause GetKind() const;
4862+
bool IsCapture() const;
4863+
bool IsCompare() const;
4864+
TUPLE_CLASS_BOILERPLATE(OpenMPAtomicConstruct);
49244865
CharBlock source;
4925-
std::tuple<OmpAtomicClauseList, Verbatim, OmpAtomicClauseList,
4926-
OmpAtomicCompareIfStmt, std::optional<OmpEndAtomic>>
4866+
std::tuple<OmpDirectiveSpecification, Block,
4867+
std::optional<OmpDirectiveSpecification>>
49274868
t;
4928-
};
49294869

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-
};
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+
};
49384889

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;
4890+
mutable Analysis analysis;
49484891
};
49494892

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

0 commit comments

Comments
 (0)