[clang] 7dcff59 - [OpenACC] Implement 'private' clause sema for loop constructs

via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 5 11:39:05 PDT 2024


Author: erichkeane
Date: 2024-06-05T11:39:00-07:00
New Revision: 7dcff5912a7d2b449d43759f5d87a993fa0b65ff

URL: https://github.com/llvm/llvm-project/commit/7dcff5912a7d2b449d43759f5d87a993fa0b65ff
DIFF: https://github.com/llvm/llvm-project/commit/7dcff5912a7d2b449d43759f5d87a993fa0b65ff.diff

LOG: [OpenACC] Implement 'private' clause sema for loop constructs

This clause works identically as far as Sema is concerned, to the
'private' clause on compute constructs, so this simply adds tests and
unblocks the ASTNode generation and Sema checking when used on loop
clauses.

Added: 
    clang/test/SemaOpenACC/loop-construct-private-clause.c
    clang/test/SemaOpenACC/loop-construct-private-clause.cpp

Modified: 
    clang/lib/Sema/SemaOpenACC.cpp
    clang/test/AST/ast-print-openacc-loop-construct.cpp
    clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index cdb60d4d36397..1320fd90b440b 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -675,10 +675,12 @@ SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
         Clause.getEndLoc());
   }
   case OpenACCClauseKind::Private: {
-    // Restrictions only properly implemented on 'compute' constructs, and
-    // 'compute' constructs are the only construct that can do anything with
-    // this yet, so skip/treat as unimplemented in this case.
-    if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
+    // Restrictions only properly implemented on 'compute' and 'loop'
+    // constructs, and 'compute'/'loop' constructs are the only construct that
+    // can do anything with this yet, so skip/treat as unimplemented in this
+    // case.
+    if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
+        Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
       break;
 
     // ActOnVar ensured that everything is a valid variable reference, so there

diff  --git a/clang/test/AST/ast-print-openacc-loop-construct.cpp b/clang/test/AST/ast-print-openacc-loop-construct.cpp
index 519825b89e328..cde302a66f3af 100644
--- a/clang/test/AST/ast-print-openacc-loop-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-loop-construct.cpp
@@ -48,4 +48,13 @@ void foo() {
 // CHECK-NEXT: ;
 #pragma acc loop auto
   for(;;);
+
+  int i;
+  float array[5];
+
+// CHECK: #pragma acc loop private(i, array[1], array, array[1:2])
+// CHECK-NEXT: for (;;)
+// CHECK-NEXT: ;
+#pragma acc loop private(i, array[1], array, array[1:2])
+  for(;;);
 }

diff  --git a/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c
index 23f852ec68700..ac61976ff620d 100644
--- a/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c
+++ b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c
@@ -106,7 +106,6 @@ void uses() {
   // expected-error at +1{{OpenACC 'present' clause is not valid on 'loop' directive}}
 #pragma acc loop auto present(Var)
   for(;;);
-  // expected-warning at +1{{OpenACC clause 'private' not yet implemented}}
 #pragma acc loop auto private(Var)
   for(;;);
   // expected-error at +1{{OpenACC 'copyout' clause is not valid on 'loop' directive}}
@@ -246,7 +245,6 @@ void uses() {
   // expected-error at +1{{OpenACC 'present' clause is not valid on 'loop' directive}}
 #pragma acc loop present(Var) auto
   for(;;);
-  // expected-warning at +1{{OpenACC clause 'private' not yet implemented}}
 #pragma acc loop private(Var) auto
   for(;;);
   // expected-error at +1{{OpenACC 'copyout' clause is not valid on 'loop' directive}}
@@ -387,7 +385,6 @@ void uses() {
   // expected-error at +1{{OpenACC 'present' clause is not valid on 'loop' directive}}
 #pragma acc loop independent present(Var)
   for(;;);
-  // expected-warning at +1{{OpenACC clause 'private' not yet implemented}}
 #pragma acc loop independent private(Var)
   for(;;);
   // expected-error at +1{{OpenACC 'copyout' clause is not valid on 'loop' directive}}
@@ -527,7 +524,6 @@ void uses() {
   // expected-error at +1{{OpenACC 'present' clause is not valid on 'loop' directive}}
 #pragma acc loop present(Var) independent
   for(;;);
-  // expected-warning at +1{{OpenACC clause 'private' not yet implemented}}
 #pragma acc loop private(Var) independent
   for(;;);
   // expected-error at +1{{OpenACC 'copyout' clause is not valid on 'loop' directive}}
@@ -677,7 +673,6 @@ void uses() {
   // expected-error at +1{{OpenACC 'present' clause is not valid on 'loop' directive}}
 #pragma acc loop seq present(Var)
   for(;;);
-  // expected-warning at +1{{OpenACC clause 'private' not yet implemented}}
 #pragma acc loop seq private(Var)
   for(;;);
   // expected-error at +1{{OpenACC 'copyout' clause is not valid on 'loop' directive}}
@@ -826,7 +821,6 @@ void uses() {
   // expected-error at +1{{OpenACC 'present' clause is not valid on 'loop' directive}}
 #pragma acc loop present(Var) seq
   for(;;);
-  // expected-warning at +1{{OpenACC clause 'private' not yet implemented}}
 #pragma acc loop private(Var) seq
   for(;;);
   // expected-error at +1{{OpenACC 'copyout' clause is not valid on 'loop' directive}}

diff  --git a/clang/test/SemaOpenACC/loop-construct-private-clause.c b/clang/test/SemaOpenACC/loop-construct-private-clause.c
new file mode 100644
index 0000000000000..f3ffdfbe3984c
--- /dev/null
+++ b/clang/test/SemaOpenACC/loop-construct-private-clause.c
@@ -0,0 +1,132 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+struct Incomplete;
+enum SomeE{ A };
+typedef struct IsComplete {
+  struct S { int A; } CompositeMember;
+  int ScalarMember;
+  float ArrayMember[5];
+  enum SomeE EnumMember;
+  void *PointerMember;
+} Complete;
+
+int GlobalInt;
+float GlobalArray[5];
+short *GlobalPointer;
+Complete GlobalComposite;
+
+void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) {
+  int LocalInt;
+  short *LocalPointer;
+  float LocalArray[5];
+  Complete LocalComposite;
+
+  // Check Appertainment:
+#pragma acc loop private(LocalInt)
+  for(;;);
+
+  // Valid cases:
+#pragma acc loop private(LocalInt, LocalPointer, LocalArray)
+  for(;;);
+#pragma acc loop private(LocalArray)
+  for(;;);
+#pragma acc loop private(LocalArray[:])
+  for(;;);
+#pragma acc loop private(LocalArray[:5])
+  for(;;);
+#pragma acc loop private(LocalArray[2:])
+  for(;;);
+#pragma acc loop private(LocalArray[2:1])
+  for(;;);
+#pragma acc loop private(LocalArray[2])
+  for(;;);
+#pragma acc loop private(LocalComposite)
+  for(;;);
+#pragma acc loop private(LocalComposite.EnumMember)
+  for(;;);
+#pragma acc loop private(LocalComposite.ScalarMember)
+  for(;;);
+#pragma acc loop private(LocalComposite.ArrayMember)
+  for(;;);
+#pragma acc loop private(LocalComposite.ArrayMember[5])
+  for(;;);
+#pragma acc loop private(LocalComposite.PointerMember)
+  for(;;);
+#pragma acc loop private(GlobalInt, GlobalArray, GlobalPointer, GlobalComposite)
+  for(;;);
+#pragma acc loop private(GlobalArray[2], GlobalPointer[2], GlobalComposite.CompositeMember.A)
+  for(;;);
+#pragma acc loop private(LocalComposite, GlobalComposite)
+  for(;;);
+#pragma acc loop private(IntParam, PointerParam, ArrayParam, CompositeParam)
+  for(;;);
+#pragma acc loop private(PointerParam[IntParam], ArrayParam[IntParam], CompositeParam.CompositeMember.A)
+  for(;;);
+
+#pragma acc loop private(LocalArray) private(LocalArray[2])
+  for(;;);
+
+#pragma acc loop private(LocalArray, LocalArray[2])
+  for(;;);
+
+#pragma acc loop private(LocalComposite, LocalComposite.ScalarMember)
+  for(;;);
+
+#pragma acc loop private(LocalComposite.CompositeMember.A, LocalComposite.ScalarMember)
+  for(;;);
+
+#pragma acc loop private(LocalComposite.CompositeMember.A) private(LocalComposite.ScalarMember)
+  for(;;);
+
+  Complete LocalComposite2;
+#pragma acc loop private(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
+  for(;;);
+
+  // Invalid cases, arbitrary expressions.
+  struct Incomplete *I;
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc loop private(*I)
+  for(;;);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc loop private(GlobalInt + IntParam)
+  for(;;);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc loop private(+GlobalInt)
+  for(;;);
+
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc loop private(PointerParam[:])
+  for(;;);
+#pragma acc loop private(PointerParam[:5])
+  for(;;);
+#pragma acc loop private(PointerParam[:IntParam])
+  for(;;);
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc loop private(PointerParam[2:])
+  for(;;);
+#pragma acc loop private(PointerParam[2:5])
+  for(;;);
+#pragma acc loop private(PointerParam[2])
+  for(;;);
+#pragma acc loop private(ArrayParam[:])
+  for(;;);
+#pragma acc loop private(ArrayParam[:5])
+  for(;;);
+#pragma acc loop private(ArrayParam[:IntParam])
+  for(;;);
+#pragma acc loop private(ArrayParam[2:])
+  for(;;);
+  // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc loop private(ArrayParam[2:5])
+  for(;;);
+#pragma acc loop private(ArrayParam[2])
+  for(;;);
+
+  // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc loop private((float*)ArrayParam[2:5])
+  for(;;);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc loop private((float)ArrayParam[2])
+  for(;;);
+}

diff  --git a/clang/test/SemaOpenACC/loop-construct-private-clause.cpp b/clang/test/SemaOpenACC/loop-construct-private-clause.cpp
new file mode 100644
index 0000000000000..b5d3fc9e7f222
--- /dev/null
+++ b/clang/test/SemaOpenACC/loop-construct-private-clause.cpp
@@ -0,0 +1,155 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+struct Incomplete;
+enum SomeE{};
+typedef struct IsComplete {
+  struct S { int A; } CompositeMember;
+  int ScalarMember;
+  float ArrayMember[5];
+  SomeE EnumMember;
+  char *PointerMember;
+} Complete;
+
+int GlobalInt;
+float GlobalArray[5];
+char *GlobalPointer;
+Complete GlobalComposite;
+
+void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) {
+  int LocalInt;
+  char *LocalPointer;
+  float LocalArray[5];
+  Complete LocalComposite;
+
+  // Check Appertainment:
+
+#pragma acc loop private(LocalInt)
+  for(;;);
+
+  // Valid cases:
+#pragma acc loop private(LocalInt, LocalPointer, LocalArray)
+  for(;;);
+#pragma acc loop private(LocalArray)
+  for(;;);
+#pragma acc loop private(LocalArray[2])
+  for(;;);
+#pragma acc loop private(LocalComposite)
+  for(;;);
+#pragma acc loop private(LocalComposite.EnumMember)
+  for(;;);
+#pragma acc loop private(LocalComposite.ScalarMember)
+  for(;;);
+#pragma acc loop private(LocalComposite.ArrayMember)
+  for(;;);
+#pragma acc loop private(LocalComposite.ArrayMember[5])
+  for(;;);
+#pragma acc loop private(LocalComposite.PointerMember)
+  for(;;);
+#pragma acc loop private(GlobalInt, GlobalArray, GlobalPointer, GlobalComposite)
+  for(;;);
+#pragma acc loop private(GlobalArray[2], GlobalPointer[2], GlobalComposite.CompositeMember.A)
+  for(;;);
+#pragma acc loop private(LocalComposite, GlobalComposite)
+  for(;;);
+#pragma acc loop private(IntParam, PointerParam, ArrayParam, CompositeParam) private(IntParamRef)
+  for(;;);
+#pragma acc loop private(PointerParam[IntParam], ArrayParam[IntParam], CompositeParam.CompositeMember.A)
+  for(;;);
+
+
+  // Invalid cases, arbitrary expressions.
+  Incomplete *I;
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc loop private(*I)
+  for(;;);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc loop private(GlobalInt + IntParam)
+  for(;;);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc loop private(+GlobalInt)
+  for(;;);
+}
+
+template<typename T, unsigned I, typename V>
+void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc loop private(+t)
+  for(;;);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc loop private(+I)
+  for(;;);
+
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#TEMPL_USES_INST{{in instantiation of}}
+#pragma acc loop private(I)
+  for(;;);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc loop private(t, I)
+  for(;;);
+
+#pragma acc loop private(arrayT)
+  for(;;);
+
+#pragma acc loop private(TemplComp)
+  for(;;);
+
+#pragma acc loop private(TemplComp.PointerMember[5])
+  for(;;);
+
+#pragma acc loop private(TemplComp.PointerMember[5]) private(TemplComp)
+  for(;;);
+
+ int *Pointer;
+#pragma acc loop private(Pointer[:I])
+  for(;;);
+#pragma acc loop private(Pointer[:t])
+  for(;;);
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc loop private(Pointer[1:])
+  for(;;);
+}
+
+template<unsigned I, auto &NTTP_REF>
+void NTTP() {
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#NTTP_INST{{in instantiation of}}
+#pragma acc loop private(I)
+  for(;;);
+
+#pragma acc loop private(NTTP_REF)
+  for(;;);
+}
+
+struct S {
+  int ThisMember;
+  int ThisMemberArray[5];
+
+  void foo();
+};
+
+void S::foo() {
+#pragma acc loop private(ThisMember, this->ThisMemberArray[1])
+  for(;;);
+
+#pragma acc loop private(ThisMemberArray[1:2])
+  for(;;);
+
+#pragma acc loop private(this)
+  for(;;);
+
+#pragma acc loop private(ThisMember, this->ThisMember)
+  for(;;);
+}
+
+void Inst() {
+  static constexpr int NTTP_REFed = 1;
+  int i;
+  int Arr[5];
+  Complete C;
+  TemplUses(i, Arr, C); // #TEMPL_USES_INST
+  NTTP<5, NTTP_REFed>(); // #NTTP_INST
+}


        


More information about the cfe-commits mailing list