[llvm] d9ff670 - [flang][OpenMP] Parser support for Target directive and Device clause

Nimish Mishra via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 21 09:55:39 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 llvm-commits mailing list