Skip to content

Commit 3bfcbfc

Browse files
authored
[flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_VARIANT (#160371)
1 parent 9aa5d5a commit 3bfcbfc

File tree

9 files changed

+114
-74
lines changed

9 files changed

+114
-74
lines changed

flang/include/flang/Parser/openmp-utils.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ struct ConstructId {
3838
static constexpr llvm::omp::Directive id{Id}; \
3939
}
4040

41-
MAKE_CONSTR_ID(OmpDeclareVariantDirective, D::OMPD_declare_variant);
4241
MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
4342
MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
4443
MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
@@ -92,8 +91,7 @@ struct DirectiveNameScope {
9291
} else if constexpr (TupleTrait<T>) {
9392
if constexpr (std::is_base_of_v<OmpBlockConstruct, T>) {
9493
return std::get<OmpBeginDirective>(x.t).DirName();
95-
} else if constexpr (std::is_same_v<T, OmpDeclareVariantDirective> ||
96-
std::is_same_v<T, OpenMPDeclarativeAllocate> ||
94+
} else if constexpr (std::is_same_v<T, OpenMPDeclarativeAllocate> ||
9795
std::is_same_v<T, OpenMPDeclarativeAssumes> ||
9896
std::is_same_v<T, OpenMPDeclareReductionConstruct> ||
9997
std::is_same_v<T, OpenMPDeclareSimdConstruct> ||

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4933,10 +4933,14 @@ struct OpenMPSectionsConstruct {
49334933
t;
49344934
};
49354935

4936+
// Ref: [4.5:58-60], [5.0:58-60], [5.1:63-68], [5.2:197-198], [6.0:334-336]
4937+
//
4938+
// declare-variant-directive ->
4939+
// DECLARE_VARIANT([base-name:]variant-name) // since 4.5
49364940
struct OmpDeclareVariantDirective {
4937-
TUPLE_CLASS_BOILERPLATE(OmpDeclareVariantDirective);
4941+
WRAPPER_CLASS_BOILERPLATE(
4942+
OmpDeclareVariantDirective, OmpDirectiveSpecification);
49384943
CharBlock source;
4939-
std::tuple<Verbatim, std::optional<Name>, Name, OmpClauseList> t;
49404944
};
49414945

49424946
// 2.10.6 declare-target -> DECLARE TARGET (extended-list) |

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,8 +1763,9 @@ TYPE_PARSER(construct<OmpInitializerClause>(
17631763

17641764
// OpenMP 5.2: 7.5.4 Declare Variant directive
17651765
TYPE_PARSER(sourced(construct<OmpDeclareVariantDirective>(
1766-
verbatim("DECLARE VARIANT"_tok) || verbatim("DECLARE_VARIANT"_tok),
1767-
"(" >> maybe(name / ":"), name / ")", Parser<OmpClauseList>{})))
1766+
predicated(Parser<OmpDirectiveName>{},
1767+
IsDirective(llvm::omp::Directive::OMPD_declare_variant)) >=
1768+
Parser<OmpDirectiveSpecification>{})))
17681769

17691770
// 2.16 Declare Reduction Construct
17701771
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(

flang/lib/Parser/unparse.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2539,12 +2539,8 @@ class UnparseVisitor {
25392539
}
25402540
void Unparse(const OmpDeclareVariantDirective &x) {
25412541
BeginOpenMP();
2542-
Word("!$OMP DECLARE VARIANT ");
2543-
Put("(");
2544-
Walk(std::get<std::optional<Name>>(x.t), ":");
2545-
Walk(std::get<Name>(x.t));
2546-
Put(")");
2547-
Walk(std::get<OmpClauseList>(x.t));
2542+
Word("!$OMP ");
2543+
Walk(x.v);
25482544
Put("\n");
25492545
EndOpenMP();
25502546
}

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

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -634,11 +634,6 @@ template <typename Checker> struct DirectiveSpellingVisitor {
634634
std::get<parser::Verbatim>(x.t).source, Directive::OMPD_declare_target);
635635
return false;
636636
}
637-
bool Pre(const parser::OmpDeclareVariantDirective &x) {
638-
checker_(std::get<parser::Verbatim>(x.t).source,
639-
Directive::OMPD_declare_variant);
640-
return false;
641-
}
642637
bool Pre(const parser::OpenMPGroupprivate &x) {
643638
checker_(x.v.DirName().source, Directive::OMPD_groupprivate);
644639
return false;
@@ -1370,9 +1365,50 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
13701365
}
13711366

13721367
void OmpStructureChecker::Enter(const parser::OmpDeclareVariantDirective &x) {
1373-
const auto &dir{std::get<parser::Verbatim>(x.t)};
1374-
PushContextAndClauseSets(
1375-
dir.source, llvm::omp::Directive::OMPD_declare_variant);
1368+
const parser::OmpDirectiveName &dirName{x.v.DirName()};
1369+
PushContextAndClauseSets(dirName.source, dirName.v);
1370+
1371+
const parser::OmpArgumentList &args{x.v.Arguments()};
1372+
if (args.v.size() != 1) {
1373+
context_.Say(args.source,
1374+
"DECLARE_VARIANT directive should have a single argument"_err_en_US);
1375+
return;
1376+
}
1377+
1378+
auto InvalidArgument{[&](parser::CharBlock source) {
1379+
context_.Say(source,
1380+
"The argument to the DECLARE_VARIANT directive should be [base-name:]variant-name"_err_en_US);
1381+
}};
1382+
1383+
auto CheckSymbol{[&](const Symbol *sym, parser::CharBlock source) {
1384+
if (sym) {
1385+
if (!IsProcedure(*sym) && !IsFunction(*sym)) {
1386+
auto &msg{context_.Say(source,
1387+
"The name '%s' should refer to a procedure"_err_en_US,
1388+
sym->name())};
1389+
if (sym->test(Symbol::Flag::Implicit)) {
1390+
msg.Attach(source, "The name '%s' has been implicitly declared"_en_US,
1391+
sym->name());
1392+
}
1393+
}
1394+
} else {
1395+
InvalidArgument(source);
1396+
}
1397+
}};
1398+
1399+
const parser::OmpArgument &arg{args.v.front()};
1400+
common::visit( //
1401+
common::visitors{
1402+
[&](const parser::OmpBaseVariantNames &y) {
1403+
CheckSymbol(GetObjectSymbol(std::get<0>(y.t)), arg.source);
1404+
CheckSymbol(GetObjectSymbol(std::get<1>(y.t)), arg.source);
1405+
},
1406+
[&](const parser::OmpLocator &y) {
1407+
CheckSymbol(GetArgumentSymbol(arg), arg.source);
1408+
},
1409+
[&](auto &&y) { InvalidArgument(arg.source); },
1410+
},
1411+
arg.u);
13761412
}
13771413

13781414
void OmpStructureChecker::Leave(const parser::OmpDeclareVariantDirective &) {

flang/lib/Semantics/resolve-names.cpp

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,20 +1540,6 @@ class OmpVisitor : public virtual DeclarationVisitor {
15401540

15411541
bool Pre(const parser::OmpDeclareVariantDirective &x) {
15421542
AddOmpSourceRange(x.source);
1543-
auto FindSymbolOrError = [&](const parser::Name &procName) {
1544-
auto *symbol{FindSymbol(NonDerivedTypeScope(), procName)};
1545-
if (!symbol) {
1546-
context().Say(procName.source,
1547-
"Implicit subroutine declaration '%s' in !$OMP DECLARE VARIANT"_err_en_US,
1548-
procName.source);
1549-
}
1550-
};
1551-
auto &baseProcName = std::get<std::optional<parser::Name>>(x.t);
1552-
if (baseProcName) {
1553-
FindSymbolOrError(*baseProcName);
1554-
}
1555-
auto &varProcName = std::get<parser::Name>(x.t);
1556-
FindSymbolOrError(varProcName);
15571543
return true;
15581544
}
15591545

@@ -1687,16 +1673,19 @@ class OmpVisitor : public virtual DeclarationVisitor {
16871673
PopScope();
16881674
}
16891675
}
1676+
1677+
// These objects are handled explicitly, and the AST traversal should not
1678+
// reach a point where it calls the Pre functions for them.
16901679
bool Pre(const parser::OmpMapperSpecifier &x) {
1691-
// OmpMapperSpecifier is handled explicitly, and the AST traversal
1692-
// should not reach a point where it calls this function.
16931680
llvm_unreachable("This function should not be reached by AST traversal");
16941681
}
16951682
bool Pre(const parser::OmpReductionSpecifier &x) {
1696-
// OmpReductionSpecifier is handled explicitly, and the AST traversal
1697-
// should not reach a point where it calls this function.
16981683
llvm_unreachable("This function should not be reached by AST traversal");
16991684
}
1685+
bool Pre(const parser::OmpBaseVariantNames &x) {
1686+
llvm_unreachable("This function should not be reached by AST traversal");
1687+
}
1688+
17001689
bool Pre(const parser::OmpDirectiveSpecification &x);
17011690
void Post(const parser::OmpDirectiveSpecification &) {
17021691
messageHandler().set_currStmtSource(std::nullopt);

flang/test/Parser/OpenMP/declare-variant.f90

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@
22
! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
33

44
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'
5+
!CHECK: !$OMP DECLARE VARIANT(sub:vsub) MATCH(CONSTRUCT={PARALLEL})
6+
7+
!PARSE-TREE: OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective -> OmpDirectiveSpecification
8+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare variant
9+
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpBaseVariantNames
10+
!PARSE-TREE: | | OmpObject -> Designator -> DataRef -> Name = 'sub'
11+
!PARSE-TREE: | | OmpObject -> Designator -> DataRef -> Name = 'vsub'
1012
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector
1113
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct
1214
!PARSE-TREE: | | OmpTraitSelector
1315
!PARSE-TREE: | | | OmpTraitSelectorName -> llvm::omp::Directive = parallel
16+
!PARSE-TREE: | Flags = None
17+
1418
!$omp declare variant (sub:vsub) match (construct={parallel})
1519
contains
1620
subroutine vsub
@@ -30,14 +34,17 @@ subroutine vsub (v1)
3034
integer, value :: v1
3135
end
3236
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+
!CHECK: !$OMP DECLARE VARIANT(vsub) MATCH(CONSTRUCT={DISPATCH})
38+
39+
!PARSE-TREE: OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective -> OmpDirectiveSpecification
40+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare variant
41+
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'vsub'
3742
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector
3843
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct
3944
!PARSE-TREE: | | OmpTraitSelector
4045
!PARSE-TREE: | | | OmpTraitSelectorName -> llvm::omp::Directive = dispatch
46+
!PARSE-TREE: | Flags = None
47+
4148
!$omp declare variant(vsub), match(construct={dispatch})
4249
integer, value :: v1
4350
end
@@ -56,17 +63,20 @@ subroutine vsub (v1, a1, a2)
5663
integer(omp_interop_kind), value :: a2
5764
end
5865
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'
66+
!CHECK: !$OMP DECLARE VARIANT(vsub) MATCH(CONSTRUCT={DISPATCH}) APPEND_ARGS(INTEROP(TA&
67+
!CHECK: !$OMP&RGET),INTEROP(TARGET))
68+
69+
!PARSE-TREE: OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective -> OmpDirectiveSpecification
70+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare variant
71+
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'vsub'
6472
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector
6573
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct
6674
!PARSE-TREE: | | OmpTraitSelector
6775
!PARSE-TREE: | | | OmpTraitSelectorName -> llvm::omp::Directive = dispatch
6876
!PARSE-TREE: | OmpClause -> AppendArgs -> OmpAppendArgsClause -> OmpAppendOp -> OmpInteropType -> Value = Target
6977
!PARSE-TREE: | OmpAppendOp -> OmpInteropType -> Value = Target
78+
!PARSE-TREE: | Flags = None
79+
7080
!$omp declare variant(vsub), match(construct={dispatch}), append_args (interop(target), interop(target))
7181
integer, value :: v1
7282
end
@@ -81,11 +91,12 @@ subroutine sb3 (x1, x2)
8191
contains
8292
subroutine sub (v1, v2)
8393
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'
94+
!CHECK: !$OMP DECLARE VARIANT(vsub) MATCH(CONSTRUCT={DISPATCH}) ADJUST_ARGS(NOTHING:v1&
95+
!CHECK: !$OMP&) ADJUST_ARGS(NEED_DEVICE_PTR:v2)
96+
97+
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective -> OmpDirectiveSpecification
98+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare variant
99+
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'vsub'
89100
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector
90101
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct
91102
!PARSE-TREE: | | OmpTraitSelector
@@ -96,6 +107,8 @@ subroutine sub (v1, v2)
96107
!PARSE-TREE: | OmpClause -> AdjustArgs -> OmpAdjustArgsClause
97108
!PARSE-TREE: | | OmpAdjustOp -> Value = Need_Device_Ptr
98109
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'v2'
110+
!PARSE-TREE: | Flags = None
111+
99112
!$omp declare variant(vsub) match ( construct = { dispatch } ) adjust_args(nothing : v1 ) adjust_args(need_device_ptr : v2)
100113
end
101114
subroutine vsub(v1, v2)
@@ -119,13 +132,15 @@ subroutine f2 (x, y)
119132
!$omp declare variant (f1) match (construct={simd(uniform(y))})
120133
end
121134
end subroutine
122-
!CHECK: !$OMP DECLARE VARIANT (f1) MATCH(CONSTRUCT={SIMD(UNIFORM(y))})
123-
!PARSE-TREE: | | | | DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective
124-
!PARSE-TREE-NEXT: | | | | | Verbatim
125-
!PARSE-TREE-NEXT: | | | | | Name = 'f1'
126-
!PARSE-TREE-NEXT: | | | | | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector
127-
!PARSE-TREE-NEXT: | | | | | | OmpTraitSetSelectorName -> Value = Construct
128-
!PARSE-TREE-NEXT: | | | | | | OmpTraitSelector
129-
!PARSE-TREE-NEXT: | | | | | | | OmpTraitSelectorName -> Value = Simd
130-
!PARSE-TREE-NEXT: | | | | | | | Properties
131-
!PARSE-TREE-NEXT: | | | | | | | | OmpTraitProperty -> OmpClause -> Uniform -> Name = 'y'
135+
!CHECK: !$OMP DECLARE VARIANT(f1) MATCH(CONSTRUCT={SIMD(UNIFORM(y))})
136+
137+
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective -> OmpDirectiveSpecification
138+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare variant
139+
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'f1'
140+
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector
141+
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct
142+
!PARSE-TREE: | | OmpTraitSelector
143+
!PARSE-TREE: | | | OmpTraitSelectorName -> Value = Simd
144+
!PARSE-TREE: | | | Properties
145+
!PARSE-TREE: | | | | OmpTraitProperty -> OmpClause -> Uniform -> Name = 'y'
146+
!PARSE-TREE: | Flags = None

flang/test/Parser/OpenMP/openmp6-directive-spellings.f90

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,12 @@ subroutine g05
145145
!UNPARSE: SUBROUTINE g05
146146
!UNPARSE: END SUBROUTINE
147147
!UNPARSE: END INTERFACE
148-
!UNPARSE: !$OMP DECLARE VARIANT (g05) MATCH(USER={CONDITION(.true._4)})
148+
!UNPARSE: !$OMP DECLARE_VARIANT(g05) MATCH(USER={CONDITION(.true._4)})
149149
!UNPARSE: END SUBROUTINE
150150

151-
!PARSE-TREE: OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective
152-
!PARSE-TREE: | Verbatim
153-
!PARSE-TREE: | Name = 'g05'
151+
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective -> OmpDirectiveSpecification
152+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare variant
153+
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'g05'
154154
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector
155155
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = User
156156
!PARSE-TREE: | | OmpTraitSelector
@@ -159,6 +159,7 @@ subroutine g05
159159
!PARSE-TREE: | | | | OmpTraitProperty -> Scalar -> Expr = '.true._4'
160160
!PARSE-TREE: | | | | | LiteralConstant -> LogicalLiteralConstant
161161
!PARSE-TREE: | | | | | | bool = 'true'
162+
!PARSE-TREE: | Flags = None
162163

163164
subroutine f06
164165
implicit none

flang/test/Semantics/OpenMP/declare-variant.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=51
22

33
subroutine sub0
4-
!ERROR: Implicit subroutine declaration 'vsub1' in !$OMP DECLARE VARIANT
4+
!ERROR: The name 'vsub1' should refer to a procedure
55
!$omp declare variant (sub:vsub1) match (construct={parallel})
6-
!ERROR: Implicit subroutine declaration 'sub1' in !$OMP DECLARE VARIANT
6+
!ERROR: The name 'sub1' should refer to a procedure
77
!$omp declare variant (sub1:vsub) match (construct={parallel})
88
contains
99
subroutine vsub

0 commit comments

Comments
 (0)