Skip to content

Commit a13c0b6

Browse files
[Flang][OpenMP] Add frontend support for declare variant (#130578)
Support is added for parsing. Basic semantics support is added to forward the code to Lowering. Lowering will emit a TODO error. Detailed semantics checks and lowering is further work.
1 parent 74c3025 commit a13c0b6

File tree

12 files changed

+257
-6
lines changed

12 files changed

+257
-6
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,11 @@ class ParseTreeDumper {
483483
NODE(parser, OldParameterStmt)
484484
NODE(parser, OmpTypeSpecifier)
485485
NODE(parser, OmpTypeNameList)
486+
NODE(parser, OmpAdjustArgsClause)
487+
NODE(OmpAdjustArgsClause, OmpAdjustOp)
488+
NODE_ENUM(OmpAdjustArgsClause::OmpAdjustOp, Value)
489+
NODE(parser, OmpAppendArgsClause)
490+
NODE(OmpAppendArgsClause, OmpAppendOp)
486491
NODE(parser, OmpLocator)
487492
NODE(parser, OmpLocatorList)
488493
NODE(parser, OmpReductionSpecifier)
@@ -703,6 +708,7 @@ class ParseTreeDumper {
703708
NODE(parser, OpenMPCriticalConstruct)
704709
NODE(parser, OpenMPDeclarativeAllocate)
705710
NODE(parser, OpenMPDeclarativeConstruct)
711+
NODE(parser, OmpDeclareVariantDirective)
706712
NODE(parser, OpenMPDeclareReductionConstruct)
707713
NODE(parser, OpenMPDeclareSimdConstruct)
708714
NODE(parser, OpenMPDeclareTargetConstruct)

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

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4013,6 +4013,15 @@ struct OmpAbsentClause {
40134013
WRAPPER_CLASS_BOILERPLATE(OmpAbsentClause, OmpDirectiveList);
40144014
};
40154015

4016+
struct OmpAdjustArgsClause {
4017+
TUPLE_CLASS_BOILERPLATE(OmpAdjustArgsClause);
4018+
struct OmpAdjustOp {
4019+
ENUM_CLASS(Value, Nothing, Need_Device_Ptr)
4020+
WRAPPER_CLASS_BOILERPLATE(OmpAdjustOp, Value);
4021+
};
4022+
std::tuple<OmpAdjustOp, OmpObjectList> t;
4023+
};
4024+
40164025
// Ref: [5.0:135-140], [5.1:161-166], [5.2:264-265]
40174026
//
40184027
// affinity-clause ->
@@ -4056,6 +4065,13 @@ struct OmpAllocateClause {
40564065
std::tuple<MODIFIERS(), OmpObjectList> t;
40574066
};
40584067

4068+
struct OmpAppendArgsClause {
4069+
struct OmpAppendOp {
4070+
WRAPPER_CLASS_BOILERPLATE(OmpAppendOp, std::list<OmpInteropType>);
4071+
};
4072+
WRAPPER_CLASS_BOILERPLATE(OmpAppendArgsClause, std::list<OmpAppendOp>);
4073+
};
4074+
40594075
// Ref: [5.2:216-217 (sort of, as it's only mentioned in passing)
40604076
// AT(compilation|execution)
40614077
struct OmpAtClause {
@@ -4698,6 +4714,12 @@ struct OmpBlockDirective {
46984714
CharBlock source;
46994715
};
47004716

4717+
struct OmpDeclareVariantDirective {
4718+
TUPLE_CLASS_BOILERPLATE(OmpDeclareVariantDirective);
4719+
CharBlock source;
4720+
std::tuple<Verbatim, std::optional<Name>, Name, OmpClauseList> t;
4721+
};
4722+
47014723
// 2.10.6 declare-target -> DECLARE TARGET (extended-list) |
47024724
// DECLARE TARGET [declare-target-clause[ [,]
47034725
// declare-target-clause]...]
@@ -4776,8 +4798,8 @@ struct OpenMPDeclarativeConstruct {
47764798
std::variant<OpenMPDeclarativeAllocate, OpenMPDeclarativeAssumes,
47774799
OpenMPDeclareMapperConstruct, OpenMPDeclareReductionConstruct,
47784800
OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
4779-
OpenMPThreadprivate, OpenMPRequiresConstruct, OpenMPUtilityConstruct,
4780-
OmpMetadirectiveDirective>
4801+
OmpDeclareVariantDirective, OpenMPThreadprivate, OpenMPRequiresConstruct,
4802+
OpenMPUtilityConstruct, OmpMetadirectiveDirective>
47814803
u;
47824804
};
47834805

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3816,6 +3816,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
38163816
TODO(converter.getCurrentLocation(), "OpenMP ASSUMES declaration");
38173817
}
38183818

3819+
static void
3820+
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3821+
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
3822+
const parser::OmpDeclareVariantDirective &declareVariantDirective) {
3823+
TODO(converter.getCurrentLocation(), "OmpDeclareVariantDirective");
3824+
}
3825+
38193826
static void genOMP(
38203827
lower::AbstractConverter &converter, lower::SymMap &symTable,
38213828
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,14 @@ TYPE_PARSER(sourced(construct<OmpToClause::Modifier>(
611611
TYPE_PARSER(sourced(construct<OmpWhenClause::Modifier>( //
612612
Parser<OmpContextSelector>{})))
613613

614+
TYPE_PARSER(construct<OmpAppendArgsClause::OmpAppendOp>(
615+
"INTEROP" >> parenthesized(nonemptyList(Parser<OmpInteropType>{}))))
616+
617+
TYPE_PARSER(construct<OmpAdjustArgsClause::OmpAdjustOp>(
618+
"NOTHING" >> pure(OmpAdjustArgsClause::OmpAdjustOp::Value::Nothing) ||
619+
"NEED_DEVICE_PTR" >>
620+
pure(OmpAdjustArgsClause::OmpAdjustOp::Value::Need_Device_Ptr)))
621+
614622
// --- Parsers for clauses --------------------------------------------
615623

616624
/// `MOBClause` is a clause that has a
@@ -630,6 +638,10 @@ static inline MOBClause makeMobClause(
630638
}
631639
}
632640

641+
TYPE_PARSER(construct<OmpAdjustArgsClause>(
642+
(Parser<OmpAdjustArgsClause::OmpAdjustOp>{} / ":"),
643+
Parser<OmpObjectList>{}))
644+
633645
// [5.0] 2.10.1 affinity([aff-modifier:] locator-list)
634646
// aff-modifier: interator-modifier
635647
TYPE_PARSER(construct<OmpAffinityClause>(
@@ -653,6 +665,9 @@ TYPE_PARSER(construct<OmpAtomicDefaultMemOrderClause>(
653665
TYPE_PARSER(construct<OmpCancellationConstructTypeClause>(
654666
OmpDirectiveNameParser{}, maybe(parenthesized(scalarLogicalExpr))))
655667

668+
TYPE_PARSER(construct<OmpAppendArgsClause>(
669+
nonemptyList(Parser<OmpAppendArgsClause::OmpAppendOp>{})))
670+
656671
// 2.15.3.1 DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE)
657672
TYPE_PARSER(construct<OmpDefaultClause::DataSharingAttribute>(
658673
"PRIVATE" >> pure(OmpDefaultClause::DataSharingAttribute::Private) ||
@@ -901,6 +916,8 @@ TYPE_PARSER( //
901916
parenthesized(Parser<OmpAbsentClause>{}))) ||
902917
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
903918
"ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
919+
"ADJUST_ARGS" >> construct<OmpClause>(construct<OmpClause::AdjustArgs>(
920+
parenthesized(Parser<OmpAdjustArgsClause>{}))) ||
904921
"AFFINITY" >> construct<OmpClause>(construct<OmpClause::Affinity>(
905922
parenthesized(Parser<OmpAffinityClause>{}))) ||
906923
"ALIGN" >> construct<OmpClause>(construct<OmpClause::Align>(
@@ -909,6 +926,8 @@ TYPE_PARSER( //
909926
parenthesized(Parser<OmpAlignedClause>{}))) ||
910927
"ALLOCATE" >> construct<OmpClause>(construct<OmpClause::Allocate>(
911928
parenthesized(Parser<OmpAllocateClause>{}))) ||
929+
"APPEND_ARGS" >> construct<OmpClause>(construct<OmpClause::AppendArgs>(
930+
parenthesized(Parser<OmpAppendArgsClause>{}))) ||
912931
"ALLOCATOR" >> construct<OmpClause>(construct<OmpClause::Allocator>(
913932
parenthesized(scalarIntExpr))) ||
914933
"AT" >> construct<OmpClause>(construct<OmpClause::At>(
@@ -1348,6 +1367,11 @@ TYPE_PARSER(construct<OmpInitializerClause>(
13481367
construct<OmpInitializerClause>(assignmentStmt) ||
13491368
construct<OmpInitializerClause>(Parser<OmpInitializerProc>{})))
13501369

1370+
// OpenMP 5.2: 7.5.4 Declare Variant directive
1371+
TYPE_PARSER(sourced(
1372+
construct<OmpDeclareVariantDirective>(verbatim("DECLARE VARIANT"_tok),
1373+
"(" >> maybe(name / ":"), name / ")", Parser<OmpClauseList>{})))
1374+
13511375
// 2.16 Declare Reduction Construct
13521376
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(
13531377
verbatim("DECLARE REDUCTION"_tok),
@@ -1519,6 +1543,8 @@ TYPE_PARSER(
15191543
Parser<OpenMPDeclareSimdConstruct>{}) ||
15201544
construct<OpenMPDeclarativeConstruct>(
15211545
Parser<OpenMPDeclareTargetConstruct>{}) ||
1546+
construct<OpenMPDeclarativeConstruct>(
1547+
Parser<OmpDeclareVariantDirective>{}) ||
15221548
construct<OpenMPDeclarativeConstruct>(
15231549
Parser<OpenMPDeclarativeAllocate>{}) ||
15241550
construct<OpenMPDeclarativeConstruct>(

flang/lib/Parser/unparse.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2743,7 +2743,28 @@ class UnparseVisitor {
27432743
Put("\n");
27442744
EndOpenMP();
27452745
}
2746-
2746+
void Unparse(const OmpAppendArgsClause::OmpAppendOp &x) {
2747+
Put("INTEROP(");
2748+
Walk(x.v, ",");
2749+
Put(")");
2750+
}
2751+
void Unparse(const OmpAppendArgsClause &x) { Walk(x.v, ","); }
2752+
void Unparse(const OmpAdjustArgsClause &x) {
2753+
Walk(std::get<OmpAdjustArgsClause::OmpAdjustOp>(x.t).v);
2754+
Put(":");
2755+
Walk(std::get<parser::OmpObjectList>(x.t));
2756+
}
2757+
void Unparse(const OmpDeclareVariantDirective &x) {
2758+
BeginOpenMP();
2759+
Word("!$OMP DECLARE VARIANT ");
2760+
Put("(");
2761+
Walk(std::get<std::optional<Name>>(x.t), ":");
2762+
Walk(std::get<Name>(x.t));
2763+
Put(")");
2764+
Walk(std::get<OmpClauseList>(x.t));
2765+
Put("\n");
2766+
EndOpenMP();
2767+
}
27472768
void Unparse(const OpenMPInteropConstruct &x) {
27482769
BeginOpenMP();
27492770
Word("!$OMP INTEROP");
@@ -3042,6 +3063,7 @@ class UnparseVisitor {
30423063
WALK_NESTED_ENUM(InquireSpec::LogVar, Kind)
30433064
WALK_NESTED_ENUM(ProcedureStmt, Kind) // R1506
30443065
WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410
3066+
WALK_NESTED_ENUM(OmpAdjustArgsClause::OmpAdjustOp, Value) // OMP adjustop
30453067
WALK_NESTED_ENUM(OmpAtClause, ActionTime) // OMP at
30463068
WALK_NESTED_ENUM(OmpBindClause, Binding) // OMP bind
30473069
WALK_NESTED_ENUM(OmpProcBindClause, AffinityPolicy) // OMP proc_bind

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,6 +1619,16 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
16191619
dirContext_.pop_back();
16201620
}
16211621

1622+
void OmpStructureChecker::Enter(const parser::OmpDeclareVariantDirective &x) {
1623+
const auto &dir{std::get<parser::Verbatim>(x.t)};
1624+
PushContextAndClauseSets(
1625+
dir.source, llvm::omp::Directive::OMPD_declare_variant);
1626+
}
1627+
1628+
void OmpStructureChecker::Leave(const parser::OmpDeclareVariantDirective &) {
1629+
dirContext_.pop_back();
1630+
}
1631+
16221632
void OmpStructureChecker::Enter(const parser::OpenMPDepobjConstruct &x) {
16231633
const auto &dirName{std::get<parser::OmpDirectiveName>(x.v.t)};
16241634
PushContextAndClauseSets(dirName.source, llvm::omp::Directive::OMPD_depobj);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ class OmpStructureChecker
9898
void Enter(const parser::OmpEndSectionsDirective &);
9999
void Leave(const parser::OmpEndSectionsDirective &);
100100

101+
void Enter(const parser::OmpDeclareVariantDirective &);
102+
void Leave(const parser::OmpDeclareVariantDirective &);
101103
void Enter(const parser::OpenMPDeclareSimdConstruct &);
102104
void Leave(const parser::OpenMPDeclareSimdConstruct &);
103105
void Enter(const parser::OpenMPDeclarativeAllocate &);

flang/lib/Semantics/resolve-names.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,25 @@ class OmpVisitor : public virtual DeclarationVisitor {
15111511
return true;
15121512
}
15131513

1514+
bool Pre(const parser::OmpDeclareVariantDirective &x) {
1515+
AddOmpSourceRange(x.source);
1516+
auto FindSymbolOrError = [&](const parser::Name &procName) {
1517+
auto *symbol{FindSymbol(NonDerivedTypeScope(), procName)};
1518+
if (!symbol) {
1519+
context().Say(procName.source,
1520+
"Implicit subroutine declaration '%s' in !$OMP DECLARE VARIANT"_err_en_US,
1521+
procName.source);
1522+
}
1523+
};
1524+
auto &baseProcName = std::get<std::optional<parser::Name>>(x.t);
1525+
if (baseProcName) {
1526+
FindSymbolOrError(*baseProcName);
1527+
}
1528+
auto &varProcName = std::get<parser::Name>(x.t);
1529+
FindSymbolOrError(varProcName);
1530+
return true;
1531+
}
1532+
15141533
bool Pre(const parser::OpenMPDeclareReductionConstruct &x) {
15151534
AddOmpSourceRange(x.source);
15161535
ProcessReductionSpecifier(
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
2+
3+
! CHECK: not yet implemented: OmpDeclareVariantDirective
4+
5+
subroutine sb1
6+
integer :: x
7+
x = 1
8+
call sub(x)
9+
contains
10+
subroutine vsub (v1)
11+
integer, value :: v1
12+
end
13+
subroutine sub (v1)
14+
!$omp declare variant(vsub), match(construct={dispatch})
15+
integer, value :: v1
16+
end
17+
end subroutine
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck --ignore-case %s
2+
! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
3+
4+
subroutine sub0
5+
!CHECK: !$OMP DECLARE VARIANT (sub:vsub) MATCH(CONSTRUCT={PARALLEL})
6+
!PARSE-TREE: OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective
7+
!PARSE-TREE: | Verbatim
8+
!PARSE-TREE: | Name = 'sub'
9+
!PARSE-TREE: | Name = 'vsub'
10+
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector
11+
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct
12+
!PARSE-TREE: | | OmpTraitSelector
13+
!PARSE-TREE: | | | OmpTraitSelectorName -> llvm::omp::Directive = parallel
14+
!$omp declare variant (sub:vsub) match (construct={parallel})
15+
contains
16+
subroutine vsub
17+
end subroutine
18+
19+
subroutine sub ()
20+
end subroutine
21+
end subroutine
22+
23+
subroutine sb1
24+
integer :: x
25+
x = 1
26+
!$omp dispatch device(1)
27+
call sub(x)
28+
contains
29+
subroutine vsub (v1)
30+
integer, value :: v1
31+
end
32+
subroutine sub (v1)
33+
!CHECK: !$OMP DECLARE VARIANT (vsub) MATCH(CONSTRUCT={DISPATCH}
34+
!PARSE-TREE: OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective
35+
!PARSE-TREE: | Verbatim
36+
!PARSE-TREE: | Name = 'vsub'
37+
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector
38+
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct
39+
!PARSE-TREE: | | OmpTraitSelector
40+
!PARSE-TREE: | | | OmpTraitSelectorName -> llvm::omp::Directive = dispatch
41+
!$omp declare variant(vsub), match(construct={dispatch})
42+
integer, value :: v1
43+
end
44+
end subroutine
45+
46+
subroutine sb2 (x1, x2)
47+
use omp_lib, only: omp_interop_kind
48+
integer :: x
49+
x = 1
50+
!$omp dispatch device(1)
51+
call sub(x)
52+
contains
53+
subroutine vsub (v1, a1, a2)
54+
integer, value :: v1
55+
integer(omp_interop_kind) :: a1
56+
integer(omp_interop_kind), value :: a2
57+
end
58+
subroutine sub (v1)
59+
!CHECK: !$OMP DECLARE VARIANT (vsub) MATCH(CONSTRUCT={DISPATCH}) APPEND_ARGS(INTEROP(T&
60+
!CHECK: !$OMP&ARGET),INTEROP(TARGET))
61+
!PARSE-TREE: OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective
62+
!PARSE-TREE: | Verbatim
63+
!PARSE-TREE: | Name = 'vsub'
64+
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector
65+
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct
66+
!PARSE-TREE: | | OmpTraitSelector
67+
!PARSE-TREE: | | | OmpTraitSelectorName -> llvm::omp::Directive = dispatch
68+
!PARSE-TREE: | OmpClause -> AppendArgs -> OmpAppendArgsClause -> OmpAppendOp -> OmpInteropType -> Value = Target
69+
!PARSE-TREE: | OmpAppendOp -> OmpInteropType -> Value = Target
70+
!$omp declare variant(vsub), match(construct={dispatch}), append_args (interop(target), interop(target))
71+
integer, value :: v1
72+
end
73+
end subroutine
74+
75+
subroutine sb3 (x1, x2)
76+
use iso_c_binding, only: c_ptr
77+
type(c_ptr), value :: x1, x2
78+
79+
!$omp dispatch device(1)
80+
call sub(x1, x2)
81+
contains
82+
subroutine sub (v1, v2)
83+
type(c_ptr), value :: v1, v2
84+
!CHECK: !$OMP DECLARE VARIANT (vsub) MATCH(CONSTRUCT={DISPATCH}) ADJUST_ARGS(NOTHING:v&
85+
!CHECK: !$OMP&1) ADJUST_ARGS(NEED_DEVICE_PTR:v2)
86+
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective
87+
!PARSE-TREE: | Verbatim
88+
!PARSE-TREE: | Name = 'vsub'
89+
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector
90+
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct
91+
!PARSE-TREE: | | OmpTraitSelector
92+
!PARSE-TREE: | | | OmpTraitSelectorName -> llvm::omp::Directive = dispatch
93+
!PARSE-TREE: | OmpClause -> AdjustArgs -> OmpAdjustArgsClause
94+
!PARSE-TREE: | | OmpAdjustOp -> Value = Nothing
95+
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'v1'
96+
!PARSE-TREE: | OmpClause -> AdjustArgs -> OmpAdjustArgsClause
97+
!PARSE-TREE: | | OmpAdjustOp -> Value = Need_Device_Ptr
98+
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'v2'
99+
!$omp declare variant(vsub) match ( construct = { dispatch } ) adjust_args(nothing : v1 ) adjust_args(need_device_ptr : v2)
100+
end
101+
subroutine vsub(v1, v2)
102+
type(c_ptr), value :: v1, v2
103+
end
104+
end subroutine
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=51
2+
3+
subroutine sub0
4+
!ERROR: Implicit subroutine declaration 'vsub1' in !$OMP DECLARE VARIANT
5+
!$omp declare variant (sub:vsub1) match (construct={parallel})
6+
!ERROR: Implicit subroutine declaration 'sub1' in !$OMP DECLARE VARIANT
7+
!$omp declare variant (sub1:vsub) match (construct={parallel})
8+
contains
9+
subroutine vsub
10+
end subroutine
11+
12+
subroutine sub ()
13+
end subroutine
14+
end subroutine

0 commit comments

Comments
 (0)