Skip to content

Commit 6cfad63

Browse files
committed
[OpenACC] Implement 'if' clause sema for 'data' constructs
This is another one that has no additional sema work other than enabling it, so this patch does just that.
1 parent 3392774 commit 6cfad63

8 files changed

+200
-15
lines changed

clang/include/clang/Basic/OpenACCKinds.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,14 @@ inline bool isOpenACCCombinedDirectiveKind(OpenACCDirectiveKind K) {
158158
K == OpenACCDirectiveKind::KernelsLoop;
159159
}
160160

161+
// Tests 'K' to see if it is 'data', 'host_data', 'enter data', or 'exit data'.
162+
inline bool isOpenACCDataDirectiveKind(OpenACCDirectiveKind K) {
163+
return K == OpenACCDirectiveKind::Data ||
164+
K == OpenACCDirectiveKind::EnterData ||
165+
K == OpenACCDirectiveKind::ExitData ||
166+
K == OpenACCDirectiveKind::HostData;
167+
}
168+
161169
enum class OpenACCAtomicKind : uint8_t {
162170
Read,
163171
Write,

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -641,16 +641,20 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause(
641641

642642
OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
643643
SemaOpenACC::OpenACCParsedClause &Clause) {
644-
// Restrictions only properly implemented on 'compute'/'combined' constructs,
645-
// and 'compute'/'combined' constructs are the only construct that can do
646-
// anything with this yet, so skip/treat as unimplemented in this case.
644+
// Restrictions only properly implemented on 'compute'/'combined'/'data'
645+
// constructs, and 'compute'/'combined'/'data' constructs are the only
646+
// constructs that can do anything with this yet, so skip/treat as
647+
// unimplemented in this case.
647648
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
648-
!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
649+
!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) &&
650+
!isOpenACCDataDirectiveKind(Clause.getDirectiveKind()))
649651
return isNotImplemented();
650652

651653
// There is no prose in the standard that says duplicates aren't allowed,
652654
// but this diagnostic is present in other compilers, as well as makes
653-
// sense.
655+
// sense. Prose DOES exist for 'data' and 'host_data', 'enter data' and 'exit
656+
// data' both don't, but other implmementations do this. OpenACC issue 519
657+
// filed for the latter two.
654658
if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
655659
return nullptr;
656660

clang/test/AST/ast-print-openacc-data-construct.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,20 @@ void foo() {
2727
// CHECK-NOT: use_device(Var)
2828
#pragma acc host_data use_device(Var)
2929
;
30+
31+
int i;
32+
int array[5];
33+
34+
// CHECK: #pragma acc data if(i == array[1])
35+
#pragma acc data default(none) if(i == array[1])
36+
;
37+
// CHECK: #pragma acc enter data if(i == array[1])
38+
#pragma acc enter data copyin(Var) if(i == array[1])
39+
;
40+
// CHECK: #pragma acc exit data if(i == array[1])
41+
#pragma acc exit data copyout(Var) if(i == array[1])
42+
;
43+
// CHECK: #pragma acc host_data if(i == array[1])
44+
#pragma acc host_data use_device(Var) if(i == array[1])
45+
;
3046
}

