Skip to content

Commit c478aab

Browse files
authored
[flang][OpenMP] Parser support for DEPOBJ plus DEPEND, DESTROY, UPDATE (#114074)
Parse the DEPOBJ construct and the associated clauses, perform basic semantic checks.
1 parent 5082638 commit c478aab

File tree

21 files changed

+429
-51
lines changed

21 files changed

+429
-51
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ class ParseTreeDumper {
517517
NODE_ENUM(OmpTaskDependenceType, Type)
518518
NODE(parser, OmpDependSinkVec)
519519
NODE(parser, OmpDependSinkVecLength)
520+
NODE(parser, OmpDestroyClause)
520521
NODE(parser, OmpEndAllocators)
521522
NODE(parser, OmpEndAtomic)
522523
NODE(parser, OmpEndBlockDirective)
@@ -571,6 +572,7 @@ class ParseTreeDumper {
571572
NODE_ENUM(OmpDeviceClause, DeviceModifier)
572573
NODE(parser, OmpDeviceTypeClause)
573574
NODE_ENUM(OmpDeviceTypeClause, Type)
575+
NODE(parser, OmpUpdateClause)
574576
NODE(parser, OmpScheduleModifier)
575577
NODE(OmpScheduleModifier, Modifier1)
576578
NODE(OmpScheduleModifier, Modifier2)
@@ -609,6 +611,7 @@ class ParseTreeDumper {
609611
NODE(parser, OmpAtomicClauseList)
610612
NODE(parser, OmpAtomicDefaultMemOrderClause)
611613
NODE_ENUM(common, OmpAtomicDefaultMemOrderType)
614+
NODE(parser, OpenMPDepobjConstruct)
612615
NODE(parser, OpenMPFlushConstruct)
613616
NODE(parser, OpenMPLoopConstruct)
614617
NODE(parser, OpenMPExecutableAllocate)

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

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3447,7 +3447,7 @@ WRAPPER_CLASS(OmpObjectList, std::list<OmpObject>);
34473447
// MUTEXINOUTSET | DEPOBJ | // since 5.0
34483448
// INOUTSET // since 5.2
34493449
struct OmpTaskDependenceType {
3450-
ENUM_CLASS(Type, In, Out, Inout, Source, Sink)
3450+
ENUM_CLASS(Type, In, Out, Inout, Source, Sink, Depobj)
34513451
WRAPPER_CLASS_BOILERPLATE(OmpTaskDependenceType, Type);
34523452
};
34533453

@@ -3527,19 +3527,6 @@ struct OmpDefaultmapClause {
35273527
std::tuple<ImplicitBehavior, std::optional<VariableCategory>> t;
35283528
};
35293529

3530-
// device([ device-modifier :] scalar-integer-expression)
3531-
struct OmpDeviceClause {
3532-
TUPLE_CLASS_BOILERPLATE(OmpDeviceClause);
3533-
ENUM_CLASS(DeviceModifier, Ancestor, Device_Num)
3534-
std::tuple<std::optional<DeviceModifier>, ScalarIntExpr> t;
3535-
};
3536-
3537-
// device_type(any | host | nohost)
3538-
struct OmpDeviceTypeClause {
3539-
ENUM_CLASS(Type, Any, Host, Nohost)
3540-
WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, Type);
3541-
};
3542-
35433530
// 2.13.9 depend-vec-length -> +/- non-negative-constant
35443531
struct OmpDependSinkVecLength {
35453532
TUPLE_CLASS_BOILERPLATE(OmpDependSinkVecLength);
@@ -3561,6 +3548,8 @@ struct OmpDependSinkVec {
35613548
//
35623549
// depend-modifier -> iterator-modifier // since 5.0
35633550
struct OmpDependClause {
3551+
OmpTaskDependenceType::Type GetDepType() const;
3552+
35643553
UNION_CLASS_BOILERPLATE(OmpDependClause);
35653554
EMPTY_CLASS(Source);
35663555
WRAPPER_CLASS(Sink, std::list<OmpDependSinkVec>);
@@ -3573,6 +3562,26 @@ struct OmpDependClause {
35733562
std::variant<Source, Sink, InOut> u;
35743563
};
35753564

3565+
// Ref: [5.0:254-255], [5.1:287-288], [5.2:73]
3566+
//
3567+
// destroy-clause ->
3568+
// DESTROY | // since 5.0, until 5.2
3569+
// DESTROY(variable) // since 5.2
3570+
WRAPPER_CLASS(OmpDestroyClause, OmpObject);
3571+
3572+
// device([ device-modifier :] scalar-integer-expression)
3573+
struct OmpDeviceClause {
3574+
TUPLE_CLASS_BOILERPLATE(OmpDeviceClause);
3575+
ENUM_CLASS(DeviceModifier, Ancestor, Device_Num)
3576+
std::tuple<std::optional<DeviceModifier>, ScalarIntExpr> t;
3577+
};
3578+
3579+
// device_type(any | host | nohost)
3580+
struct OmpDeviceTypeClause {
3581+
ENUM_CLASS(Type, Any, Host, Nohost)
3582+
WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, Type);
3583+
};
3584+
35763585
// OMP 5.2 12.6.1 grainsize-clause -> grainsize ([prescriptiveness :] value)
35773586
struct OmpGrainsizeClause {
35783587
TUPLE_CLASS_BOILERPLATE(OmpGrainsizeClause);
@@ -3716,6 +3725,11 @@ struct OmpNumTasksClause {
37163725
std::tuple<std::optional<Prescriptiveness>, ScalarIntExpr> t;
37173726
};
37183727

3728+
// Ref: [5.0:254-255], [5.1:287-288], [5.2:321-322]
3729+
//
3730+
// update-clause -> UPDATE(task-dependence-type) // since 5.0
3731+
WRAPPER_CLASS(OmpUpdateClause, OmpTaskDependenceType);
3732+
37193733
// OpenMP Clauses
37203734
struct OmpClause {
37213735
UNION_CLASS_BOILERPLATE(OmpClause);
@@ -4023,6 +4037,18 @@ struct OpenMPCancelConstruct {
40234037
std::tuple<Verbatim, OmpCancelType, std::optional<If>> t;
40244038
};
40254039

4040+
// Ref: [5.0:254-255], [5.1:287-288], [5.2:322-323]
4041+
//
4042+
// depobj-construct -> DEPOBJ(depend-object) depobj-clause // since 5.0
4043+
// depobj-clause -> depend-clause | // until 5.2
4044+
// destroy-clause |
4045+
// update-clause
4046+
struct OpenMPDepobjConstruct {
4047+
TUPLE_CLASS_BOILERPLATE(OpenMPDepobjConstruct);
4048+
CharBlock source;
4049+
std::tuple<Verbatim, OmpObject, OmpClause> t;
4050+
};
4051+
40264052
// 2.17.8 flush -> FLUSH [memory-order-clause] [(variable-name-list)]
40274053
struct OpenMPFlushConstruct {
40284054
TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct);
@@ -4047,7 +4073,8 @@ struct OpenMPStandaloneConstruct {
40474073
UNION_CLASS_BOILERPLATE(OpenMPStandaloneConstruct);
40484074
CharBlock source;
40494075
std::variant<OpenMPSimpleStandaloneConstruct, OpenMPFlushConstruct,
4050-
OpenMPCancelConstruct, OpenMPCancellationPointConstruct>
4076+
OpenMPCancelConstruct, OpenMPCancellationPointConstruct,
4077+
OpenMPDepobjConstruct>
40514078
u;
40524079
};
40534080

flang/include/flang/Semantics/symbol.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ class Symbol {
755755
OmpDeclarativeAllocateDirective, OmpExecutableAllocateDirective,
756756
OmpDeclareSimd, OmpDeclareTarget, OmpThreadprivate, OmpDeclareReduction,
757757
OmpFlushed, OmpCriticalLock, OmpIfSpecified, OmpNone, OmpPreDetermined,
758-
OmpImplicit);
758+
OmpImplicit, OmpDependObject);
759759
using Flags = common::EnumSet<Flag, Flag_enumSize>;
760760

761761
const Scope &owner() const { return *owner_; }

flang/lib/Lower/OpenMP/ClauseProcessor.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ genDependKindAttr(fir::FirOpBuilder &firOpBuilder,
137137
case omp::clause::Depend::TaskDependenceType::Mutexinoutset:
138138
case omp::clause::Depend::TaskDependenceType::Inoutset:
139139
case omp::clause::Depend::TaskDependenceType::Depobj:
140+
case omp::clause::Depend::TaskDependenceType::Sink:
141+
case omp::clause::Depend::TaskDependenceType::Source:
140142
llvm_unreachable("unhandled parser task dependence type");
141143
break;
142144
}

flang/lib/Lower/OpenMP/Clauses.cpp

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,27 @@ ReductionOperator makeReductionOperator(const parser::OmpReductionOperator &inp,
338338
inp.u);
339339
}
340340

341+
clause::TaskDependenceType
342+
makeDepType(const parser::OmpTaskDependenceType &inp) {
343+
switch (inp.v) {
344+
case parser::OmpTaskDependenceType::Type::Depobj:
345+
return clause::TaskDependenceType::Depobj;
346+
case parser::OmpTaskDependenceType::Type::In:
347+
return clause::TaskDependenceType::In;
348+
case parser::OmpTaskDependenceType::Type::Inout:
349+
return clause::TaskDependenceType::Inout;
350+
// Inoutset // missing-in-parser
351+
// Mutexinoutset // missing-in-parser
352+
case parser::OmpTaskDependenceType::Type::Out:
353+
return clause::TaskDependenceType::Out;
354+
case parser::OmpTaskDependenceType::Type::Sink:
355+
return clause::TaskDependenceType::Sink;
356+
case parser::OmpTaskDependenceType::Type::Source:
357+
return clause::TaskDependenceType::Source;
358+
}
359+
llvm_unreachable("Unexpected dependence type");
360+
}
361+
341362
// --------------------------------------------------------------------
342363
// Actual clauses. Each T (where tomp::T exists in ClauseT) has its "make".
343364

@@ -554,18 +575,6 @@ Depend make(const parser::OmpClause::Depend &inp,
554575
// Iteration is the equivalent of parser::OmpDependSinkVec
555576
using Iteration = Doacross::Vector::value_type; // LoopIterationT
556577

557-
CLAUSET_ENUM_CONVERT( //
558-
convert1, parser::OmpTaskDependenceType::Type, Depend::TaskDependenceType,
559-
// clang-format off
560-
MS(In, In)
561-
MS(Out, Out)
562-
MS(Inout, Inout)
563-
// MS(, Mutexinoutset) // missing-in-parser
564-
// MS(, Inputset) // missing-in-parser
565-
// MS(, Depobj) // missing-in-parser
566-
// clang-format on
567-
);
568-
569578
return Depend{Fortran::common::visit( //
570579
common::visitors{
571580
// Doacross
@@ -602,7 +611,7 @@ Depend make(const parser::OmpClause::Depend &inp,
602611

603612
auto &&maybeIter = maybeApply(
604613
[&](auto &&s) { return makeIterator(s, semaCtx); }, t0);
605-
return Depend::DepType{{/*TaskDependenceType=*/convert1(t1.v),
614+
return Depend::DepType{{/*TaskDependenceType=*/makeDepType(t1),
606615
/*Iterator=*/std::move(maybeIter),
607616
/*LocatorList=*/makeObjects(t2, semaCtx)}};
608617
},
@@ -614,8 +623,14 @@ Depend make(const parser::OmpClause::Depend &inp,
614623

615624
Destroy make(const parser::OmpClause::Destroy &inp,
616625
semantics::SemanticsContext &semaCtx) {
617-
// inp -> empty
618-
llvm_unreachable("Empty: destroy");
626+
// inp.v -> std::optional<OmpDestroyClause>
627+
auto &&maybeObject = maybeApply(
628+
[&](const parser::OmpDestroyClause &c) {
629+
return makeObject(c.v, semaCtx);
630+
},
631+
inp.v);
632+
633+
return Destroy{/*DestroyVar=*/std::move(maybeObject)};
619634
}
620635

621636
Detach make(const parser::OmpClause::Detach &inp,
@@ -1279,8 +1294,8 @@ Uniform make(const parser::OmpClause::Uniform &inp,
12791294

12801295
Update make(const parser::OmpClause::Update &inp,
12811296
semantics::SemanticsContext &semaCtx) {
1282-
// inp -> empty
1283-
return Update{/*TaskDependenceType=*/std::nullopt};
1297+
// inp.v -> parser::OmpUpdateClause
1298+
return Update{/*TaskDependenceType=*/makeDepType(inp.v.v)};
12841299
}
12851300

12861301
Use make(const parser::OmpClause::Use &inp,

flang/lib/Lower/OpenMP/Clauses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ using IteratorSpecifier = tomp::type::IteratorSpecifierT<TypeTy, IdTy, ExprTy>;
152152
using DefinedOperator = tomp::type::DefinedOperatorT<IdTy, ExprTy>;
153153
using ProcedureDesignator = tomp::type::ProcedureDesignatorT<IdTy, ExprTy>;
154154
using ReductionOperator = tomp::type::ReductionIdentifierT<IdTy, ExprTy>;
155+
using TaskDependenceType = tomp::type::TaskDependenceType;
155156

156157
// "Requires" clauses are handled early on, and the aggregated information
157158
// is stored in the Symbol details of modules, programs, and subprograms.

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2710,6 +2710,21 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
27102710
TODO(converter.getCurrentLocation(), "OpenMPCancelConstruct");
27112711
}
27122712

2713+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
2714+
semantics::SemanticsContext &semaCtx,
2715+
lower::pft::Evaluation &eval,
2716+
const parser::OpenMPDepobjConstruct &construct) {
2717+
// These values will be ignored until the construct itself is implemented,
2718+
// but run them anyway for the sake of testing (via a Todo test).
2719+
auto &ompObj = std::get<parser::OmpObject>(construct.t);
2720+
const Object &depObj = makeObject(ompObj, semaCtx);
2721+
Clause clause = makeClause(std::get<parser::OmpClause>(construct.t), semaCtx);
2722+
(void)depObj;
2723+
(void)clause;
2724+
2725+
TODO(converter.getCurrentLocation(), "OpenMPDepobjConstruct");
2726+
}
2727+
27132728
static void
27142729
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
27152730
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,12 @@ TYPE_PARSER(
366366
construct<OmpDependSinkVec>(name, maybe(Parser<OmpDependSinkVecLength>{})))
367367

368368
TYPE_PARSER(construct<OmpTaskDependenceType>(
369+
"DEPOBJ" >> pure(OmpTaskDependenceType::Type::Depobj) ||
369370
"IN"_id >> pure(OmpTaskDependenceType::Type::In) ||
370371
"INOUT" >> pure(OmpTaskDependenceType::Type::Inout) ||
371-
"OUT" >> pure(OmpTaskDependenceType::Type::Out)))
372+
"OUT" >> pure(OmpTaskDependenceType::Type::Out) ||
373+
"SINK" >> pure(OmpTaskDependenceType::Type::Sink) ||
374+
"SOURCE" >> pure(OmpTaskDependenceType::Type::Source)))
372375

373376
TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
374377
construct<OmpDependClause>(construct<OmpDependClause::Sink>(
@@ -454,6 +457,9 @@ TYPE_PARSER(
454457
parenthesized(Parser<OmpDefaultmapClause>{}))) ||
455458
"DEPEND" >> construct<OmpClause>(construct<OmpClause::Depend>(
456459
parenthesized(Parser<OmpDependClause>{}))) ||
460+
"DESTROY" >>
461+
construct<OmpClause>(construct<OmpClause::Destroy>(maybe(parenthesized(
462+
construct<OmpDestroyClause>(Parser<OmpObject>{}))))) ||
457463
"DEVICE" >> construct<OmpClause>(construct<OmpClause::Device>(
458464
parenthesized(Parser<OmpDeviceClause>{}))) ||
459465
"DEVICE_TYPE" >> construct<OmpClause>(construct<OmpClause::DeviceType>(
@@ -560,7 +566,9 @@ TYPE_PARSER(
560566
construct<OmpClause>(construct<OmpClause::UnifiedSharedMemory>()) ||
561567
"UNIFORM" >> construct<OmpClause>(construct<OmpClause::Uniform>(
562568
parenthesized(nonemptyList(name)))) ||
563-
"UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>()))
569+
"UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>()) ||
570+
"UPDATE" >> construct<OmpClause>(construct<OmpClause::Update>(
571+
parenthesized(Parser<OmpTaskDependenceType>{}))))
564572

565573
// [Clause, [Clause], ...]
566574
TYPE_PARSER(sourced(construct<OmpClauseList>(
@@ -680,6 +688,9 @@ TYPE_PARSER(sourced(construct<OmpAtomicClause>(
680688
TYPE_PARSER(sourced(construct<OmpAtomicClauseList>(
681689
many(maybe(","_tok) >> sourced(Parser<OmpAtomicClause>{})))))
682690

691+
TYPE_PARSER(sourced(construct<OpenMPDepobjConstruct>(verbatim("DEPOBJ"_tok),
692+
parenthesized(Parser<OmpObject>{}), sourced(Parser<OmpClause>{}))))
693+
683694
TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(verbatim("FLUSH"_tok),
684695
many(maybe(","_tok) >> sourced(Parser<OmpMemoryOrderClause>{})),
685696
maybe(parenthesized(Parser<OmpObjectList>{})))))
@@ -704,7 +715,8 @@ TYPE_PARSER(
704715
construct<OpenMPStandaloneConstruct>(Parser<OpenMPFlushConstruct>{}) ||
705716
construct<OpenMPStandaloneConstruct>(Parser<OpenMPCancelConstruct>{}) ||
706717
construct<OpenMPStandaloneConstruct>(
707-
Parser<OpenMPCancellationPointConstruct>{})) /
718+
Parser<OpenMPCancellationPointConstruct>{}) ||
719+
construct<OpenMPStandaloneConstruct>(Parser<OpenMPDepobjConstruct>{})) /
708720
endOfLine)
709721

710722
// Directives enclosing structured-block

flang/lib/Parser/parse-tree.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,23 @@ CharBlock Variable::GetSource() const {
252252
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Name &x) {
253253
return os << x.ToString();
254254
}
255+
256+
OmpTaskDependenceType::Type OmpDependClause::GetDepType() const {
257+
return common::visit(
258+
common::visitors{
259+
[&](const parser::OmpDependClause::Source &) {
260+
return parser::OmpTaskDependenceType::Type::Source;
261+
},
262+
[&](const parser::OmpDependClause::Sink &) {
263+
return parser::OmpTaskDependenceType::Type::Sink;
264+
},
265+
[&](const parser::OmpDependClause::InOut &y) {
266+
return std::get<parser::OmpTaskDependenceType>(y.t).v;
267+
},
268+
},
269+
u);
270+
}
271+
255272
} // namespace Fortran::parser
256273

257274
template <typename C> static llvm::omp::Clause getClauseIdForClass(C &&) {

flang/lib/Parser/unparse.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,11 +2215,9 @@ class UnparseVisitor {
22152215
Walk(std::get<std::optional<OmpDependSinkVecLength>>(x.t));
22162216
}
22172217
void Unparse(const OmpDependClause::InOut &x) {
2218-
Put("(");
22192218
Walk(std::get<OmpTaskDependenceType>(x.t));
22202219
Put(":");
22212220
Walk(std::get<OmpObjectList>(x.t));
2222-
Put(")");
22232221
}
22242222
bool Pre(const OmpDependClause &x) {
22252223
return common::visit(
@@ -2721,6 +2719,16 @@ class UnparseVisitor {
27212719
},
27222720
x.u);
27232721
}
2722+
void Unparse(const OpenMPDepobjConstruct &x) {
2723+
BeginOpenMP();
2724+
Word("!$OMP DEPOBJ");
2725+
Put("(");
2726+
Walk(std::get<OmpObject>(x.t));
2727+
Put(") ");
2728+
Walk(std::get<OmpClause>(x.t));
2729+
Put("\n");
2730+
EndOpenMP();
2731+
}
27242732
void Unparse(const OpenMPFlushConstruct &x) {
27252733
BeginOpenMP();
27262734
Word("!$OMP FLUSH ");

0 commit comments

Comments
 (0)