-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Add parser+semantics support for scope construct #113700
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Test parsing, semantics and a couple of basic semantic checks for block/worksharing constructs. Add TODO message in lowering.
@llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-flang-parser Author: Kiran Chandramohan (kiranchandramohan) ChangesTest parsing, semantics and a couple of basic semantic checks for block/worksharing constructs. Full diff: https://github.com/llvm/llvm-project/pull/113700.diff 11 Files Affected:
diff --git a/flang/include/flang/Semantics/openmp-directive-sets.h b/flang/include/flang/Semantics/openmp-directive-sets.h
index 8eb736bb098fe4..50d6d5b59ef7dd 100644
--- a/flang/include/flang/Semantics/openmp-directive-sets.h
+++ b/flang/include/flang/Semantics/openmp-directive-sets.h
@@ -211,6 +211,7 @@ static const OmpDirectiveSet blockConstructSet{
Directive::OMPD_parallel,
Directive::OMPD_parallel_masked,
Directive::OMPD_parallel_workshare,
+ Directive::OMPD_scope,
Directive::OMPD_single,
Directive::OMPD_target,
Directive::OMPD_target_data,
@@ -281,6 +282,7 @@ static const OmpDirectiveSet workShareSet{
Directive::OMPD_workshare,
Directive::OMPD_parallel_workshare,
Directive::OMPD_parallel_sections,
+ Directive::OMPD_scope,
Directive::OMPD_sections,
Directive::OMPD_single,
} | allDoSet,
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index fc54da8babe63e..01a40d6e2204ef 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1650,6 +1650,15 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
return sectionsOp;
}
+static void genScopeOp(lower::AbstractConverter &converter,
+ lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval, mlir::Location loc,
+ const ConstructQueue &queue,
+ ConstructQueue::const_iterator item) {
+ TODO(loc, "Scope construct");
+}
+
static mlir::omp::SingleOp
genSingleOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
@@ -2478,6 +2487,9 @@ static void genOMPDispatch(lower::AbstractConverter &converter,
case llvm::omp::Directive::OMPD_simd:
genStandaloneSimd(converter, symTable, semaCtx, eval, loc, queue, item);
break;
+ case llvm::omp::Directive::OMPD_scope:
+ genScopeOp(converter, symTable, semaCtx, eval, loc, queue, item);
+ break;
case llvm::omp::Directive::OMPD_single:
genSingleOp(converter, symTable, semaCtx, eval, loc, queue, item);
break;
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 59a8757e58e8cc..e740c421ca8027 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -697,6 +697,7 @@ TYPE_PARSER(construct<OmpBlockDirective>(first(
"PARALLEL MASKED" >> pure(llvm::omp::Directive::OMPD_parallel_masked),
"PARALLEL WORKSHARE" >> pure(llvm::omp::Directive::OMPD_parallel_workshare),
"PARALLEL" >> pure(llvm::omp::Directive::OMPD_parallel),
+ "SCOPE" >> pure(llvm::omp::Directive::OMPD_scope),
"SINGLE" >> pure(llvm::omp::Directive::OMPD_single),
"TARGET DATA" >> pure(llvm::omp::Directive::OMPD_target_data),
"TARGET PARALLEL" >> pure(llvm::omp::Directive::OMPD_target_parallel),
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 04df988223e8f8..19ceb2a3ebc317 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2386,6 +2386,9 @@ class UnparseVisitor {
case llvm::omp::Directive::OMPD_parallel:
Word("PARALLEL ");
break;
+ case llvm::omp::Directive::OMPD_scope:
+ Word("SCOPE ");
+ break;
case llvm::omp::Directive::OMPD_single:
Word("SINGLE ");
break;
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 46486907ceb9e1..1c2cf304d0ee95 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -972,6 +972,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
HasInvalidWorksharingNesting(
beginDir.source, llvm::omp::nestedWorkshareErrSet);
break;
+ case llvm::omp::Directive::OMPD_scope:
case llvm::omp::Directive::OMPD_single:
// TODO: This check needs to be extended while implementing nesting of
// regions checks.
@@ -1864,6 +1865,9 @@ void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
const auto &dir{std::get<parser::OmpBlockDirective>(x.t)};
ResetPartialContext(dir.source);
switch (dir.v) {
+ case llvm::omp::Directive::OMPD_scope:
+ PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_end_scope);
+ break;
// 2.7.3 end-single-clause -> copyprivate-clause |
// nowait-clause
case llvm::omp::Directive::OMPD_single:
@@ -1886,7 +1890,8 @@ void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
// end_workshareare popped as they are pushed while entering the
// EndBlockDirective.
void OmpStructureChecker::Leave(const parser::OmpEndBlockDirective &x) {
- if ((GetContext().directive == llvm::omp::Directive::OMPD_end_single) ||
+ if ((GetContext().directive == llvm::omp::Directive::OMPD_end_scope) ||
+ (GetContext().directive == llvm::omp::Directive::OMPD_end_single) ||
(GetContext().directive == llvm::omp::Directive::OMPD_end_workshare)) {
dirContext_.pop_back();
}
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 33936ba4c2b34f..513e42bee976a9 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1526,6 +1526,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
case llvm::omp::Directive::OMPD_master:
case llvm::omp::Directive::OMPD_ordered:
case llvm::omp::Directive::OMPD_parallel:
+ case llvm::omp::Directive::OMPD_scope:
case llvm::omp::Directive::OMPD_single:
case llvm::omp::Directive::OMPD_target:
case llvm::omp::Directive::OMPD_target_data:
@@ -1557,6 +1558,7 @@ void OmpAttributeVisitor::Post(const parser::OpenMPBlockConstruct &x) {
case llvm::omp::Directive::OMPD_masked:
case llvm::omp::Directive::OMPD_parallel_masked:
case llvm::omp::Directive::OMPD_parallel:
+ case llvm::omp::Directive::OMPD_scope:
case llvm::omp::Directive::OMPD_single:
case llvm::omp::Directive::OMPD_target:
case llvm::omp::Directive::OMPD_task:
diff --git a/flang/test/Lower/OpenMP/Todo/scope.f90 b/flang/test/Lower/OpenMP/Todo/scope.f90
new file mode 100644
index 00000000000000..16a067dc8f256b
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/scope.f90
@@ -0,0 +1,13 @@
+! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s -fopenmp-version=51 2>&1 | FileCheck %s
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s -fopenmp-version=51 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: Scope construct
+program omp_scope
+ integer i
+ i = 10
+
+ !$omp scope private(i)
+ print *, "omp scope", i
+ !$omp end scope
+
+end program omp_scope
diff --git a/flang/test/Parser/OpenMP/scope.f90 b/flang/test/Parser/OpenMP/scope.f90
new file mode 100644
index 00000000000000..6574136311e718
--- /dev/null
+++ b/flang/test/Parser/OpenMP/scope.f90
@@ -0,0 +1,24 @@
+! RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=51 %s | FileCheck --ignore-case %s
+! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=51 %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+program omp_scope
+ integer i
+ i = 10
+
+!CHECK: !$OMP SCOPE PRIVATE(i)
+!CHECK: !$OMP END SCOPE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
+!PARSE-TREE: OmpBeginBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = scope
+!PARSE-TREE: OmpClauseList -> OmpClause -> Private -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'i'
+!PARSE-TREE: Block
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> PrintStmt
+!PARSE-TREE: OmpEndBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = scope
+!PARSE-TREE: OmpClauseList -> OmpClause -> Nowait
+
+ !$omp scope private(i)
+ print *, "omp scope", i
+ !$omp end scope nowait
+end program omp_scope
diff --git a/flang/test/Semantics/OpenMP/invalid-branch.f90 b/flang/test/Semantics/OpenMP/invalid-branch.f90
index ed9e4d268f65a8..28aab8b122f3f2 100644
--- a/flang/test/Semantics/OpenMP/invalid-branch.f90
+++ b/flang/test/Semantics/OpenMP/invalid-branch.f90
@@ -105,4 +105,12 @@ program omp_invalid_branch
!$omp end parallel
9 print *, "2nd alternate return"
+ !CHECK: invalid branch into an OpenMP structured block
+ goto 100
+ !$omp scope
+ 100 continue
+ !CHECK: invalid branch leaving an OpenMP structured block
+ goto 200
+ !$omp end scope
+ 200 continue
end program
diff --git a/flang/test/Semantics/OpenMP/nested01.f90 b/flang/test/Semantics/OpenMP/nested01.f90
index 49c964ab86aa6b..0936e4c1b45a5d 100644
--- a/flang/test/Semantics/OpenMP/nested01.f90
+++ b/flang/test/Semantics/OpenMP/nested01.f90
@@ -25,6 +25,13 @@
!$omp end target
enddo
+ !$omp do
+ do i = 1, N
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp scope
+ !$omp end scope
+ end do
+ !$omp end do
!$omp do
do i = 1, N
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 1834ad4d037f3d..d592f369a17f92 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -892,7 +892,7 @@ def OMP_Scan : Directive<"scan"> {
let association = AS_Separating;
let category = CA_Subsidiary;
}
-def OMP_scope : Directive<"scope"> {
+def OMP_Scope : Directive<"scope"> {
let allowedClauses = [
VersionedClause<OMPC_Private, 51>,
VersionedClause<OMPC_Reduction, 51>,
@@ -905,6 +905,14 @@ def OMP_scope : Directive<"scope"> {
let association = AS_Block;
let category = CA_Executable;
}
+def OMP_EndScope : Directive<"end scope"> {
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_NoWait>,
+ ];
+ let leafConstructs = OMP_Scope.leafConstructs;
+ let association = OMP_Scope.association;
+ let category = OMP_Scope.category;
+}
def OMP_Section : Directive<"section"> {
let association = AS_Separating;
let category = CA_Subsidiary;
|
@llvm/pr-subscribers-flang-openmp Author: Kiran Chandramohan (kiranchandramohan) ChangesTest parsing, semantics and a couple of basic semantic checks for block/worksharing constructs. Full diff: https://github.com/llvm/llvm-project/pull/113700.diff 11 Files Affected:
diff --git a/flang/include/flang/Semantics/openmp-directive-sets.h b/flang/include/flang/Semantics/openmp-directive-sets.h
index 8eb736bb098fe4..50d6d5b59ef7dd 100644
--- a/flang/include/flang/Semantics/openmp-directive-sets.h
+++ b/flang/include/flang/Semantics/openmp-directive-sets.h
@@ -211,6 +211,7 @@ static const OmpDirectiveSet blockConstructSet{
Directive::OMPD_parallel,
Directive::OMPD_parallel_masked,
Directive::OMPD_parallel_workshare,
+ Directive::OMPD_scope,
Directive::OMPD_single,
Directive::OMPD_target,
Directive::OMPD_target_data,
@@ -281,6 +282,7 @@ static const OmpDirectiveSet workShareSet{
Directive::OMPD_workshare,
Directive::OMPD_parallel_workshare,
Directive::OMPD_parallel_sections,
+ Directive::OMPD_scope,
Directive::OMPD_sections,
Directive::OMPD_single,
} | allDoSet,
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index fc54da8babe63e..01a40d6e2204ef 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1650,6 +1650,15 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
return sectionsOp;
}
+static void genScopeOp(lower::AbstractConverter &converter,
+ lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval, mlir::Location loc,
+ const ConstructQueue &queue,
+ ConstructQueue::const_iterator item) {
+ TODO(loc, "Scope construct");
+}
+
static mlir::omp::SingleOp
genSingleOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
@@ -2478,6 +2487,9 @@ static void genOMPDispatch(lower::AbstractConverter &converter,
case llvm::omp::Directive::OMPD_simd:
genStandaloneSimd(converter, symTable, semaCtx, eval, loc, queue, item);
break;
+ case llvm::omp::Directive::OMPD_scope:
+ genScopeOp(converter, symTable, semaCtx, eval, loc, queue, item);
+ break;
case llvm::omp::Directive::OMPD_single:
genSingleOp(converter, symTable, semaCtx, eval, loc, queue, item);
break;
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 59a8757e58e8cc..e740c421ca8027 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -697,6 +697,7 @@ TYPE_PARSER(construct<OmpBlockDirective>(first(
"PARALLEL MASKED" >> pure(llvm::omp::Directive::OMPD_parallel_masked),
"PARALLEL WORKSHARE" >> pure(llvm::omp::Directive::OMPD_parallel_workshare),
"PARALLEL" >> pure(llvm::omp::Directive::OMPD_parallel),
+ "SCOPE" >> pure(llvm::omp::Directive::OMPD_scope),
"SINGLE" >> pure(llvm::omp::Directive::OMPD_single),
"TARGET DATA" >> pure(llvm::omp::Directive::OMPD_target_data),
"TARGET PARALLEL" >> pure(llvm::omp::Directive::OMPD_target_parallel),
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 04df988223e8f8..19ceb2a3ebc317 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2386,6 +2386,9 @@ class UnparseVisitor {
case llvm::omp::Directive::OMPD_parallel:
Word("PARALLEL ");
break;
+ case llvm::omp::Directive::OMPD_scope:
+ Word("SCOPE ");
+ break;
case llvm::omp::Directive::OMPD_single:
Word("SINGLE ");
break;
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 46486907ceb9e1..1c2cf304d0ee95 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -972,6 +972,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
HasInvalidWorksharingNesting(
beginDir.source, llvm::omp::nestedWorkshareErrSet);
break;
+ case llvm::omp::Directive::OMPD_scope:
case llvm::omp::Directive::OMPD_single:
// TODO: This check needs to be extended while implementing nesting of
// regions checks.
@@ -1864,6 +1865,9 @@ void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
const auto &dir{std::get<parser::OmpBlockDirective>(x.t)};
ResetPartialContext(dir.source);
switch (dir.v) {
+ case llvm::omp::Directive::OMPD_scope:
+ PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_end_scope);
+ break;
// 2.7.3 end-single-clause -> copyprivate-clause |
// nowait-clause
case llvm::omp::Directive::OMPD_single:
@@ -1886,7 +1890,8 @@ void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
// end_workshareare popped as they are pushed while entering the
// EndBlockDirective.
void OmpStructureChecker::Leave(const parser::OmpEndBlockDirective &x) {
- if ((GetContext().directive == llvm::omp::Directive::OMPD_end_single) ||
+ if ((GetContext().directive == llvm::omp::Directive::OMPD_end_scope) ||
+ (GetContext().directive == llvm::omp::Directive::OMPD_end_single) ||
(GetContext().directive == llvm::omp::Directive::OMPD_end_workshare)) {
dirContext_.pop_back();
}
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 33936ba4c2b34f..513e42bee976a9 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1526,6 +1526,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
case llvm::omp::Directive::OMPD_master:
case llvm::omp::Directive::OMPD_ordered:
case llvm::omp::Directive::OMPD_parallel:
+ case llvm::omp::Directive::OMPD_scope:
case llvm::omp::Directive::OMPD_single:
case llvm::omp::Directive::OMPD_target:
case llvm::omp::Directive::OMPD_target_data:
@@ -1557,6 +1558,7 @@ void OmpAttributeVisitor::Post(const parser::OpenMPBlockConstruct &x) {
case llvm::omp::Directive::OMPD_masked:
case llvm::omp::Directive::OMPD_parallel_masked:
case llvm::omp::Directive::OMPD_parallel:
+ case llvm::omp::Directive::OMPD_scope:
case llvm::omp::Directive::OMPD_single:
case llvm::omp::Directive::OMPD_target:
case llvm::omp::Directive::OMPD_task:
diff --git a/flang/test/Lower/OpenMP/Todo/scope.f90 b/flang/test/Lower/OpenMP/Todo/scope.f90
new file mode 100644
index 00000000000000..16a067dc8f256b
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/scope.f90
@@ -0,0 +1,13 @@
+! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s -fopenmp-version=51 2>&1 | FileCheck %s
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s -fopenmp-version=51 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: Scope construct
+program omp_scope
+ integer i
+ i = 10
+
+ !$omp scope private(i)
+ print *, "omp scope", i
+ !$omp end scope
+
+end program omp_scope
diff --git a/flang/test/Parser/OpenMP/scope.f90 b/flang/test/Parser/OpenMP/scope.f90
new file mode 100644
index 00000000000000..6574136311e718
--- /dev/null
+++ b/flang/test/Parser/OpenMP/scope.f90
@@ -0,0 +1,24 @@
+! RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=51 %s | FileCheck --ignore-case %s
+! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=51 %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+program omp_scope
+ integer i
+ i = 10
+
+!CHECK: !$OMP SCOPE PRIVATE(i)
+!CHECK: !$OMP END SCOPE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
+!PARSE-TREE: OmpBeginBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = scope
+!PARSE-TREE: OmpClauseList -> OmpClause -> Private -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'i'
+!PARSE-TREE: Block
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> PrintStmt
+!PARSE-TREE: OmpEndBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = scope
+!PARSE-TREE: OmpClauseList -> OmpClause -> Nowait
+
+ !$omp scope private(i)
+ print *, "omp scope", i
+ !$omp end scope nowait
+end program omp_scope
diff --git a/flang/test/Semantics/OpenMP/invalid-branch.f90 b/flang/test/Semantics/OpenMP/invalid-branch.f90
index ed9e4d268f65a8..28aab8b122f3f2 100644
--- a/flang/test/Semantics/OpenMP/invalid-branch.f90
+++ b/flang/test/Semantics/OpenMP/invalid-branch.f90
@@ -105,4 +105,12 @@ program omp_invalid_branch
!$omp end parallel
9 print *, "2nd alternate return"
+ !CHECK: invalid branch into an OpenMP structured block
+ goto 100
+ !$omp scope
+ 100 continue
+ !CHECK: invalid branch leaving an OpenMP structured block
+ goto 200
+ !$omp end scope
+ 200 continue
end program
diff --git a/flang/test/Semantics/OpenMP/nested01.f90 b/flang/test/Semantics/OpenMP/nested01.f90
index 49c964ab86aa6b..0936e4c1b45a5d 100644
--- a/flang/test/Semantics/OpenMP/nested01.f90
+++ b/flang/test/Semantics/OpenMP/nested01.f90
@@ -25,6 +25,13 @@
!$omp end target
enddo
+ !$omp do
+ do i = 1, N
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp scope
+ !$omp end scope
+ end do
+ !$omp end do
!$omp do
do i = 1, N
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 1834ad4d037f3d..d592f369a17f92 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -892,7 +892,7 @@ def OMP_Scan : Directive<"scan"> {
let association = AS_Separating;
let category = CA_Subsidiary;
}
-def OMP_scope : Directive<"scope"> {
+def OMP_Scope : Directive<"scope"> {
let allowedClauses = [
VersionedClause<OMPC_Private, 51>,
VersionedClause<OMPC_Reduction, 51>,
@@ -905,6 +905,14 @@ def OMP_scope : Directive<"scope"> {
let association = AS_Block;
let category = CA_Executable;
}
+def OMP_EndScope : Directive<"end scope"> {
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_NoWait>,
+ ];
+ let leafConstructs = OMP_Scope.leafConstructs;
+ let association = OMP_Scope.association;
+ let category = OMP_Scope.category;
+}
def OMP_Section : Directive<"section"> {
let association = AS_Separating;
let category = CA_Subsidiary;
|
@llvm/pr-subscribers-flang-semantics Author: Kiran Chandramohan (kiranchandramohan) ChangesTest parsing, semantics and a couple of basic semantic checks for block/worksharing constructs. Full diff: https://github.com/llvm/llvm-project/pull/113700.diff 11 Files Affected:
diff --git a/flang/include/flang/Semantics/openmp-directive-sets.h b/flang/include/flang/Semantics/openmp-directive-sets.h
index 8eb736bb098fe4..50d6d5b59ef7dd 100644
--- a/flang/include/flang/Semantics/openmp-directive-sets.h
+++ b/flang/include/flang/Semantics/openmp-directive-sets.h
@@ -211,6 +211,7 @@ static const OmpDirectiveSet blockConstructSet{
Directive::OMPD_parallel,
Directive::OMPD_parallel_masked,
Directive::OMPD_parallel_workshare,
+ Directive::OMPD_scope,
Directive::OMPD_single,
Directive::OMPD_target,
Directive::OMPD_target_data,
@@ -281,6 +282,7 @@ static const OmpDirectiveSet workShareSet{
Directive::OMPD_workshare,
Directive::OMPD_parallel_workshare,
Directive::OMPD_parallel_sections,
+ Directive::OMPD_scope,
Directive::OMPD_sections,
Directive::OMPD_single,
} | allDoSet,
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index fc54da8babe63e..01a40d6e2204ef 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1650,6 +1650,15 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
return sectionsOp;
}
+static void genScopeOp(lower::AbstractConverter &converter,
+ lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval, mlir::Location loc,
+ const ConstructQueue &queue,
+ ConstructQueue::const_iterator item) {
+ TODO(loc, "Scope construct");
+}
+
static mlir::omp::SingleOp
genSingleOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
@@ -2478,6 +2487,9 @@ static void genOMPDispatch(lower::AbstractConverter &converter,
case llvm::omp::Directive::OMPD_simd:
genStandaloneSimd(converter, symTable, semaCtx, eval, loc, queue, item);
break;
+ case llvm::omp::Directive::OMPD_scope:
+ genScopeOp(converter, symTable, semaCtx, eval, loc, queue, item);
+ break;
case llvm::omp::Directive::OMPD_single:
genSingleOp(converter, symTable, semaCtx, eval, loc, queue, item);
break;
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 59a8757e58e8cc..e740c421ca8027 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -697,6 +697,7 @@ TYPE_PARSER(construct<OmpBlockDirective>(first(
"PARALLEL MASKED" >> pure(llvm::omp::Directive::OMPD_parallel_masked),
"PARALLEL WORKSHARE" >> pure(llvm::omp::Directive::OMPD_parallel_workshare),
"PARALLEL" >> pure(llvm::omp::Directive::OMPD_parallel),
+ "SCOPE" >> pure(llvm::omp::Directive::OMPD_scope),
"SINGLE" >> pure(llvm::omp::Directive::OMPD_single),
"TARGET DATA" >> pure(llvm::omp::Directive::OMPD_target_data),
"TARGET PARALLEL" >> pure(llvm::omp::Directive::OMPD_target_parallel),
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 04df988223e8f8..19ceb2a3ebc317 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2386,6 +2386,9 @@ class UnparseVisitor {
case llvm::omp::Directive::OMPD_parallel:
Word("PARALLEL ");
break;
+ case llvm::omp::Directive::OMPD_scope:
+ Word("SCOPE ");
+ break;
case llvm::omp::Directive::OMPD_single:
Word("SINGLE ");
break;
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 46486907ceb9e1..1c2cf304d0ee95 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -972,6 +972,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
HasInvalidWorksharingNesting(
beginDir.source, llvm::omp::nestedWorkshareErrSet);
break;
+ case llvm::omp::Directive::OMPD_scope:
case llvm::omp::Directive::OMPD_single:
// TODO: This check needs to be extended while implementing nesting of
// regions checks.
@@ -1864,6 +1865,9 @@ void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
const auto &dir{std::get<parser::OmpBlockDirective>(x.t)};
ResetPartialContext(dir.source);
switch (dir.v) {
+ case llvm::omp::Directive::OMPD_scope:
+ PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_end_scope);
+ break;
// 2.7.3 end-single-clause -> copyprivate-clause |
// nowait-clause
case llvm::omp::Directive::OMPD_single:
@@ -1886,7 +1890,8 @@ void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
// end_workshareare popped as they are pushed while entering the
// EndBlockDirective.
void OmpStructureChecker::Leave(const parser::OmpEndBlockDirective &x) {
- if ((GetContext().directive == llvm::omp::Directive::OMPD_end_single) ||
+ if ((GetContext().directive == llvm::omp::Directive::OMPD_end_scope) ||
+ (GetContext().directive == llvm::omp::Directive::OMPD_end_single) ||
(GetContext().directive == llvm::omp::Directive::OMPD_end_workshare)) {
dirContext_.pop_back();
}
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 33936ba4c2b34f..513e42bee976a9 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1526,6 +1526,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
case llvm::omp::Directive::OMPD_master:
case llvm::omp::Directive::OMPD_ordered:
case llvm::omp::Directive::OMPD_parallel:
+ case llvm::omp::Directive::OMPD_scope:
case llvm::omp::Directive::OMPD_single:
case llvm::omp::Directive::OMPD_target:
case llvm::omp::Directive::OMPD_target_data:
@@ -1557,6 +1558,7 @@ void OmpAttributeVisitor::Post(const parser::OpenMPBlockConstruct &x) {
case llvm::omp::Directive::OMPD_masked:
case llvm::omp::Directive::OMPD_parallel_masked:
case llvm::omp::Directive::OMPD_parallel:
+ case llvm::omp::Directive::OMPD_scope:
case llvm::omp::Directive::OMPD_single:
case llvm::omp::Directive::OMPD_target:
case llvm::omp::Directive::OMPD_task:
diff --git a/flang/test/Lower/OpenMP/Todo/scope.f90 b/flang/test/Lower/OpenMP/Todo/scope.f90
new file mode 100644
index 00000000000000..16a067dc8f256b
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/scope.f90
@@ -0,0 +1,13 @@
+! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s -fopenmp-version=51 2>&1 | FileCheck %s
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s -fopenmp-version=51 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: Scope construct
+program omp_scope
+ integer i
+ i = 10
+
+ !$omp scope private(i)
+ print *, "omp scope", i
+ !$omp end scope
+
+end program omp_scope
diff --git a/flang/test/Parser/OpenMP/scope.f90 b/flang/test/Parser/OpenMP/scope.f90
new file mode 100644
index 00000000000000..6574136311e718
--- /dev/null
+++ b/flang/test/Parser/OpenMP/scope.f90
@@ -0,0 +1,24 @@
+! RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=51 %s | FileCheck --ignore-case %s
+! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=51 %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+program omp_scope
+ integer i
+ i = 10
+
+!CHECK: !$OMP SCOPE PRIVATE(i)
+!CHECK: !$OMP END SCOPE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
+!PARSE-TREE: OmpBeginBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = scope
+!PARSE-TREE: OmpClauseList -> OmpClause -> Private -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'i'
+!PARSE-TREE: Block
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> PrintStmt
+!PARSE-TREE: OmpEndBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = scope
+!PARSE-TREE: OmpClauseList -> OmpClause -> Nowait
+
+ !$omp scope private(i)
+ print *, "omp scope", i
+ !$omp end scope nowait
+end program omp_scope
diff --git a/flang/test/Semantics/OpenMP/invalid-branch.f90 b/flang/test/Semantics/OpenMP/invalid-branch.f90
index ed9e4d268f65a8..28aab8b122f3f2 100644
--- a/flang/test/Semantics/OpenMP/invalid-branch.f90
+++ b/flang/test/Semantics/OpenMP/invalid-branch.f90
@@ -105,4 +105,12 @@ program omp_invalid_branch
!$omp end parallel
9 print *, "2nd alternate return"
+ !CHECK: invalid branch into an OpenMP structured block
+ goto 100
+ !$omp scope
+ 100 continue
+ !CHECK: invalid branch leaving an OpenMP structured block
+ goto 200
+ !$omp end scope
+ 200 continue
end program
diff --git a/flang/test/Semantics/OpenMP/nested01.f90 b/flang/test/Semantics/OpenMP/nested01.f90
index 49c964ab86aa6b..0936e4c1b45a5d 100644
--- a/flang/test/Semantics/OpenMP/nested01.f90
+++ b/flang/test/Semantics/OpenMP/nested01.f90
@@ -25,6 +25,13 @@
!$omp end target
enddo
+ !$omp do
+ do i = 1, N
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp scope
+ !$omp end scope
+ end do
+ !$omp end do
!$omp do
do i = 1, N
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 1834ad4d037f3d..d592f369a17f92 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -892,7 +892,7 @@ def OMP_Scan : Directive<"scan"> {
let association = AS_Separating;
let category = CA_Subsidiary;
}
-def OMP_scope : Directive<"scope"> {
+def OMP_Scope : Directive<"scope"> {
let allowedClauses = [
VersionedClause<OMPC_Private, 51>,
VersionedClause<OMPC_Reduction, 51>,
@@ -905,6 +905,14 @@ def OMP_scope : Directive<"scope"> {
let association = AS_Block;
let category = CA_Executable;
}
+def OMP_EndScope : Directive<"end scope"> {
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_NoWait>,
+ ];
+ let leafConstructs = OMP_Scope.leafConstructs;
+ let association = OMP_Scope.association;
+ let category = OMP_Scope.category;
+}
def OMP_Section : Directive<"section"> {
let association = AS_Separating;
let category = CA_Subsidiary;
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Test parsing, semantics and a couple of basic semantic checks for block/worksharing constructs. Add TODO message in lowering.
Test parsing, semantics and a couple of basic semantic checks for block/worksharing constructs.
Add TODO message in lowering.