aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaOpenACC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaOpenACC.cpp')
-rw-r--r--clang/lib/Sema/SemaOpenACC.cpp100
1 files changed, 44 insertions, 56 deletions
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 846b196..51a95f9 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -498,12 +498,9 @@ bool checkAlreadyHasClauseOfKind(
bool checkValidAfterDeviceType(
SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause,
const SemaOpenACC::OpenACCParsedClause &NewClause) {
- // This is only a requirement on compute, combined, data and loop constructs
- // so far, so this is fine otherwise.
- if (!isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind()) &&
- !isOpenACCCombinedDirectiveKind(NewClause.getDirectiveKind()) &&
- NewClause.getDirectiveKind() != OpenACCDirectiveKind::Loop &&
- NewClause.getDirectiveKind() != OpenACCDirectiveKind::Data)
+ // This is implemented for everything but 'routine', so treat as 'fine' for
+ // that.
+ if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
return false;
// OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are
@@ -578,6 +575,21 @@ bool checkValidAfterDeviceType(
default:
break;
}
+ } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Set ||
+ NewClause.getDirectiveKind() == OpenACCDirectiveKind::Init ||
+ NewClause.getDirectiveKind() == OpenACCDirectiveKind::Shutdown) {
+ // There are no restrictions on 'set', 'init', or 'shutdown'.
+ return false;
+ } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
+ // OpenACC3.3 section 2.14.4: Only the async and wait clauses may follow a
+ // device_type clause.
+ switch (NewClause.getClauseKind()) {
+ case OpenACCClauseKind::Async:
+ case OpenACCClauseKind::Wait:
+ return false;
+ default:
+ break;
+ }
}
S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type)
<< NewClause.getClauseKind() << DeviceTypeClause.getClauseKind()
@@ -709,18 +721,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause(
OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
- // Restrictions only properly implemented on 'compute'/'combined'/'data'
- // constructs, and 'compute'/'combined'/'data' constructs are the only
- // constructs that can do anything with this yet, so skip/treat as
- // unimplemented in this case.
- if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
- return isNotImplemented();
-
// There is no prose in the standard that says duplicates aren't allowed,
// but this diagnostic is present in other compilers, as well as makes
// sense. Prose DOES exist for 'data' and 'host_data', 'set', 'enter data' and
// 'exit data' both don't, but other implmementations do this. OpenACC issue
- // 519 filed for the latter two.
+ // 519 filed for the latter two. Prose also exists for 'update'.
// GCC allows this on init/shutdown, presumably for good reason, so we do too.
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Init &&
Clause.getDirectiveKind() != OpenACCDirectiveKind::Shutdown &&
@@ -731,14 +736,14 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
// isn't really much to do here.
// If the 'if' clause is true, it makes the 'self' clause have no effect,
- // diagnose that here.
- // TODO OpenACC: When we add these two to other constructs, we might not
- // want to warn on this (for example, 'update').
- const auto *Itr =
- llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>);
- if (Itr != ExistingClauses.end()) {
- SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
- SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
+ // diagnose that here. This only applies on compute/combined constructs.
+ if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Update) {
+ const auto *Itr =
+ llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>);
+ if (Itr != ExistingClauses.end()) {
+ SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
+ SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
+ }
}
return OpenACCIfClause::Create(Ctx, Clause.getBeginLoc(),
@@ -748,16 +753,6 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
- // 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 (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
- return isNotImplemented();
-
- // TODO OpenACC: When we implement this for 'update', this takes a
- // 'var-list' instead of a condition expression, so semantics/handling has
- // to happen differently here.
-
// There is no prose in the standard that says duplicates aren't allowed,
// but this diagnostic is present in other compilers, as well as makes
// sense.
@@ -765,9 +760,12 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause(
return nullptr;
// If the 'if' clause is true, it makes the 'self' clause have no effect,
- // diagnose that here.
- // TODO OpenACC: When we add these two to other constructs, we might not
- // want to warn on this (for example, 'update').
+ // diagnose that here. This only applies on compute/combined constructs.
+ if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Update)
+ return OpenACCSelfClause::Create(Ctx, Clause.getBeginLoc(),
+ Clause.getLParenLoc(), Clause.getVarList(),
+ Clause.getEndLoc());
+
const auto *Itr =
llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>);
if (Itr != ExistingClauses.end()) {
@@ -944,13 +942,6 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
- // Restrictions only properly implemented on 'compute'/'combined'/'data'
- // constructs, and 'compute'/'combined'/'data' constructs are the only
- // construct that can do anything with this yet, so skip/treat as
- // unimplemented in this case.
- if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
- return isNotImplemented();
-
// There is no prose in the standard that says duplicates aren't allowed,
// but this diagnostic is present in other compilers, as well as makes
// sense.
@@ -1185,13 +1176,6 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
- // Restrictions only properly implemented on 'compute'/'combined'/'data'
- // constructs, and 'compute'/'combined'/'data' constructs are the only
- // construct that can do anything with this yet, so skip/treat as
- // unimplemented in this case.
- if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
- return isNotImplemented();
-
return OpenACCWaitClause::Create(
Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getDevNumExpr(),
Clause.getQueuesLoc(), Clause.getQueueIdExprs(), Clause.getEndLoc());
@@ -1199,11 +1183,8 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(
OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
- // Restrictions only properly implemented on 'compute', 'combined', 'data' and
- // 'loop' constructs, and 'compute'/'combined'/'data'/'loop' constructs are
- // the only construct that can do anything with this yet, so skip/treat as
- // unimplemented in this case.
- if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
+ // Restrictions implemented properly on everything except 'routine'.
+ if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
return isNotImplemented();
// OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
@@ -1744,8 +1725,6 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause(
OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
- if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
- return isNotImplemented();
// There isn't anything to do here, this is only valid on one construct, and
// has no associated rules.
return OpenACCIfPresentClause::Create(Ctx, Clause.getBeginLoc(),
@@ -1936,6 +1915,7 @@ bool PreserveLoopRAIIDepthInAssociatedStmtRAII(OpenACCDirectiveKind DK) {
case OpenACCDirectiveKind::Init:
case OpenACCDirectiveKind::Shutdown:
case OpenACCDirectiveKind::Set:
+ case OpenACCDirectiveKind::Update:
llvm_unreachable("Doesn't have an associated stmt");
default:
case OpenACCDirectiveKind::Invalid:
@@ -2365,6 +2345,7 @@ void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K,
case OpenACCDirectiveKind::Init:
case OpenACCDirectiveKind::Shutdown:
case OpenACCDirectiveKind::Set:
+ case OpenACCDirectiveKind::Update:
// Nothing to do here, there is no real legalization that needs to happen
// here as these constructs do not take any arguments.
break;
@@ -3713,6 +3694,9 @@ bool SemaOpenACC::ActOnStartStmtDirective(
OpenACCClauseKind::DeviceType,
OpenACCClauseKind::If});
+ // TODO: OpenACC: 'Update' construct needs to have one of 'self', 'host', or
+ // 'device'. Implement here.
+
return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
}
@@ -3780,6 +3764,10 @@ StmtResult SemaOpenACC::ActOnEndStmtDirective(
return OpenACCSetConstruct::Create(getASTContext(), StartLoc, DirLoc,
EndLoc, Clauses);
}
+ case OpenACCDirectiveKind::Update: {
+ return OpenACCUpdateConstruct::Create(getASTContext(), StartLoc, DirLoc,
+ EndLoc, Clauses);
+ }
}
llvm_unreachable("Unhandled case in directive handling?");
}