[OpenACC] Enable serial/kernels Compute Constructs

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.
This commit is contained in:
erichkeane 2024-03-04 12:32:09 -08:00
parent be3eeea7be
commit bb97c99283
9 changed files with 587 additions and 453 deletions

View File

@ -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");
@ -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 |

View File

@ -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;
@ -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;
@ -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);
@ -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:

File diff suppressed because it is too large Load Diff

View File

@ -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'}}
@ -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'}}

View File

@ -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>
@ -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
@ -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
@ -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 {

View File

@ -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:
@ -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
{
{
@ -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() {
@ -329,6 +379,14 @@ 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) {
@ -336,4 +394,12 @@ void DuffsDevice() {
{}
}
}
switch (j) {
#pragma acc serial
for(int i =0; i < 5; ++i) {
case 'a' ... 'z': // expected-error{{invalid branch into OpenACC Compute Construct}}
{}
}
}
}

View File

@ -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 {

View File

@ -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 {
@ -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>();
}

View File

@ -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() {
@ -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){}