Skip to content

Commit

Permalink
[OpenACC] Enable serial/kernels Compute Constructs
Browse files Browse the repository at this point in the history
So far, all the work we've done for compute constructs has only used
'parallel'.  This patch does the work to enable the same logic for
'serial' and 'kernels' constructs as well, since they are the same
semantic behavior.
  • Loading branch information
erichkeane committed Mar 4, 2024
1 parent be3eeea commit bb97c99
Show file tree
Hide file tree
Showing 9 changed files with 585 additions and 451 deletions.
4 changes: 4 additions & 0 deletions clang/lib/Parse/ParseOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,8 @@ bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) {
default:
return false;
case OpenACCDirectiveKind::Parallel:
case OpenACCDirectiveKind::Serial:
case OpenACCDirectiveKind::Kernels:
return true;
}
llvm_unreachable("Unhandled directive->assoc stmt");
Expand All @@ -563,6 +565,8 @@ bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) {
unsigned getOpenACCScopeFlags(OpenACCDirectiveKind DirKind) {
switch (DirKind) {
case OpenACCDirectiveKind::Parallel:
case OpenACCDirectiveKind::Serial:
case OpenACCDirectiveKind::Kernels:
// Mark this as a BreakScope/ContinueScope as well as a compute construct
// so that we can diagnose trying to 'break'/'continue' inside of one.
return Scope::BreakScope | Scope::ContinueScope |
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Sema/SemaOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ bool diagnoseConstructAppertainment(Sema &S, OpenACCDirectiveKind K,
// do anything.
break;
case OpenACCDirectiveKind::Parallel:
case OpenACCDirectiveKind::Serial:
case OpenACCDirectiveKind::Kernels:
if (!IsStmt)
return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
break;
Expand Down Expand Up @@ -55,6 +57,8 @@ void Sema::ActOnOpenACCConstruct(OpenACCDirectiveKind K,
// rules anywhere.
break;
case OpenACCDirectiveKind::Parallel:
case OpenACCDirectiveKind::Serial:
case OpenACCDirectiveKind::Kernels:
// Nothing to do here, there is no real legalization that needs to happen
// here as these constructs do not take any arguments.
break;
Expand All @@ -79,6 +83,8 @@ StmtResult Sema::ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K,
case OpenACCDirectiveKind::Invalid:
return StmtError();
case OpenACCDirectiveKind::Parallel:
case OpenACCDirectiveKind::Serial:
case OpenACCDirectiveKind::Kernels:
return OpenACCComputeConstruct::Create(
getASTContext(), K, StartLoc, EndLoc,
AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
Expand All @@ -92,6 +98,8 @@ StmtResult Sema::ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K,
default:
llvm_unreachable("Unimplemented associated statement application");
case OpenACCDirectiveKind::Parallel:
case OpenACCDirectiveKind::Serial:
case OpenACCDirectiveKind::Kernels:
// There really isn't any checking here that could happen. As long as we
// have a statement to associate, this should be fine.
// OpenACC 3.3 Section 6:
Expand Down
841 changes: 404 additions & 437 deletions clang/test/ParserOpenACC/parse-clauses.c

Large diffs are not rendered by default.

21 changes: 8 additions & 13 deletions clang/test/ParserOpenACC/parse-constructs.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,19 @@ void func() {
// expected-note@+1{{to match this '('}}
#pragma acc parallel( clause list
for(;;){}
// expected-error@+3{{expected clause-list or newline in OpenACC directive}}
// expected-error@+2{{invalid OpenACC clause 'clause'}}
// expected-warning@+1{{OpenACC construct 'serial' not yet implemented, pragma ignored}}
// expected-error@+2{{expected clause-list or newline in OpenACC directive}}
// expected-error@+1{{invalid OpenACC clause 'clause'}}
#pragma acc serial() clause list
for(;;){}
// expected-error@+4{{expected clause-list or newline in OpenACC directive}}
// expected-error@+3{{expected ')'}}
// expected-note@+2{{to match this '('}}
// expected-warning@+1{{OpenACC construct 'serial' not yet implemented, pragma ignored}}
// expected-error@+3{{expected clause-list or newline in OpenACC directive}}
// expected-error@+2{{expected ')'}}
// expected-note@+1{{to match this '('}}
#pragma acc serial( clause list
for(;;){}
// expected-error@+2{{invalid OpenACC clause 'clause'}}
// expected-warning@+1{{OpenACC construct 'serial' not yet implemented, pragma ignored}}
// expected-error@+1{{invalid OpenACC clause 'clause'}}
#pragma acc serial clause list
for(;;){}
// expected-error@+2{{invalid OpenACC clause 'clause'}}
// expected-warning@+1{{OpenACC construct 'kernels' not yet implemented, pragma ignored}}
// expected-error@+1{{invalid OpenACC clause 'clause'}}
#pragma acc kernels clause list
for(;;){}
// expected-error@+2{{invalid OpenACC clause 'clause'}}
Expand Down Expand Up @@ -93,8 +89,7 @@ void func() {
// expected-error@+1{{invalid OpenACC clause 'invalid'}}
#pragma acc parallel invalid clause list
for(;;){}
// expected-error@+2{{invalid OpenACC clause 'invalid'}}
// expected-warning@+1{{OpenACC construct 'serial' not yet implemented, pragma ignored}}
// expected-error@+1{{invalid OpenACC clause 'invalid'}}
#pragma acc serial invalid clause list
for(;;){}
// expected-error@+2{{invalid OpenACC clause 'clause'}}
Expand Down
50 changes: 50 additions & 0 deletions clang/test/SemaOpenACC/compute-construct-ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,30 @@ void NormalFunc() {
#pragma acc parallel
{}
}
// FIXME: Add a test once we have clauses for this.
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}serial
// CHECK-NEXT: CompoundStmt
#pragma acc serial
{
#pragma acc serial
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}serial
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}serial
// CHECK-NEXT: CompoundStmt
#pragma acc serial
{}
}
// FIXME: Add a test once we have clauses for this.
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}kernels
// CHECK-NEXT: CompoundStmt
#pragma acc kernels
{
#pragma acc kernels
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}kernels
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}kernels
// CHECK-NEXT: CompoundStmt
#pragma acc kernels
{}
}
}

template<typename T>
Expand All @@ -24,6 +48,16 @@ void TemplFunc() {
typename T::type I;
}

#pragma acc serial
{
typename T::type I;
}

#pragma acc kernels
{
typename T::type I;
}

// CHECK-LABEL: FunctionTemplateDecl {{.*}}TemplFunc
// CHECK-NEXT: TemplateTypeParmDecl

Expand All @@ -34,6 +68,14 @@ void TemplFunc() {
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename T::type'
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}serial
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename T::type'
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}kernels
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename T::type'

