diff options
Diffstat (limited to 'clang/lib/Sema/SemaOpenACC.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenACC.cpp | 100 |
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?"); } |