Skip to content

Commit 2244d2e

Browse files
committed
[OpenACC] Implement 'if_present' clause sema
The 'if_present' clause controls the replacement of addresses in the var-list in current device memory. This clause can only go on 'host_device'. From a Sema perspective, there isn't anything to do beyond add this to AST and pass it on.
1 parent 0f776f1 commit 2244d2e

20 files changed

+169
-24
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,28 @@ class OpenACCFinalizeClause : public OpenACCClause {
9898
}
9999
};
100100

101+
// Represents the 'if_present' clause.
102+
class OpenACCIfPresentClause : public OpenACCClause {
103+
protected:
104+
OpenACCIfPresentClause(SourceLocation BeginLoc, SourceLocation EndLoc)
105+
: OpenACCClause(OpenACCClauseKind::IfPresent, BeginLoc, EndLoc) {}
106+
107+
public:
108+
static bool classof(const OpenACCClause *C) {
109+
return C->getClauseKind() == OpenACCClauseKind::IfPresent;
110+
}
111+
112+
static OpenACCIfPresentClause *
113+
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
114+
115+
child_range children() {
116+
return child_range(child_iterator(), child_iterator());
117+
}
118+
const_child_range children() const {
119+
return const_child_range(const_child_iterator(), const_child_iterator());
120+
}
121+
};
122+
101123
// Represents the 'independent' clause.
102124
class OpenACCIndependentClause : public OpenACCClause {
103125
protected:

clang/include/clang/Basic/OpenACCClauses.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ VISIT_CLAUSE(Finalize)
4545
VISIT_CLAUSE(FirstPrivate)
4646
VISIT_CLAUSE(Gang)
4747
VISIT_CLAUSE(If)
48+
VISIT_CLAUSE(IfPresent)
4849
VISIT_CLAUSE(Independent)
4950
VISIT_CLAUSE(NoCreate)
5051
VISIT_CLAUSE(NumGangs)

clang/lib/AST/OpenACCClause.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,14 @@ OpenACCFinalizeClause *OpenACCFinalizeClause::Create(const ASTContext &C,
452452
return new (Mem) OpenACCFinalizeClause(BeginLoc, EndLoc);
453453
}
454454

455+
OpenACCIfPresentClause *OpenACCIfPresentClause::Create(const ASTContext &C,
456+
SourceLocation BeginLoc,
457+
SourceLocation EndLoc) {
458+
void *Mem = C.Allocate(sizeof(OpenACCIfPresentClause),
459+
alignof(OpenACCIfPresentClause));
460+
return new (Mem) OpenACCIfPresentClause(BeginLoc, EndLoc);
461+
}
462+
455463
//===----------------------------------------------------------------------===//
456464
// OpenACC clauses printing methods
457465
//===----------------------------------------------------------------------===//
@@ -697,3 +705,8 @@ void OpenACCClausePrinter::VisitVectorClause(const OpenACCVectorClause &C) {
697705
void OpenACCClausePrinter::VisitFinalizeClause(const OpenACCFinalizeClause &C) {
698706
OS << "finalize";
699707
}
708+
709+
void OpenACCClausePrinter::VisitIfPresentClause(
710+
const OpenACCIfPresentClause &C) {
711+
OS << "if_present";
712+
}

clang/lib/AST/StmtProfile.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2561,6 +2561,9 @@ void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) {
25612561
void OpenACCClauseProfiler::VisitFinalizeClause(
25622562
const OpenACCFinalizeClause &Clause) {}
25632563

2564+
void OpenACCClauseProfiler::VisitIfPresentClause(
2565+
const OpenACCIfPresentClause &Clause) {}
2566+
25642567
void OpenACCClauseProfiler::VisitNumGangsClause(
25652568
const OpenACCNumGangsClause &Clause) {
25662569
for (auto *E : Clause.getIntExprs())

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
409409
case OpenACCClauseKind::PCopy:
410410
case OpenACCClauseKind::PresentOrCopy:
411411
case OpenACCClauseKind::If:
412+
case OpenACCClauseKind::IfPresent:
412413
case OpenACCClauseKind::Independent:
413414
case OpenACCClauseKind::DevicePtr:
414415
case OpenACCClauseKind::Finalize:

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,15 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
416416
return false;
417417
}
418418
}
419+
case OpenACCClauseKind::IfPresent: {
420+
switch (DirectiveKind) {
421+
case OpenACCDirectiveKind::HostData:
422+
case OpenACCDirectiveKind::Update:
423+
return true;
424+
default:
425+
return false;
426+
}
427+
}
419428
}
420429