clang/test/SemaOpenACC/combined-construct-if-clause.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ void BoolExpr(int *I, float *F) {
4343
#pragma acc kernels loop if (*I < *F)
4444
for (unsigned i = 0; i < 5; ++i);
4545

46-
// expected-warning@+1{{OpenACC clause 'if' not yet implemented}}
4746
#pragma acc data if (*I < *F)
4847
for (unsigned i = 0; i < 5; ++i);
4948
#pragma acc parallel loop if (*I < *F)

clang/test/SemaOpenACC/compute-construct-if-clause.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ void BoolExpr(int *I, float *F) {
4343
#pragma acc kernels if (*I < *F)
4444
while(0);
4545

46-
// expected-warning@+1{{OpenACC clause 'if' not yet implemented}}
4746
#pragma acc data if (*I < *F)
4847
while(0);
4948
#pragma acc parallel loop if (*I < *F)
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s
2+
3+
// Test this with PCH.
4+
// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s
5+
// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s
6+
7+
#ifndef PCH_HELPER
8+
#define PCH_HELPER
9+
void NormalFunc(int j, float f) {
10+
// CHECK: FunctionDecl{{.*}}NormalFunc
11+
// CHECK-NEXT: ParmVarDecl
12+
// CHECK-NEXT: ParmVarDecl
13+
// CHECK-NEXT: CompoundStmt
14+
#pragma acc data if( j < f) default(none)
15+
;
16+
// CHECK-NEXT: OpenACCDataConstruct{{.*}}data
17+
// CHECK-NEXT: if clause
18+
// CHECK-NEXT: BinaryOperator{{.*}} 'bool' '<'
19+
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float' <IntegralToFloating>
20+
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
21+
// CHECK-NEXT: DeclRefExpr{{.*}} 'int' lvalue ParmVar{{.*}} 'j' 'int'
22+
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float' <LValueToRValue>
23+
// CHECK-NEXT: DeclRefExpr{{.*}} 'float' lvalue ParmVar{{.*}} 'f' 'float'
24+
// CHECK-NEXT: NullStmt
25+
26+
}
27+
28+
int Global;
29+
30+
template<typename T>
31+
void TemplFunc() {
32+
// CHECK: FunctionTemplateDecl{{.*}}TemplFunc
33+
// CHECK-NEXT: TemplateTypeParmDecl
34+
35+
// Match the prototype:
36+
// CHECK-NEXT: FunctionDecl{{.*}}TemplFunc
37+
// CHECK-NEXT: CompoundStmt
38+
39+
#pragma acc data default(none) if(T::SomeFloat < typename T::IntTy{})
40+
;
41+
// CHECK-NEXT: OpenACCDataConstruct{{.*}}data
42+
// CHECK-NEXT: if clause
43+
// CHECK-NEXT: BinaryOperator{{.*}} '<dependent type>' '<'
44+
// CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '<dependent type>' lvalue
45+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'T'
46+
// CHECK-NEXT: CXXUnresolvedConstructExpr{{.*}} 'typename T::IntTy' 'typename T::IntTy'
47+
// CHECK-NEXT: InitListExpr{{.*}} 'void'
48+
// CHECK-NEXT: NullStmt
49+
50+
#pragma acc enter data copyin(Global) if(typename T::IntTy{})
51+
;
52+
// CHECK-NEXT: OpenACCEnterDataConstruct{{.*}}enter data
53+
// CHECK-NEXT: if clause
54+
// CHECK-NEXT: CXXUnresolvedConstructExpr{{.*}} 'typename T::IntTy' 'typename T::IntTy'
55+
// CHECK-NEXT: InitListExpr{{.*}} 'void'
56+
// CHECK-NEXT: NullStmt
57+
58+
#pragma acc exit data copyout(Global) if(T::SomeFloat)
59+
;
60+
// CHECK-NEXT: OpenACCExitDataConstruct{{.*}}exit data
61+
// CHECK-NEXT: if clause
62+
// CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '<dependent type>' lvalue
63+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'T'
64+
// CHECK-NEXT: NullStmt
65+
66+
#pragma acc host_data use_device(Global) if(T::BC)
67+
;
68+
// CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data
69+
// CHECK-NEXT: if clause
70+
// CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '<dependent type>' lvalue
71+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'T'
72+
// CHECK-NEXT: NullStmt
73+
74+
// Match the instantiation:
75+
// CHECK: FunctionDecl{{.*}}TemplFunc{{.*}}implicit_instantiation
76+
// CHECK-NEXT: TemplateArgument type 'InstTy'
77+
// CHECK-NEXT: RecordType{{.*}} 'InstTy'
78+
// CHECK-NEXT: CXXRecord{{.*}} 'InstTy'
79+
// CHECK-NEXT: CompoundStmt
80+
81+
// CHECK-NEXT: OpenACCDataConstruct{{.*}}data
82+
// CHECK-NEXT: if clause
83+
// CHECK-NEXT: BinaryOperator{{.*}} 'bool' '<'
84+
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float' <LValueToRValue>
85+
// CHECK-NEXT: DeclRefExpr{{.*}} 'const float' lvalue Var{{.*}} 'SomeFloat' 'const float'
86+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy'
87+
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float' <IntegralToFloating>
88+
// CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename struct InstTy::IntTy <NoOp>
89+
// CHECK-NEXT: InitListExpr {{.*}}'typename InstTy::IntTy':'int'
90+
// CHECK-NEXT: NullStmt
91+
92+
// CHECK-NEXT: OpenACCEnterDataConstruct{{.*}}enter data
93+
// CHECK-NEXT: if clause
94+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'bool' <IntegralToBoolean>
95+
// CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename struct InstTy::IntTy <NoOp>
96+
// CHECK-NEXT: InitListExpr {{.*}}'typename InstTy::IntTy':'int'
97+
// CHECK-NEXT: NullStmt
98+
99+
// CHECK-NEXT: OpenACCExitDataConstruct{{.*}}exit data
100+
// CHECK-NEXT: if clause
101+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'bool' <FloatingToBoolean>
102+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'float' <LValueToRValue>
103+
// CHECK-NEXT: DeclRefExpr{{.*}} 'const float' lvalue Var{{.*}} 'SomeFloat' 'const float'
104+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy'
105+
// CHECK-NEXT: NullStmt
106+
107+
// CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data
108+
// CHECK-NEXT: if clause
109+
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'bool' <UserDefinedConversion>
110+
// CHECK-NEXT: CXXMemberCallExpr{{.*}} 'bool'
111+
// CHECK-NEXT: MemberExpr{{.*}} .operator bool
112+
// CHECK-NEXT: DeclRefExpr{{.*}} 'const BoolConversion' lvalue Var{{.*}} 'BC' 'const BoolConversion'
113+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy'
114+
// CHECK-NEXT: NullStmt
115+
116+
}
117+
118+
struct BoolConversion{ operator bool() const;};
119+
struct InstTy {
120+
using IntTy = int;
121+
static constexpr float SomeFloat = 5.0;
122+
static constexpr BoolConversion BC;
123+
};
124+
125+
void Instantiate() {
126+
TemplFunc<InstTy>();
127+
}
128+
#endif
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %clang_cc1 %s -fopenacc -verify
2+
3+
void Foo() {
4+
int Var;
5+
// expected-warning@+1{{OpenACC clause 'default' not yet implemented}}
6+
#pragma acc data default(present) if(1)
7+
;
8+
// expected-warning@+3{{OpenACC clause 'default' not yet implemented}}
9+
// expected-error@+2{{OpenACC 'if' clause cannot appear more than once on a 'data' directive}}
10+
// expected-note@+1{{previous clause is here}}
11+
#pragma acc data default(present) if(1) if (2)
12+
;
13+
14+
// expected-warning@+1{{OpenACC clause 'copyin' not yet implemented}}
15+
#pragma acc enter data copyin(Var) if(1)
16+
17+
// expected-warning@+3{{OpenACC clause 'copyin' not yet implemented}}
18+
// expected-error@+2{{OpenACC 'if' clause cannot appear more than once on a 'enter data' directive}}
19+
// expected-note@+1{{previous clause is here}}
20+
#pragma acc enter data copyin(Var) if(1) if (2)
21+
22+
// expected-warning@+1{{OpenACC clause 'copyout' not yet implemented}}
23+
#pragma acc exit data copyout(Var) if(1)
24+
// expected-warning@+3{{OpenACC clause 'copyout' not yet implemented}}
25+
// expected-error@+2{{OpenACC 'if' clause cannot appear more than once on a 'exit data' directive}}
26+
// expected-note@+1{{previous clause is here}}
27+
#pragma acc exit data copyout(Var) if(1) if (2)
28+
29+
// expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}}
30+
#pragma acc host_data use_device(Var) if(1)
31+
;
32+
// expected-warning@+3{{OpenACC clause 'use_device' not yet implemented}}
33+
// expected-error@+2{{OpenACC 'if' clause cannot appear more than once on a 'host_data' directive}}
34+
// expected-note@+1{{previous clause is here}}
35+
#pragma acc host_data use_device(Var) if(1) if (2)
36+
;
37+
}

clang/test/SemaOpenACC/data-construct.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ void AtLeastOneOf() {
5252
// OpenACC TODO: The following 'data' directives should diagnose, since they
5353
// don't have at least one of the above clauses.
5454

55-
// expected-warning@+1{{OpenACC clause 'if' not yet implemented}}
5655
#pragma acc data if(Var)
5756
;
5857

@@ -80,7 +79,6 @@ void AtLeastOneOf() {
8079
// OpenACC TODO: The following 'enter data' directives should diagnose, since
8180
// they don't have at least one of the above clauses.
8281

83-
// expected-warning@+1{{OpenACC clause 'if' not yet implemented}}
8482
#pragma acc enter data if(Var)
8583
// expected-warning@+1{{OpenACC clause 'async' not yet implemented}}
8684
#pragma acc enter data async
@@ -99,7 +97,6 @@ void AtLeastOneOf() {
9997
// OpenACC TODO: The following 'exit data' directives should diagnose, since
10098
// they don't have at least one of the above clauses.
10199

102-
// expected-warning@+1{{OpenACC clause 'if' not yet implemented}}
103100
#pragma acc exit data if(Var)
104101
// expected-warning@+1{{OpenACC clause 'async' not yet implemented}}
105102
#pragma acc exit data async
@@ -116,7 +113,6 @@ void AtLeastOneOf() {
116113
// OpenACC TODO: The following 'host_data' directives should diagnose, since
117114
// they don't have at least one of the above clauses.
118115

119-
// expected-warning@+1{{OpenACC clause 'if' not yet implemented}}
120116
#pragma acc host_data if(Var)
121117
;
122118
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
@@ -200,10 +196,8 @@ struct HasMembers {
200196

201197
void HostDataRules() {
202198
int Var, Var2;
203-
// TODO OpenACC: The following line should diagnose, since only 1 'if' is
204-
// allowed per directive on host_data.
205-
// expected-warning@+2{{OpenACC clause 'if' not yet implemented}}
206-
// expected-warning@+1{{OpenACC clause 'if' not yet implemented}}
199+
// expected-error@+2{{OpenACC 'if' clause cannot appear more than once on a 'host_data' directive}}
200+
// expected-note@+1{{previous clause is here}}
207201
#pragma acc host_data if(Var) if (Var2)
208202
;
209203

0 commit comments

Comments
 (0)