// Check instantiation.
// CHECK-LABEL: FunctionDecl{{.*}} used TemplFunc 'void ()' implicit_instantiation
Expand All @@ -45,6 +87,14 @@ void TemplFunc() {
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename S::type':'int'
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}serial
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename S::type':'int'
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}kernels
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename S::type':'int'
}

struct S {
Expand Down
66 changes: 66 additions & 0 deletions clang/test/SemaOpenACC/no-branch-in-out.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ void BreakContinue() {
break; // expected-error{{invalid branch out of OpenACC Compute Construct}}
}

#pragma acc serial
for(int i = 0; i < 5; ++i) {
if (i > 1)
break; // expected-error{{invalid branch out of OpenACC Compute Construct}}
}

#pragma acc kernels
for(int i = 0; i < 5; ++i) {
if (i > 1)
break; // expected-error{{invalid branch out of OpenACC Compute Construct}}
}

#pragma acc parallel
switch(j) {
case 1:
Expand Down Expand Up @@ -99,6 +111,16 @@ void Return() {
return;// expected-error{{invalid return out of OpenACC Compute Construct}}
}

#pragma acc serial
{
return;// expected-error{{invalid return out of OpenACC Compute Construct}}
}

#pragma acc kernels
{
return;// expected-error{{invalid return out of OpenACC Compute Construct}}
}

#pragma acc parallel
{
{
Expand Down Expand Up @@ -255,6 +277,34 @@ LABEL13:{}
LABEL14:{}
({goto LABEL14;});
}



({goto LABEL15;});// expected-error{{cannot jump from this goto statement to its label}}
#pragma acc serial// expected-note{{invalid branch into OpenACC Compute Construct}}
{
LABEL15:{}
}

LABEL16:{}
#pragma acc serial// expected-note{{invalid branch out of OpenACC Compute Construct}}
{
({goto LABEL16;});// expected-error{{cannot jump from this goto statement to its label}}
}


({goto LABEL17;});// expected-error{{cannot jump from this goto statement to its label}}
#pragma acc kernels// expected-note{{invalid branch into OpenACC Compute Construct}}
{
LABEL17:{}
}

LABEL18:{}
#pragma acc kernels// expected-note{{invalid branch out of OpenACC Compute Construct}}
{
({goto LABEL18;});// expected-error{{cannot jump from this goto statement to its label}}
}

}

void IndirectGoto1() {
Expand Down Expand Up @@ -329,11 +379,27 @@ void DuffsDevice() {
}
}

switch (j) {
#pragma acc kernels
for(int i =0; i < 5; ++i) {
default: // expected-error{{invalid branch into OpenACC Compute Construct}}
{}
}
}

switch (j) {
#pragma acc parallel
for(int i =0; i < 5; ++i) {
case 'a' ... 'z': // expected-error{{invalid branch into OpenACC Compute Construct}}
{}
}
}

switch (j) {
#pragma acc serial
for(int i =0; i < 5; ++i) {
case 'a' ... 'z': // expected-error{{invalid branch into OpenACC Compute Construct}}
{}
}
}
}
11 changes: 11 additions & 0 deletions clang/test/SemaOpenACC/no-branch-in-out.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,17 @@ void Exceptions() {
throw; // expected-error{{invalid throw out of OpenACC Compute Construct}}
}

#pragma acc serial
for(int i = 0; i < 5; ++i) {
throw; // expected-error{{invalid throw out of OpenACC Compute Construct}}
}

#pragma acc kernels
for(int i = 0; i < 5; ++i) {
throw; // expected-error{{invalid throw out of OpenACC Compute Construct}}
}


#pragma acc parallel
for(int i = 0; i < 5; ++i) {
try {
Expand Down
8 changes: 7 additions & 1 deletion clang/test/SemaOpenACC/parallel-assoc-stmt-inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ template<typename T>
void Func() {
#pragma acc parallel
typename T::type I; //#ILOC
#pragma acc serial
typename T::type IS; //#ILOCSERIAL
#pragma acc kernels
typename T::type IK; //#ILOCKERNELS
}

struct S {
Expand All @@ -13,6 +17,8 @@ struct S {
void use() {
Func<S>();
// expected-error@#ILOC{{type 'int' cannot be used prior to '::' because it has no members}}
// expected-note@+1{{in instantiation of function template specialization 'Func<int>' requested here}}
// expected-note@+3{{in instantiation of function template specialization 'Func<int>' requested here}}
// expected-error@#ILOCSERIAL{{type 'int' cannot be used prior to '::' because it has no members}}
// expected-error@#ILOCKERNELS{{type 'int' cannot be used prior to '::' because it has no members}}
Func<int>();
}
27 changes: 27 additions & 0 deletions clang/test/SemaOpenACC/parallel-loc-and-stmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,32 @@
// expected-error@+1{{OpenACC construct 'parallel' cannot be used here; it can only be used in a statement context}}
#pragma acc parallel

// expected-error@+1{{OpenACC construct 'serial' cannot be used here; it can only be used in a statement context}}
#pragma acc serial

// expected-error@+1{{OpenACC construct 'kernels' cannot be used here; it can only be used in a statement context}}
#pragma acc kernels

// expected-error@+1{{OpenACC construct 'parallel' cannot be used here; it can only be used in a statement context}}
#pragma acc parallel
int foo;
// expected-error@+1{{OpenACC construct 'serial' cannot be used here; it can only be used in a statement context}}
#pragma acc serial
int foo2;
// expected-error@+1{{OpenACC construct 'kernels' cannot be used here; it can only be used in a statement context}}
#pragma acc kernels
int foo3;

struct S {
// expected-error@+1{{OpenACC construct 'parallel' cannot be used here; it can only be used in a statement context}}
#pragma acc parallel
int foo;
// expected-error@+1{{OpenACC construct 'serial' cannot be used here; it can only be used in a statement context}}
#pragma acc serial
int foo2;
// expected-error@+1{{OpenACC construct 'kernels' cannot be used here; it can only be used in a statement context}}
#pragma acc kernels
int foo3;
};

void func() {
Expand All @@ -31,6 +49,15 @@ void func() {
#pragma acc parallel
}

{
// expected-error@+2{{expected statement}}
#pragma acc serial
}
{
// expected-error@+2{{expected statement}}
#pragma acc kernels
}

#pragma acc parallel
while(0){}

Expand Down

0 comments on commit bb97c99

Please sign in to comment.