421430
default:
@@ -1620,6 +1629,16 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause(
16201629
Clause.getEndLoc());
16211630
}
16221631

1632+
OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause(
1633+
SemaOpenACC::OpenACCParsedClause &Clause) {
1634+
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::HostData)
1635+
return isNotImplemented();
1636+
// There isn't anything to do here, this is only valid on one construct, and
1637+
// has no associated rules.
1638+
return OpenACCIfPresentClause::Create(Ctx, Clause.getBeginLoc(),
1639+
Clause.getEndLoc());
1640+
}
1641+
16231642
OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause(
16241643
SemaOpenACC::OpenACCParsedClause &Clause) {
16251644
// Restrictions only properly implemented on 'loop' constructs and combined ,

clang/lib/Sema/TreeTransform.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11986,6 +11986,14 @@ void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
1198611986
ParsedClause.getEndLoc());
1198711987
}
1198811988

11989+
template <typename Derived>
11990+
void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
11991+
const OpenACCIfPresentClause &C) {
11992+
NewClause = OpenACCIfPresentClause::Create(Self.getSema().getASTContext(),
11993+
ParsedClause.getBeginLoc(),
11994+
ParsedClause.getEndLoc());
11995+
}
11996+
1198911997
template <typename Derived>
1199011998
void OpenACCClauseTransform<Derived>::VisitReductionClause(
1199111999
const OpenACCReductionClause &C) {

clang/lib/Serialization/ASTReader.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12536,6 +12536,8 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1253612536
return OpenACCSeqClause::Create(getContext(), BeginLoc, EndLoc);
1253712537
case OpenACCClauseKind::Finalize:
1253812538
return OpenACCFinalizeClause::Create(getContext(), BeginLoc, EndLoc);
12539+
case OpenACCClauseKind::IfPresent:
12540+
return OpenACCIfPresentClause::Create(getContext(), BeginLoc, EndLoc);
1253912541
case OpenACCClauseKind::Independent:
1254012542
return OpenACCIndependentClause::Create(getContext(), BeginLoc, EndLoc);
1254112543
case OpenACCClauseKind::Auto:
@@ -12581,7 +12583,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1258112583
VectorExpr, EndLoc);
1258212584
}
1258312585

12584-
case OpenACCClauseKind::IfPresent:
1258512586
case OpenACCClauseKind::NoHost:
1258612587
case OpenACCClauseKind::UseDevice:
1258712588
case OpenACCClauseKind::Delete:

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8452,6 +8452,7 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
84528452
case OpenACCClauseKind::Independent:
84538453
case OpenACCClauseKind::Auto:
84548454
case OpenACCClauseKind::Finalize:
8455+
case OpenACCClauseKind::IfPresent:
84558456
// Nothing to do here, there is no additional information beyond the
84568457
// begin/end loc and clause kind.
84578458
return;
@@ -8497,7 +8498,6 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
84978498
return;
84988499
}
84998500

8500-
case OpenACCClauseKind::IfPresent:
85018501
case OpenACCClauseKind::NoHost:
85028502
case OpenACCClauseKind::UseDevice:
85038503
case OpenACCClauseKind::Delete:

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,8 @@ void foo() {
113113

114114
// CHECK: #pragma acc exit data copyout(i) finalize
115115
#pragma acc exit data copyout(i) finalize
116+
117+
// CHECK: #pragma acc host_data if_present
118+
#pragma acc host_data use_device(i) if_present
119+
;
116120
}

clang/test/ParserOpenACC/parse-clauses.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,8 @@ void func() {
1616

1717
#pragma acc exit data wait finalize
1818

19-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented, clause ignored}}
2019
#pragma acc host_data if_present
2120

