Skip to content

Commit

Permalink
[Clang][OpenMP] Add support for compare capture in parser
Browse files Browse the repository at this point in the history
This patch adds the support for `atomic compare capture` in parser and part of
sema. We don't create an AST node for this because the spec doesn't say `compare`
and `capture` clauses should be used tightly, so we cannot look one more token
ahead in the parser.

Reviewed By: ABataev

Differential Revision: https://reviews.llvm.org/D116261
  • Loading branch information
shiltian committed Feb 18, 2022
1 parent 3c84e68 commit ccebf8a
Show file tree
Hide file tree
Showing 4 changed files with 488 additions and 25 deletions.
43 changes: 29 additions & 14 deletions clang/lib/CodeGen/CGStmtOpenMP.cpp
Expand Up @@ -24,6 +24,7 @@
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/PrettyStackTrace.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
Expand Down Expand Up @@ -6020,7 +6021,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
llvm::AtomicOrdering AO, bool IsPostfixUpdate,
const Expr *X, const Expr *V, const Expr *E,
const Expr *UE, bool IsXLHSInRHSPart,
SourceLocation Loc) {
bool IsCompareCapture, SourceLocation Loc) {
switch (Kind) {
case OMPC_read:
emitOMPAtomicReadExpr(CGF, AO, X, V, Loc);
Expand All @@ -6037,10 +6038,19 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
IsXLHSInRHSPart, Loc);
break;
case OMPC_compare: {
// Emit an error here.
unsigned DiagID = CGF.CGM.getDiags().getCustomDiagID(
DiagnosticsEngine::Error, "'atomic compare' is not supported for now");
CGF.CGM.getDiags().Report(DiagID);
if (IsCompareCapture) {
// Emit an error here.
unsigned DiagID = CGF.CGM.getDiags().getCustomDiagID(
DiagnosticsEngine::Error,
"'atomic compare capture' is not supported for now");
CGF.CGM.getDiags().Report(DiagID);
} else {
// Emit an error here.
unsigned DiagID = CGF.CGM.getDiags().getCustomDiagID(
DiagnosticsEngine::Error,
"'atomic compare' is not supported for now");
CGF.CGM.getDiags().Report(DiagID);
}
break;
}
case OMPC_if:
Expand Down Expand Up @@ -6153,18 +6163,23 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
AO = llvm::AtomicOrdering::Monotonic;
MemOrderingSpecified = true;
}
llvm::SmallSet<OpenMPClauseKind, 2> KindsEncountered;
OpenMPClauseKind Kind = OMPC_unknown;
for (const OMPClause *C : S.clauses()) {
// Find first clause (skip seq_cst|acq_rel|aqcuire|release|relaxed clause,
// if it is first).
if (C->getClauseKind() != OMPC_seq_cst &&
C->getClauseKind() != OMPC_acq_rel &&
C->getClauseKind() != OMPC_acquire &&
C->getClauseKind() != OMPC_release &&
C->getClauseKind() != OMPC_relaxed && C->getClauseKind() != OMPC_hint) {
Kind = C->getClauseKind();
break;
}
OpenMPClauseKind K = C->getClauseKind();
if (K == OMPC_seq_cst || K == OMPC_acq_rel || K == OMPC_acquire ||
K == OMPC_release || K == OMPC_relaxed || K == OMPC_hint)
continue;
Kind = K;
KindsEncountered.insert(K);
}
bool IsCompareCapture = false;
if (KindsEncountered.contains(OMPC_compare) &&
KindsEncountered.contains(OMPC_capture)) {
IsCompareCapture = true;
Kind = OMPC_compare;
}
if (!MemOrderingSpecified) {
llvm::AtomicOrdering DefaultOrder =
Expand All @@ -6188,7 +6203,7 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
EmitStopPoint(S.getAssociatedStmt());
emitOMPAtomicExpr(*this, Kind, AO, S.isPostfixUpdate(), S.getX(), S.getV(),
S.getExpr(), S.getUpdateExpr(), S.isXLHSInRHSPart(),
S.getBeginLoc());
IsCompareCapture, S.getBeginLoc());
}

static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
Expand Down
44 changes: 33 additions & 11 deletions clang/lib/Sema/SemaOpenMP.cpp
Expand Up @@ -35,6 +35,7 @@
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/PointerEmbeddedInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Frontend/OpenMP/OMPAssume.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
Expand Down Expand Up @@ -11322,21 +11323,31 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation AtomicKindLoc;
OpenMPClauseKind MemOrderKind = OMPC_unknown;
SourceLocation MemOrderLoc;
bool MutexClauseEncountered = false;
llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
for (const OMPClause *C : Clauses) {
switch (C->getClauseKind()) {
case OMPC_read:
case OMPC_write:
case OMPC_update:
MutexClauseEncountered = true;
LLVM_FALLTHROUGH;
case OMPC_capture:
case OMPC_compare: {
if (AtomicKind != OMPC_unknown) {
if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
<< SourceRange(C->getBeginLoc(), C->getEndLoc());
Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
<< getOpenMPClauseName(AtomicKind);
} else {
AtomicKind = C->getClauseKind();
AtomicKindLoc = C->getBeginLoc();
if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
<< SourceRange(C->getBeginLoc(), C->getEndLoc());
Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
<< getOpenMPClauseName(AtomicKind);
}
}
break;
}
Expand Down Expand Up @@ -11364,6 +11375,12 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
llvm_unreachable("unknown clause is encountered");
}
}
bool IsCompareCapture = false;
if (EncounteredAtomicKinds.contains(OMPC_compare) &&
EncounteredAtomicKinds.contains(OMPC_capture)) {
IsCompareCapture = true;
AtomicKind = OMPC_compare;
}
// OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
// If atomic-clause is read then memory-order-clause must not be acq_rel or
// release.
Expand Down Expand Up @@ -11782,17 +11799,22 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
if (CurContext->isDependentContext())
UE = V = E = X = nullptr;
} else if (AtomicKind == OMPC_compare) {
OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
OpenMPAtomicCompareChecker Checker(*this);
if (!Checker.checkStmt(Body, ErrorInfo)) {
Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
<< ErrorInfo.ErrorRange;
Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
<< ErrorInfo.Error << ErrorInfo.NoteRange;
return StmtError();
if (IsCompareCapture) {
// TODO: We don't set X, D, E, etc. here because in code gen we will emit
// error directly.
} else {
OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
OpenMPAtomicCompareChecker Checker(*this);
if (!Checker.checkStmt(Body, ErrorInfo)) {
Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
<< ErrorInfo.ErrorRange;
Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
<< ErrorInfo.Error << ErrorInfo.NoteRange;
return StmtError();
}
// TODO: We don't set X, D, E, etc. here because in code gen we will emit
// error directly.
}
// TODO: We don't set X, D, E, etc. here because in code gen we will emit
// error directly.
}

setFunctionHasBranchProtectedScope();
Expand Down

0 comments on commit ccebf8a

Please sign in to comment.