Skip to content

Commit fe30cf1

Browse files
Revert "Revert "[flang][openmp] Adds Parser and Semantic Support for Interop Construct, and Init and Use Clauses."" (#132343)
Reverts #132005
1 parent 2218587 commit fe30cf1

File tree

14 files changed

+525
-2
lines changed

14 files changed

+525
-2
lines changed

flang/examples/FeatureList/FeatureList.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,13 @@ struct NodeVisitor {
522522
READ_FEATURE(OmpScheduleClause)
523523
READ_FEATURE(OmpScheduleClause::Kind)
524524
READ_FEATURE(OmpScheduleClause::Modifier)
525+
READ_FEATURE(OmpInteropRuntimeIdentifier)
526+
READ_FEATURE(OmpInteropPreference)
527+
READ_FEATURE(OmpInteropType)
528+
READ_FEATURE(OmpInteropType::Value)
529+
READ_FEATURE(OmpInitClause)
530+
READ_FEATURE(OmpInitClause::Modifier)
531+
READ_FEATURE(OmpUseClause)
525532
READ_FEATURE(OmpDeviceModifier)
526533
READ_FEATURE(OmpDeviceClause)
527534
READ_FEATURE(OmpDeviceClause::Modifier)
@@ -541,6 +548,7 @@ struct NodeVisitor {
541548
READ_FEATURE(OpenACCConstruct)
542549
READ_FEATURE(OpenACCDeclarativeConstruct)
543550
READ_FEATURE(OpenACCLoopConstruct)
551+
READ_FEATURE(OpenMPInteropConstruct)
544552
READ_FEATURE(OpenACCRoutineConstruct)
545553
READ_FEATURE(OpenACCStandaloneDeclarativeConstruct)
546554
READ_FEATURE(OpenACCStandaloneConstruct)

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,13 @@ class ParseTreeDumper {
657657
NODE_ENUM(OmpDeviceModifier, Value)
658658
NODE(parser, OmpDeviceTypeClause)
659659
NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription)
660+
NODE(parser, OmpInteropRuntimeIdentifier)
661+
NODE(parser, OmpInteropPreference)
662+
NODE(parser, OmpInteropType)
663+
NODE_ENUM(OmpInteropType, Value)
664+
NODE(parser, OmpInitClause)
665+
NODE(OmpInitClause, Modifier)
666+
NODE(parser, OmpUseClause)
660667
NODE(parser, OmpUpdateClause)
661668
NODE(parser, OmpChunkModifier)
662669
NODE_ENUM(OmpChunkModifier, Value)
@@ -675,6 +682,7 @@ class ParseTreeDumper {
675682
NODE(parser, OpenACCDeclarativeConstruct)
676683
NODE(parser, OpenACCEndConstruct)
677684
NODE(parser, OpenACCLoopConstruct)
685+
NODE(parser, OpenMPInteropConstruct)
678686
NODE(parser, OpenACCRoutineConstruct)
679687
NODE(parser, OpenACCStandaloneDeclarativeConstruct)
680688
NODE(parser, OpenACCStandaloneConstruct)

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

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3829,6 +3829,33 @@ struct OmpExpectation {
38293829
WRAPPER_CLASS_BOILERPLATE(OmpExpectation, Value);
38303830
};
38313831

3832+
// REF: [5.1:217-220], [5.2:293-294]
3833+
//
3834+
// OmpInteropRuntimeIdentifier -> // since 5.2
3835+
// CharLiteralConstant || ScalarIntConstantExpr
3836+
struct OmpInteropRuntimeIdentifier {
3837+
UNION_CLASS_BOILERPLATE(OmpInteropRuntimeIdentifier);
3838+
std::variant<CharLiteralConstant, ScalarIntConstantExpr> u;
3839+
};
3840+
3841+
// REF: [5.1:217-220], [5.2:293-294]
3842+
//
3843+
// OmpInteropPreference -> // since 5.2
3844+
// ([OmpRuntimeIdentifier, ...])
3845+
struct OmpInteropPreference {
3846+
WRAPPER_CLASS_BOILERPLATE(
3847+
OmpInteropPreference, std::list<OmpInteropRuntimeIdentifier>);
3848+
};
3849+
3850+
// REF: [5.1:217-220], [5.2:293-294]
3851+
//
3852+
// InteropType -> target || targetsync // since 5.2
3853+
// There can be at most only two interop-type.
3854+
struct OmpInteropType {
3855+
ENUM_CLASS(Value, Target, TargetSync)
3856+
WRAPPER_CLASS_BOILERPLATE(OmpInteropType, Value);
3857+
};
3858+
38323859
// Ref: [5.0:47-49], [5.1:49-51], [5.2:67-69]
38333860
//
38343861
// iterator-modifier ->
@@ -4486,6 +4513,25 @@ struct OmpWhenClause {
44864513
t;
44874514
};
44884515

4516+
// REF: [5.1:217-220], [5.2:293-294]
4517+
//
4518+
// init-clause -> INIT ([interop-modifier,] [interop-type,]
4519+
// interop-type: interop-var)
4520+
// interop-modifier: prefer_type(preference-list)
4521+
// interop-type: target, targetsync
4522+
// interop-var: Ompobject
4523+
// There can be at most only two interop-type.
4524+
struct OmpInitClause {
4525+
TUPLE_CLASS_BOILERPLATE(OmpInitClause);
4526+
MODIFIER_BOILERPLATE(OmpInteropPreference, OmpInteropType);
4527+
std::tuple<MODIFIERS(), OmpObject> t;
4528+
};
4529+
4530+
// REF: [5.1:217-220], [5.2:294]
4531+
//
4532+
// 14.1.3 use-clause -> USE (interop-var)
4533+
WRAPPER_CLASS(OmpUseClause, OmpObject);
4534+
44894535
// OpenMP Clauses
44904536
struct OmpClause {
44914537
UNION_CLASS_BOILERPLATE(OmpClause);
@@ -4935,6 +4981,14 @@ struct OpenMPFlushConstruct {
49354981
CharBlock source;
49364982
};
49374983

4984+
// Ref: [5.1:217-220], [5.2:291-292]
4985+
//
4986+
// interop -> INTEROP clause[ [ [,] clause]...]
4987+
struct OpenMPInteropConstruct {
4988+
WRAPPER_CLASS_BOILERPLATE(OpenMPInteropConstruct, OmpDirectiveSpecification);
4989+
CharBlock source;
4990+
};
4991+
49384992
struct OpenMPSimpleStandaloneConstruct {
49394993
WRAPPER_CLASS_BOILERPLATE(
49404994
OpenMPSimpleStandaloneConstruct, OmpDirectiveSpecification);
@@ -4946,7 +5000,7 @@ struct OpenMPStandaloneConstruct {
49465000
CharBlock source;
49475001
std::variant<OpenMPSimpleStandaloneConstruct, OpenMPFlushConstruct,
49485002
OpenMPCancelConstruct, OpenMPCancellationPointConstruct,
4949-
OpenMPDepobjConstruct, OmpMetadirectiveDirective>
5003+
OpenMPDepobjConstruct, OmpMetadirectiveDirective, OpenMPInteropConstruct>
49505004
u;
49515005
};
49525006

flang/include/flang/Semantics/openmp-modifiers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ DECLARE_DESCRIPTOR(parser::OmpDependenceType);
7777
DECLARE_DESCRIPTOR(parser::OmpDeviceModifier);
7878
DECLARE_DESCRIPTOR(parser::OmpDirectiveNameModifier);
7979
DECLARE_DESCRIPTOR(parser::OmpExpectation);
80+
DECLARE_DESCRIPTOR(parser::OmpInteropPreference);
81+
DECLARE_DESCRIPTOR(parser::OmpInteropType);
8082
DECLARE_DESCRIPTOR(parser::OmpIterator);
8183
DECLARE_DESCRIPTOR(parser::OmpLastprivateModifier);
8284
DECLARE_DESCRIPTOR(parser::OmpLinearModifier);

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,9 @@ extractOmpDirective(const parser::OpenMPConstruct &ompConstruct) {
424424
},
425425
[](const parser::OpenMPDepobjConstruct &c) {
426426
return llvm::omp::OMPD_depobj;
427+
},
428+
[](const parser::OpenMPInteropConstruct &c) {
429+
return llvm::omp::OMPD_interop;
427430
}},
428431
c.u);
429432
},
@@ -3363,6 +3366,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
33633366
TODO(converter.getCurrentLocation(), "OpenMPDepobjConstruct");
33643367
}
33653368

3369+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3370+
semantics::SemanticsContext &semaCtx,
3371+
lower::pft::Evaluation &eval,
3372+
const parser::OpenMPInteropConstruct &interopConstruct) {
3373+
TODO(converter.getCurrentLocation(), "OpenMPInteropConstruct");
3374+
}
3375+
33663376
static void
33673377
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
33683378
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,17 @@ TYPE_PARSER(construct<OmpDeviceModifier>(
425425
TYPE_PARSER(construct<OmpExpectation>( //
426426
"PRESENT" >> pure(OmpExpectation::Value::Present)))
427427

428+
TYPE_PARSER(construct<OmpInteropRuntimeIdentifier>(
429+
construct<OmpInteropRuntimeIdentifier>(charLiteralConstant) ||
430+
construct<OmpInteropRuntimeIdentifier>(scalarIntConstantExpr)))
431+
432+
TYPE_PARSER(construct<OmpInteropPreference>(verbatim("PREFER_TYPE"_tok) >>
433+
parenthesized(nonemptyList(Parser<OmpInteropRuntimeIdentifier>{}))))
434+
435+
TYPE_PARSER(construct<OmpInteropType>(
436+
"TARGETSYNC" >> pure(OmpInteropType::Value::TargetSync) ||
437+
"TARGET" >> pure(OmpInteropType::Value::Target)))
438+
428439
TYPE_PARSER(construct<OmpIteratorSpecifier>(
429440
// Using Parser<TypeDeclarationStmt> or Parser<EntityDecl> has the problem
430441
// that they will attempt to treat what follows the '=' as initialization.
@@ -552,6 +563,11 @@ TYPE_PARSER(sourced(
552563

553564
TYPE_PARSER(sourced(construct<OmpIfClause::Modifier>(OmpDirectiveNameParser{})))
554565

566+
TYPE_PARSER(sourced(
567+
construct<OmpInitClause::Modifier>(
568+
construct<OmpInitClause::Modifier>(Parser<OmpInteropPreference>{})) ||
569+
construct<OmpInitClause::Modifier>(Parser<OmpInteropType>{})))
570+
555571
TYPE_PARSER(sourced(construct<OmpInReductionClause::Modifier>(
556572
Parser<OmpReductionIdentifier>{})))
557573

@@ -788,6 +804,11 @@ TYPE_PARSER(
788804
// OpenMPv5.2 12.5.2 detach-clause -> DETACH (event-handle)
789805
TYPE_PARSER(construct<OmpDetachClause>(Parser<OmpObject>{}))
790806

807+
// init clause
808+
TYPE_PARSER(construct<OmpInitClause>(
809+
maybe(nonemptyList(Parser<OmpInitClause::Modifier>{}) / ":"),
810+
Parser<OmpObject>{}))
811+
791812
// 2.8.1 ALIGNED (list: alignment)
792813
TYPE_PARSER(construct<OmpAlignedClause>(Parser<OmpObjectList>{},
793814
maybe(":" >> nonemptyList(Parser<OmpAlignedClause::Modifier>{}))))
@@ -927,6 +948,8 @@ TYPE_PARSER( //
927948
"IF" >> construct<OmpClause>(construct<OmpClause::If>(
928949
parenthesized(Parser<OmpIfClause>{}))) ||
929950
"INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
951+
"INIT" >> construct<OmpClause>(construct<OmpClause::Init>(
952+
parenthesized(Parser<OmpInitClause>{}))) ||
930953
"INCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Inclusive>(
931954
parenthesized(Parser<OmpObjectList>{}))) ||
932955
"INITIALIZER" >> construct<OmpClause>(construct<OmpClause::Initializer>(
@@ -1016,6 +1039,8 @@ TYPE_PARSER( //
10161039
parenthesized(scalarIntExpr))) ||
10171040
"TO" >> construct<OmpClause>(construct<OmpClause::To>(
10181041
parenthesized(Parser<OmpToClause>{}))) ||
1042+
"USE" >> construct<OmpClause>(construct<OmpClause::Use>(
1043+
parenthesized(Parser<OmpObject>{}))) ||
10191044
"USE_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::UseDevicePtr>(
10201045
parenthesized(Parser<OmpObjectList>{}))) ||
10211046
"USE_DEVICE_ADDR" >>
@@ -1251,6 +1276,13 @@ TYPE_PARSER(sourced( //
12511276
IsDirective(llvm::omp::Directive::OMPD_depobj)) >=
12521277
Parser<OmpDirectiveSpecification>{})))
12531278

1279+
// OMP 5.2 14.1 Interop construct
1280+
TYPE_PARSER(sourced( //
1281+
construct<OpenMPInteropConstruct>(
1282+
predicated(OmpDirectiveNameParser{},
1283+
IsDirective(llvm::omp::Directive::OMPD_interop)) >=
1284+
Parser<OmpDirectiveSpecification>{})))
1285+
12541286
// Standalone Constructs
12551287
TYPE_PARSER(
12561288
sourced( //
@@ -1263,7 +1295,9 @@ TYPE_PARSER(
12631295
construct<OpenMPStandaloneConstruct>(Parser<OpenMPCancelConstruct>{}) ||
12641296
construct<OpenMPStandaloneConstruct>(
12651297
Parser<OmpMetadirectiveDirective>{}) ||
1266-
construct<OpenMPStandaloneConstruct>(Parser<OpenMPDepobjConstruct>{})) /
1298+
construct<OpenMPStandaloneConstruct>(Parser<OpenMPDepobjConstruct>{}) ||
1299+
construct<OpenMPStandaloneConstruct>(
1300+
Parser<OpenMPInteropConstruct>{})) /
12671301
endOfLine)
12681302

12691303
// Directives enclosing structured-block

flang/lib/Parser/unparse.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,6 +2180,30 @@ class UnparseVisitor {
21802180
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
21812181
Walk(std::get<OmpObjectList>(x.t));
21822182
}
2183+
void Unparse(const OmpInteropPreference &x) { Walk(x.v, ","); }
2184+
void Unparse(const OmpInitClause &x) {
2185+
using Modifier = OmpInitClause::Modifier;
2186+
auto &modifiers{std::get<std::optional<std::list<Modifier>>>(x.t)};
2187+
bool isTypeStart{true};
2188+
for (const Modifier &m : *modifiers) {
2189+
if (auto *interopPreferenceMod{
2190+
std::get_if<parser::OmpInteropPreference>(&m.u)}) {
2191+
Put("PREFER_TYPE(");
2192+
Walk(*interopPreferenceMod);
2193+
Put("),");
2194+
} else if (auto *interopTypeMod{
2195+
std::get_if<parser::OmpInteropType>(&m.u)}) {
2196+
if (isTypeStart) {
2197+
isTypeStart = false;
2198+
} else {
2199+
Put(",");
2200+
}
2201+
Walk(*interopTypeMod);
2202+
}
2203+
}
2204+
Put(": ");
2205+
Walk(std::get<OmpObject>(x.t));
2206+
}
21832207
void Unparse(const OmpMapClause &x) {
21842208
using Modifier = OmpMapClause::Modifier;
21852209
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
@@ -2710,6 +2734,22 @@ class UnparseVisitor {
27102734
Put("\n");
27112735
EndOpenMP();
27122736
}
2737+
2738+
void Unparse(const OpenMPInteropConstruct &x) {
2739+
BeginOpenMP();
2740+
Word("!$OMP INTEROP");
2741+
using Flags = OmpDirectiveSpecification::Flags;
2742+
if (std::get<Flags>(x.v.t) == Flags::DeprecatedSyntax) {
2743+
Walk("(", std::get<std::optional<OmpArgumentList>>(x.v.t), ")");
2744+
Walk(" ", std::get<std::optional<OmpClauseList>>(x.v.t));
2745+
} else {
2746+
Walk(" ", std::get<std::optional<OmpClauseList>>(x.v.t));
2747+
Walk(" (", std::get<std::optional<OmpArgumentList>>(x.v.t), ")");
2748+
}
2749+
Put("\n");
2750+
EndOpenMP();
2751+
}
2752+
27132753
void Unparse(const OpenMPDeclarativeAssumes &x) {
27142754
BeginOpenMP();
27152755
Word("!$OMP ASSUMES ");
@@ -3004,6 +3044,7 @@ class UnparseVisitor {
30043044
OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type
30053045
WALK_NESTED_ENUM(OmpReductionModifier, Value) // OMP reduction-modifier
30063046
WALK_NESTED_ENUM(OmpExpectation, Value) // OMP motion-expectation
3047+
WALK_NESTED_ENUM(OmpInteropType, Value) // OMP InteropType
30073048
WALK_NESTED_ENUM(OmpOrderClause, Ordering) // OMP ordering
30083049
WALK_NESTED_ENUM(OmpOrderModifier, Value) // OMP order-modifier
30093050
WALK_NESTED_ENUM(OmpPrescriptiveness, Value) // OMP prescriptiveness

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5730,6 +5730,88 @@ void OmpStructureChecker::Leave(const parser::DoConstruct &x) {
57305730
Base::Leave(x);
57315731
}
57325732

5733+
void OmpStructureChecker::Enter(const parser::OpenMPInteropConstruct &x) {
5734+
bool isDependClauseOccured{false};
5735+
int targetCount{0}, targetSyncCount{0};
5736+
const auto &dir{std::get<parser::OmpDirectiveName>(x.v.t)};
5737+
std::set<const Symbol *> objectSymbolList;
5738+
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_interop);
5739+
const auto &clauseList{std::get<std::optional<parser::OmpClauseList>>(x.v.t)};
5740+
for (const auto &clause : clauseList->v) {
5741+
common::visit(
5742+
common::visitors{
5743+
[&](const parser::OmpClause::Init &initClause) {
5744+
if (OmpVerifyModifiers(initClause.v, llvm::omp::OMPC_init,
5745+
GetContext().directiveSource, context_)) {
5746+
5747+
auto &modifiers{OmpGetModifiers(initClause.v)};
5748+
auto &&interopTypeModifier{
5749+
OmpGetRepeatableModifier<parser::OmpInteropType>(
5750+
modifiers)};
5751+
for (const auto &it : interopTypeModifier) {
5752+
if (it->v == parser::OmpInteropType::Value::TargetSync) {
5753+
++targetSyncCount;
5754+
} else {
5755+
++targetCount;
5756+
}
5757+
}
5758+
}
5759+
const auto &interopVar{parser::Unwrap<parser::OmpObject>(
5760+
std::get<parser::OmpObject>(initClause.v.t))};
5761+
const auto *name{parser::Unwrap<parser::Name>(interopVar)};
5762+
const auto *objectSymbol{name->symbol};
5763+
if (llvm::is_contained(objectSymbolList, objectSymbol)) {
5764+
context_.Say(GetContext().directiveSource,
5765+
"Each interop-var may be specified for at most one action-clause of each INTEROP construct."_err_en_US);
5766+
} else {
5767+
objectSymbolList.insert(objectSymbol);
5768+
}
5769+
},
5770+
[&](const parser::OmpClause::Depend &dependClause) {
5771+
isDependClauseOccured = true;
5772+
},
5773+
[&](const parser::OmpClause::Destroy &destroyClause) {
5774+
const auto &interopVar{
5775+
parser::Unwrap<parser::OmpObject>(destroyClause.v)};
5776+
const auto *name{parser::Unwrap<parser::Name>(interopVar)};
5777+
const auto *objectSymbol{name->symbol};
5778+
if (llvm::is_contained(objectSymbolList, objectSymbol)) {
5779+
context_.Say(GetContext().directiveSource,
5780+
"Each interop-var may be specified for at most one action-clause of each INTEROP construct."_err_en_US);
5781+
} else {
5782+
objectSymbolList.insert(objectSymbol);
5783+
}
5784+
},
5785+
[&](const parser::OmpClause::Use &useClause) {
5786+
const auto &interopVar{
5787+
parser::Unwrap<parser::OmpObject>(useClause.v)};
5788+
const auto *name{parser::Unwrap<parser::Name>(interopVar)};
5789+
const auto *objectSymbol{name->symbol};
5790+
if (llvm::is_contained(objectSymbolList, objectSymbol)) {
5791+
context_.Say(GetContext().directiveSource,
5792+
"Each interop-var may be specified for at most one action-clause of each INTEROP construct."_err_en_US);
5793+
} else {
5794+
objectSymbolList.insert(objectSymbol);
5795+
}
5796+
},
5797+
[&](const auto &) {},
5798+
},
5799+
clause.u);
5800+
}
5801+
if (targetCount > 1 || targetSyncCount > 1) {
5802+
context_.Say(GetContext().directiveSource,
5803+
"Each interop-type may be specified at most once."_err_en_US);
5804+
}
5805+
if (isDependClauseOccured && !targetSyncCount) {
5806+
context_.Say(GetContext().directiveSource,
5807+
"A DEPEND clause can only appear on the directive if the interop-type includes TARGETSYNC"_err_en_US);
5808+
}
5809+
}
5810+
5811+
void OmpStructureChecker::Leave(const parser::OpenMPInteropConstruct &) {
5812+
dirContext_.pop_back();
5813+
}
5814+
57335815
void OmpStructureChecker::CheckAllowedRequiresClause(llvmOmpClause clause) {
57345816
CheckAllowedClause(clause);
57355817

0 commit comments

Comments
 (0)