22-
// expected-warning@+2{{OpenACC clause 'if_present' not yet implemented, clause ignored}}
23-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented, clause ignored}}
2421
#pragma acc host_data if_present, if_present
2522

2623
// expected-error@+4{{OpenACC clause 'independent' on 'loop' construct conflicts with previous data dependence clause}}

clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void uses() {
4040
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
4141
#pragma acc parallel loop auto finalize
4242
for(unsigned i = 0; i < 5; ++i);
43-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
43+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
4444
#pragma acc parallel loop auto if_present
4545
for(unsigned i = 0; i < 5; ++i);
4646
#pragma acc parallel loop auto worker
@@ -157,7 +157,7 @@ void uses() {
157157
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
158158
#pragma acc parallel loop finalize auto
159159
for(unsigned i = 0; i < 5; ++i);
160-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
160+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
161161
#pragma acc parallel loop if_present auto
162162
for(unsigned i = 0; i < 5; ++i);
163163
#pragma acc parallel loop worker auto
@@ -275,7 +275,7 @@ void uses() {
275275
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
276276
#pragma acc parallel loop independent finalize
277277
for(unsigned i = 0; i < 5; ++i);
278-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
278+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
279279
#pragma acc parallel loop independent if_present
280280
for(unsigned i = 0; i < 5; ++i);
281281
#pragma acc parallel loop independent worker
@@ -392,7 +392,7 @@ void uses() {
392392
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
393393
#pragma acc parallel loop finalize independent
394394
for(unsigned i = 0; i < 5; ++i);
395-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
395+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
396396
#pragma acc parallel loop if_present independent
397397
for(unsigned i = 0; i < 5; ++i);
398398
#pragma acc parallel loop worker independent
@@ -522,7 +522,7 @@ void uses() {
522522
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
523523
#pragma acc parallel loop seq finalize
524524
for(unsigned i = 0; i < 5; ++i);
525-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
525+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
526526
#pragma acc parallel loop seq if_present
527527
for(unsigned i = 0; i < 5; ++i);
528528
// expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}}
@@ -645,7 +645,7 @@ void uses() {
645645
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
646646
#pragma acc parallel loop finalize seq
647647
for(unsigned i = 0; i < 5; ++i);
648-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
648+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
649649
#pragma acc parallel loop if_present seq
650650
for(unsigned i = 0; i < 5; ++i);
651651
// expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ void uses() {
4545
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'serial loop' directive}}
4646
#pragma acc serial loop device_type(*) finalize
4747
for(int i = 0; i < 5; ++i);
48-
// expected-error@+2{{OpenACC clause 'if_present' may not follow a 'device_type' clause in a 'kernels loop' construct}}
49-
// expected-note@+1{{previous clause is here}}
48+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'kernels loop' directive}}
5049
#pragma acc kernels loop device_type(*) if_present
5150
for(int i = 0; i < 5; ++i);
5251
#pragma acc parallel loop device_type(*) seq

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ void uses() {
4545
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'kernels' directive}}
4646
#pragma acc kernels device_type(*) finalize
4747
while(1);
48-
// expected-error@+2{{OpenACC clause 'if_present' may not follow a 'device_type' clause in a 'kernels' construct}}
49-
// expected-note@+1{{previous clause is here}}
48+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'kernels' directive}}
5049
#pragma acc kernels device_type(*) if_present
5150
while(1);
5251
// expected-error@+1{{OpenACC 'seq' clause is not valid on 'kernels' directive}}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
#ifndef PCH_HELPER
7+
#define PCH_HELPER
8+
9+
void Uses() {
10+
// CHECK: FunctionDecl{{.*}}Uses
11+
// CHECK-NEXT: CompoundStmt
12+
13+
int I;
14+
// CHECK-NEXT: DeclStmt
15+
// CHECK-NEXT: VarDecl
16+
17+
#pragma acc host_data use_device(I) if_present
18+
;
19+
// CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data
20+
// CHECK-NEXT: if_present clause
21+
// CHECK-NEXT: NullStmt
22+
}
23+
24+
template<typename T>
25+
void TemplUses() {
26+
// CHECK: FunctionTemplateDecl{{.*}}TemplUses
27+
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}T
28+
// CHECK-NEXT: FunctionDecl{{.*}}TemplUses
29+
// CHECK-NEXT: CompoundStmt
30+
31+
T I;
32+
// CHECK-NEXT: DeclStmt
33+
// CHECK-NEXT: VarDecl
34+
35+
#pragma acc host_data use_device(I) if_present
36+
;
37+
// CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data
38+
// CHECK-NEXT: if_present clause
39+
// CHECK-NEXT: NullStmt
40+
41+
// Instantiations
42+
// CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void ()' implicit_instantiation
43+
// CHECK-NEXT: TemplateArgument type 'int'
44+
// CHECK-NEXT: BuiltinType{{.*}} 'int'
45+
// CHECK-NEXT: CompoundStmt
46+
47+
// CHECK-NEXT: DeclStmt
48+
// CHECK-NEXT: VarDecl
49+
50+
// CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data
51+
// CHECK-NEXT: if_present clause
52+
// CHECK-NEXT: NullStmt
53+
}
54+
void Inst() {
55+
TemplUses<int>();
56+
}
57+
58+
59+
#endif // PCH_HELPER
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %clang_cc1 %s -fopenacc -verify
2+
3+
void Test() {
4+
int I;
5+
6+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'data' directive}}
7+
#pragma acc data copyin(I) if_present
8+
;
9+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'enter data' directive}}
10+
#pragma acc enter data copyin(I) if_present
11+
;
12+
13+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'exit data' directive}}
14+
#pragma acc exit data copyout(I) if_present
15+
;
16+
// expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}}
17+
#pragma acc host_data use_device(I) if_present
18+
;
19+
}

