[flang-commits] [flang] d9ff670 - [flang][OpenMP] Parser support for Target directive and Device clause
Nimish Mishra via flang-commits
flang-commits at lists.llvm.org
Sun Aug 21 09:55:38 PDT 2022
Author: Sesha Kalyur
Date: 2022-08-21T22:26:02+05:30
New Revision: d9ff670330a80f2d597822bfd574842ad8fc55b3
URL: https://github.com/llvm/llvm-project/commit/d9ff670330a80f2d597822bfd574842ad8fc55b3
DIFF: https://github.com/llvm/llvm-project/commit/d9ff670330a80f2d597822bfd574842ad8fc55b3.diff
LOG: [flang][OpenMP] Parser support for Target directive and Device clause
This patch adds support for the device clause on `Target` directive.
Device clause was added in OpenMP specification version 4.5 to
create a device data environment for the extent of a region. On
target construct, the device expression be either be `ancestor`
(taking after the parent) or assign a new `device_num`.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D126441
Added:
flang/test/Parser/omp_target_device_parse.f90
flang/test/Parser/omp_target_device_unparse.f90
Modified:
flang/include/flang/Parser/dump-parse-tree.h
flang/include/flang/Parser/parse-tree.h
flang/lib/Parser/openmp-parsers.cpp
flang/lib/Parser/unparse.cpp
flang/lib/Semantics/check-omp-structure.cpp
flang/test/Semantics/OpenMP/omp-device-constructs.f90
llvm/include/llvm/Frontend/OpenMP/OMP.td
Removed:
################################################################################
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index e0f8a0d63240..2d9cfaf91f93 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -525,6 +525,8 @@ class ParseTreeDumper {
NODE(OmpAllocateClause, Allocator)
NODE(parser, OmpScheduleClause)
NODE_ENUM(OmpScheduleClause, ScheduleType)
+ NODE(parser, OmpDeviceClause)
+ NODE_ENUM(OmpDeviceClause, DeviceModifier)
NODE(parser, OmpScheduleModifier)
NODE(OmpScheduleModifier, Modifier1)
NODE(OmpScheduleModifier, Modifier2)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 17cee660cbc0..b37ad6179395 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3385,6 +3385,13 @@ struct OmpScheduleClause {
t;
};
+// device([ device-modifier :] scalar-integer-expression)
+struct OmpDeviceClause {
+ TUPLE_CLASS_BOILERPLATE(OmpDeviceClause);
+ ENUM_CLASS(DeviceModifier, Ancestor, Device_Num)
+ std::tuple<std::optional<DeviceModifier>, ScalarIntExpr> t;
+};
+
// 2.12 if-clause -> IF ([ directive-name-modifier :] scalar-logical-expr)
struct OmpIfClause {
TUPLE_CLASS_BOILERPLATE(OmpIfClause);
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index e3d6d5f90bd5..9f2e15223608 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -97,6 +97,14 @@ TYPE_PARSER(construct<OmpScheduleClause>(maybe(Parser<OmpScheduleModifier>{}),
"RUNTIME" >> pure(OmpScheduleClause::ScheduleType::Runtime),
maybe("," >> scalarIntExpr)))
+// device([ device-modifier :] scalar-integer-expression)
+TYPE_PARSER(construct<OmpDeviceClause>(
+ maybe(
+ ("ANCESTOR" >> pure(OmpDeviceClause::DeviceModifier::Ancestor) ||
+ "DEVICE_NUM" >> pure(OmpDeviceClause::DeviceModifier::Device_Num)) /
+ ":"),
+ scalarIntExpr))
+
// 2.12 IF (directive-name-modifier: scalar-logical-expr)
TYPE_PARSER(construct<OmpIfClause>(
maybe(
@@ -196,7 +204,7 @@ TYPE_PARSER(
"DEPEND" >> construct<OmpClause>(construct<OmpClause::Depend>(
parenthesized(Parser<OmpDependClause>{}))) ||
"DEVICE" >> construct<OmpClause>(construct<OmpClause::Device>(
- parenthesized(scalarIntExpr))) ||
+ parenthesized(Parser<OmpDeviceClause>{}))) ||
"DIST_SCHEDULE" >>
construct<OmpClause>(construct<OmpClause::DistSchedule>(
parenthesized("STATIC" >> maybe("," >> scalarIntExpr)))) ||
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index f5381dd39b9a..534738d19b1d 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2008,6 +2008,10 @@ class UnparseVisitor {
Walk(std::get<OmpScheduleClause::ScheduleType>(x.t));
Walk(",", std::get<std::optional<ScalarIntExpr>>(x.t));
}
+ void Unparse(const OmpDeviceClause &x) {
+ Walk(std::get<std::optional<OmpDeviceClause::DeviceModifier>>(x.t), ":");
+ Walk(std::get<ScalarIntExpr>(x.t));
+ }
void Unparse(const OmpAlignedClause &x) {
Walk(std::get<std::list<Name>>(x.t), ",");
Walk(std::get<std::optional<ScalarIntConstantExpr>>(x.t));
@@ -2580,6 +2584,7 @@ class UnparseVisitor {
WALK_NESTED_ENUM(OmpDependenceType, Type) // OMP dependence-type
WALK_NESTED_ENUM(OmpMapType, Type) // OMP map-type
WALK_NESTED_ENUM(OmpScheduleClause, ScheduleType) // OMP schedule-type
+ WALK_NESTED_ENUM(OmpDeviceClause, DeviceModifier) // OMP device modifier
WALK_NESTED_ENUM(OmpIfClause, DirectiveNameModifier) // OMP directive-modifier
WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type
#undef WALK_NESTED_ENUM
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index dd18b9f62491..fee4f14895d6 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1874,7 +1874,6 @@ CHECK_REQ_SCALAR_INT_CLAUSE(NumTeams, OMPC_num_teams)
CHECK_REQ_SCALAR_INT_CLAUSE(NumThreads, OMPC_num_threads)
CHECK_REQ_SCALAR_INT_CLAUSE(Priority, OMPC_priority)
CHECK_REQ_SCALAR_INT_CLAUSE(ThreadLimit, OMPC_thread_limit)
-CHECK_REQ_SCALAR_INT_CLAUSE(Device, OMPC_device)
CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Collapse, OMPC_collapse)
CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Safelen, OMPC_safelen)
@@ -2373,6 +2372,14 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) {
}
}
+void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) {
+ CheckAllowed(llvm::omp::Clause::OMPC_device);
+ const parser::OmpDeviceClause &deviceClause = x.v;
+ const auto &device{std::get<1>(deviceClause.t)};
+ RequiresPositiveParameter(
+ llvm::omp::Clause::OMPC_device, device, "device expression");
+}
+
void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
CheckAllowed(llvm::omp::Clause::OMPC_depend);
if (const auto *inOut{std::get_if<parser::OmpDependClause::InOut>(&x.v.u)}) {
diff --git a/flang/test/Parser/omp_target_device_parse.f90 b/flang/test/Parser/omp_target_device_parse.f90
new file mode 100644
index 000000000000..1867c2f2a86c
--- /dev/null
+++ b/flang/test/Parser/omp_target_device_parse.f90
@@ -0,0 +1,179 @@
+! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck --ignore-case %s
+! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
+! Checks the parsing of Openmp 5.0 Target Device constructs
+!
+PROGRAM main
+ USE OMP_LIB
+ IMPLICIT NONE
+ INTEGER :: X, Y
+ INTEGER :: M = 1
+
+
+!------------------------------------------------------
+! Check Device clause with a constant argument
+!------------------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(1)
+!$OMP TARGET DEVICE(1)
+ M = M + 1
+!CHECK: !$OMP END TARGET
+!$OMP END TARGET
+
+!PARSE-TREE: OmpBeginBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
+!PARSE-TREE: Scalar -> Integer -> Expr = '1_4'
+!PARSE-TREE: LiteralConstant -> IntLiteralConstant = '1'
+!PARSE-TREE: OmpEndBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList ->
+
+!------------------------------------------------------
+! Check Device clause with a constant integer expression argument
+!------------------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(2-1)
+!$OMP TARGET DEVICE(2-1)
+ M = M + 1
+!CHECK: !$OMP END TARGET
+!$OMP END TARGET
+
+!PARSE-TREE: OmpBeginBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
+!PARSE-TREE: Scalar -> Integer -> Expr = '1_4'
+!PARSE-TREE: Subtract
+!PARSE-TREE: Expr = '2_4'
+!PARSE-TREE: LiteralConstant -> IntLiteralConstant = '2'
+!PARSE-TREE: Expr = '1_4'
+!PARSE-TREE: LiteralConstant -> IntLiteralConstant = '1'
+!PARSE-TREE: OmpEndBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList ->
+
+
+!------------------------------------------------------
+! Check Device clause with a variable argument
+!------------------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(X)
+!$OMP TARGET DEVICE(X)
+ M = M + 1
+!CHECK: !$OMP END TARGET
+!$OMP END TARGET
+
+!PARSE-TREE: OmpBeginBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
+!PARSE-TREE: Scalar -> Integer -> Expr = 'x'
+!PARSE-TREE: Designator -> DataRef -> Name = 'x'
+!PARSE-TREE: OmpEndBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList ->
+
+
+!------------------------------------------------------
+! Check Device clause with an variable integer expression
+!------------------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(X+Y)
+!$OMP TARGET DEVICE(X+Y)
+ M = M + 1
+!CHECK: !$OMP END TARGET
+!$OMP END TARGET
+
+!PARSE-TREE: OmpBeginBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
+!PARSE-TREE: Scalar -> Integer -> Expr = 'x+y'
+!PARSE-TREE: Add
+!PARSE-TREE: Expr = 'x'
+!PARSE-TREE: Designator -> DataRef -> Name = 'x'
+!PARSE-TREE: Expr = 'y'
+!PARSE-TREE: Designator -> DataRef -> Name = 'y'
+!PARSE-TREE: OmpEndBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList ->
+
+!------------------------------------------------------
+! Check Device Ancestor clause with a constant argument
+!------------------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(ANCESTOR:1)
+!$OMP TARGET DEVICE(ANCESTOR: 1)
+ M = M + 1
+!CHECK: !$OMP END TARGET
+!$OMP END TARGET
+
+!PARSE-TREE: OmpBeginBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
+!PARSE-TREE: DeviceModifier = Ancestor
+!PARSE-TREE: Scalar -> Integer -> Expr = '1_4'
+!PARSE-TREE: LiteralConstant -> IntLiteralConstant = '1'
+!PARSE-TREE: OmpEndBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList ->
+
+
+!--------------------------------------------------------
+! Check Device Devive-Num clause with a constant argument
+!--------------------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM:2)
+!$OMP TARGET DEVICE(DEVICE_NUM: 2)
+ M = M + 1
+!CHECK: !$OMP END TARGET
+!$OMP END TARGET
+
+!PARSE-TREE: OmpBeginBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
+!PARSE-TREE: DeviceModifier = Device_Num
+!PARSE-TREE: Scalar -> Integer -> Expr = '2_4'
+!PARSE-TREE: LiteralConstant -> IntLiteralConstant = '2'
+!PARSE-TREE: OmpEndBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList ->
+
+
+!-------------------------------------------------------------------
+! Check Device Ancestor clause with a variable expression argument
+!-------------------------------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(ANCESTOR:X+Y)
+!$OMP TARGET DEVICE(ANCESTOR: X + Y)
+ M = M + 1
+!CHECK: !$OMP END TARGET
+!$OMP END TARGET
+
+!PARSE-TREE: OmpBeginBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
+!PARSE-TREE: DeviceModifier = Ancestor
+!PARSE-TREE: Scalar -> Integer -> Expr = 'x+y'
+!PARSE-TREE: Add
+!PARSE-TREE: Expr = 'x'
+!PARSE-TREE: Designator -> DataRef -> Name = 'x'
+!PARSE-TREE: Expr = 'y'
+!PARSE-TREE: Designator -> DataRef -> Name = 'y'
+!PARSE-TREE: OmpEndBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList ->
+
+
+!-------------------------------------------------------------------
+! Check Device Devive-Num clause with a variable expression argument
+!-------------------------------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM:X-Y)
+!$OMP TARGET DEVICE(DEVICE_NUM: X - Y)
+ M = M + 1
+!CHECK: !$OMP END TARGET
+!$OMP END TARGET
+
+!PARSE-TREE: OmpBeginBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+!PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
+!PARSE-TREE: DeviceModifier = Device_Num
+!PARSE-TREE: Scalar -> Integer -> Expr = 'x-y'
+!PARSE-TREE: Subtract
+!PARSE-TREE: Expr = 'x'
+!PARSE-TREE: Designator -> DataRef -> Name = 'x'
+!PARSE-TREE: Expr = 'y'
+!PARSE-TREE: Designator -> DataRef -> Name = 'y'
+!PARSE-TREE: OmpEndBlockDirective
+!PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target
+END PROGRAM
diff --git a/flang/test/Parser/omp_target_device_unparse.f90 b/flang/test/Parser/omp_target_device_unparse.f90
new file mode 100644
index 000000000000..605c2baf1b06
--- /dev/null
+++ b/flang/test/Parser/omp_target_device_unparse.f90
@@ -0,0 +1,80 @@
+! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck --ignore-case %s
+! Verifies the unparsing of the Openmp Target Device constructs
+PROGRAM main
+ USE OMP_LIB
+ IMPLICIT NONE
+ INTEGER:: X, Y
+ INTEGER:: M = 1
+
+!--------------------------------------------
+! constant argument
+!--------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(0)
+!CHECK: !$OMP END TARGET
+!$OMP TARGET DEVICE(0)
+ M = M + 1
+!$OMP END TARGET
+
+!--------------------------------------------
+! constant expression argument
+!--------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(2+1)
+!CHECK: !$OMP END TARGET
+!$OMP TARGET DEVICE(2+1)
+ M = M + 1
+!$OMP END TARGET
+
+!--------------------------------------------
+! variable argument
+!--------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(X)
+!CHECK: !$OMP END TARGET
+!$OMP TARGET DEVICE(X)
+ M = M + 1
+!$OMP END TARGET
+
+!--------------------------------------------
+! variable expression argument
+!--------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(X-Y)
+!CHECK: !$OMP END TARGET
+!$OMP TARGET DEVICE(X-Y)
+ M = M + 1
+!$OMP END TARGET
+
+!--------------------------------------------
+! Ancestor followed by constant argument
+!--------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(ANCESTOR:0)
+!CHECK: !$OMP END TARGET
+!$OMP TARGET DEVICE(ANCESTOR: 0)
+ M = M + 1
+!$OMP END TARGET
+
+!--------------------------------------------
+! Device_Num followed by constant argument
+!--------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM:1)
+!CHECK: !$OMP END TARGET
+!$OMP TARGET DEVICE(DEVICE_NUM: 1)
+ M = M + 1
+!$OMP END TARGET
+
+!--------------------------------------------
+! Ancestor followed by variable expression argument
+!--------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(ANCESTOR:X+Y)
+!CHECK: !$OMP END TARGET
+!$OMP TARGET DEVICE(ANCESTOR: X + Y)
+ M = M + 1
+!$OMP END TARGET
+
+!--------------------------------------------
+! Device_Num followed by variable expression argument
+!--------------------------------------------
+!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM:X-Y)
+!CHECK: !$OMP END TARGET
+!$OMP TARGET DEVICE(DEVICE_NUM: X - Y)
+ M = M + 1
+!$OMP END TARGET
+END PROGRAM
diff --git a/flang/test/Semantics/OpenMP/omp-device-constructs.f90 b/flang/test/Semantics/OpenMP/omp-device-constructs.f90
index 80f7902d35bb..1b242657673a 100644
--- a/flang/test/Semantics/OpenMP/omp-device-constructs.f90
+++ b/flang/test/Semantics/OpenMP/omp-device-constructs.f90
@@ -129,10 +129,10 @@ program main
enddo
!$omp end target data
- !ERROR: The parameter of the DEVICE clause must be a positive integer expression
+ !ERROR: The device expression of the DEVICE clause must be a positive integer expression
!$omp target enter data map(alloc:A) device(-2)
- !ERROR: The parameter of the DEVICE clause must be a positive integer expression
+ !ERROR: The device expression of the DEVICE clause must be a positive integer expression
!$omp target exit data map(delete:A) device(-2)
!ERROR: At most one IF clause can appear on the TARGET ENTER DATA directive
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 5f1d335ef04f..0cf9d9731718 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -210,7 +210,7 @@ def OMPC_Depend : Clause<"depend"> {
}
def OMPC_Device : Clause<"device"> {
let clangClass = "OMPDeviceClause";
- let flangClass = "ScalarIntExpr";
+ let flangClass = "OmpDeviceClause";
}
def OMPC_Threads : Clause<"threads"> { let clangClass = "OMPThreadsClause"; }
def OMPC_Simd : Clause<"simd"> { let clangClass = "OMPSIMDClause"; }
More information about the flang-commits
mailing list