clang/test/SemaOpenACC/data-construct.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ void AtLeastOneOf() {
9696

9797
#pragma acc host_data if(Var)
9898
;
99-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
10099
#pragma acc host_data if_present
101100
;
102101
#pragma acc host_data

clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void uses() {
4040
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
4141
#pragma acc loop auto finalize
4242
for(unsigned i = 0; i < 5; ++i);
43-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
43+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
4444
#pragma acc loop auto if_present
4545
for(unsigned i = 0; i < 5; ++i);
4646
#pragma acc loop auto worker
@@ -174,7 +174,7 @@ void uses() {
174174
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
175175
#pragma acc loop finalize auto
176176
for(unsigned i = 0; i < 5; ++i);
177-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
177+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
178178
#pragma acc loop if_present auto
179179
for(unsigned i = 0; i < 5; ++i);
180180
#pragma acc loop worker auto
@@ -309,7 +309,7 @@ void uses() {
309309
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
310310
#pragma acc loop independent finalize
311311
for(unsigned i = 0; i < 5; ++i);
312-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
312+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
313313
#pragma acc loop independent if_present
314314
for(unsigned i = 0; i < 5; ++i);
315315
#pragma acc loop independent worker
@@ -443,7 +443,7 @@ void uses() {
443443
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
444444
#pragma acc loop finalize independent
445445
for(unsigned i = 0; i < 5; ++i);
446-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
446+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
447447
#pragma acc loop if_present independent
448448
for(unsigned i = 0; i < 5; ++i);
449449
#pragma acc loop worker independent
@@ -590,7 +590,7 @@ void uses() {
590590
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
591591
#pragma acc loop seq finalize
592592
for(unsigned i = 0; i < 5; ++i);
593-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
593+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
594594
#pragma acc loop seq if_present
595595
for(unsigned i = 0; i < 5; ++i);
596596
// expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}}
@@ -730,7 +730,7 @@ void uses() {
730730
// expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
731731
#pragma acc loop finalize seq
732732
for(unsigned i = 0; i < 5; ++i);
733-
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
733+
// expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
734734
#pragma acc loop if_present seq
735735
for(unsigned i = 0; i < 5; ++i);
736736
// expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}}

0 commit comments

Comments
 (0)