Skip to content

Commit 086b653

Browse files
SunilKuravinakopchichunchen
authored andcommitted
[OpenMP] atomic compare fail : Parser & AST support
This is a support for " #pragma omp atomic compare fail ". It has Parser & AST support for now. Reviewed By: tianshilei1992, ABataev Differential Revision: https://reviews.llvm.org/D123235
1 parent 25ec1fa commit 086b653

File tree

19 files changed

+288
-1
lines changed

19 files changed

+288
-1
lines changed

clang/include/clang/AST/OpenMPClause.h

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,6 +2513,104 @@ class OMPRelaxedClause final : public OMPClause {
25132513
}
25142514
};
25152515

2516+
/// This represents 'fail' clause in the '#pragma omp atomic'
2517+
/// directive.
2518+
///
2519+
/// \code
2520+
/// #pragma omp atomic compare fail
2521+
/// \endcode
2522+
/// In this example directive '#pragma omp atomic compare' has 'fail' clause.
2523+
class OMPFailClause final : public OMPClause {
2524+
2525+
// FailParameter is a memory-order-clause. Storing the ClauseKind is
2526+
// sufficient for our purpose.
2527+
OpenMPClauseKind FailParameter = llvm::omp::Clause::OMPC_unknown;
2528+
SourceLocation FailParameterLoc;
2529+
SourceLocation LParenLoc;
2530+
2531+
friend class OMPClauseReader;
2532+
2533+
/// Sets the location of '(' in fail clause.
2534+
void setLParenLoc(SourceLocation Loc) {
2535+
LParenLoc = Loc;
2536+
}
2537+
2538+
/// Sets the location of memoryOrder clause argument in fail clause.
2539+
void setFailParameterLoc(SourceLocation Loc) { FailParameterLoc = Loc; }
2540+
2541+
/// Sets the mem_order clause for 'atomic compare fail' directive.
2542+
void setFailParameter(OpenMPClauseKind FailParameter) {
2543+
switch (FailParameter) {
2544+
case llvm::omp::OMPC_acq_rel:
2545+
case llvm::omp::OMPC_acquire:
2546+
this->FailParameter = llvm::omp::OMPC_acquire;
2547+
break;
2548+
case llvm::omp::OMPC_relaxed:
2549+
case llvm::omp::OMPC_release:
2550+
this->FailParameter = llvm::omp::OMPC_relaxed;
2551+
break;
2552+
case llvm::omp::OMPC_seq_cst:
2553+
this->FailParameter = llvm::omp::OMPC_seq_cst;
2554+
break;
2555+
default:
2556+
this->FailParameter = llvm::omp::OMPC_unknown;
2557+
break;
2558+
}
2559+
}
2560+
2561+
public:
2562+
/// Build 'fail' clause.
2563+
///
2564+
/// \param StartLoc Starting location of the clause.
2565+
/// \param EndLoc Ending location of the clause.
2566+
OMPFailClause(SourceLocation StartLoc, SourceLocation EndLoc)
2567+
: OMPClause(llvm::omp::OMPC_fail, StartLoc, EndLoc) {}
2568+
2569+
OMPFailClause(OpenMPClauseKind FailParameter, SourceLocation FailParameterLoc,
2570+
SourceLocation StartLoc, SourceLocation LParenLoc,
2571+
SourceLocation EndLoc)
2572+
: OMPClause(llvm::omp::OMPC_fail, StartLoc, EndLoc),
2573+
FailParameterLoc(FailParameterLoc), LParenLoc(LParenLoc) {
2574+
2575+
setFailParameter(FailParameter);
2576+
}
2577+
2578+
/// Build an empty clause.
2579+
OMPFailClause()
2580+
: OMPClause(llvm::omp::OMPC_fail, SourceLocation(), SourceLocation()) {}
2581+
2582+
child_range children() {
2583+
return child_range(child_iterator(), child_iterator());
2584+
}
2585+
2586+
const_child_range children() const {
2587+
return const_child_range(const_child_iterator(), const_child_iterator());
2588+
}
2589+
2590+
child_range used_children() {
2591+
return child_range(child_iterator(), child_iterator());
2592+
}
2593+
const_child_range used_children() const {
2594+
return const_child_range(const_child_iterator(), const_child_iterator());
2595+
}
2596+
2597+
static bool classof(const OMPClause *T) {
2598+
return T->getClauseKind() == llvm::omp::OMPC_fail;
2599+
}
2600+
2601+
/// Gets the location of '(' (for the parameter) in fail clause.
2602+
SourceLocation getLParenLoc() const {
2603+
return LParenLoc;
2604+
}
2605+
2606+
/// Gets the location of Fail Parameter (type memory-order-clause) in
2607+
/// fail clause.
2608+
SourceLocation getFailParameterLoc() const { return FailParameterLoc; }
2609+
2610+
/// Gets the parameter (type memory-order-clause) in Fail clause.
2611+
OpenMPClauseKind getFailParameter() const { return FailParameter; }
2612+
};
2613+
25162614
/// This represents clause 'private' in the '#pragma omp ...' directives.
25172615
///
25182616
/// \code

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3398,6 +3398,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPCompareClause(OMPCompareClause *) {
33983398
return true;
33993399
}
34003400

3401+
template <typename Derived>
3402+
bool RecursiveASTVisitor<Derived>::VisitOMPFailClause(OMPFailClause *) {
3403+
return true;
3404+
}
3405+
34013406
template <typename Derived>
34023407
bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
34033408
return true;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10962,6 +10962,8 @@ def note_omp_atomic_compare: Note<
1096210962
"expect binary operator in conditional expression|expect '<', '>' or '==' as order operator|expect comparison in a form of 'x == e', 'e == x', 'x ordop expr', or 'expr ordop x'|"
1096310963
"expect lvalue for result value|expect scalar value|expect integer value|unexpected 'else' statement|expect '==' operator|expect an assignment statement 'v = x'|"
1096410964
"expect a 'if' statement|expect no more than two statements|expect a compound statement|expect 'else' statement|expect a form 'r = x == e; if (r) ...'}0">;
10965+
def err_omp_atomic_fail_wrong_or_no_clauses : Error<"expected a memory order clause">;
10966+
def err_omp_atomic_fail_no_compare : Error<"expected 'compare' clause with the 'fail' modifier">;
1096510967
def err_omp_atomic_several_clauses : Error<
1096610968
"directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update', 'capture', or 'compare' clause">;
1096710969
def err_omp_several_mem_order_clauses : Error<

clang/include/clang/Basic/OpenMPKinds.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
#ifndef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND
4242
#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name)
4343
#endif
44+
#ifndef OPENMP_ATOMIC_FAIL_MODIFIER
45+
#define OPENMP_ATOMIC_FAIL_MODIFIER(Name)
46+
#endif
4447
#ifndef OPENMP_AT_KIND
4548
#define OPENMP_AT_KIND(Name)
4649
#endif
@@ -138,6 +141,13 @@ OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst)
138141
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel)
139142
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(relaxed)
140143

144+
// Modifiers for atomic 'fail' clause.
145+
OPENMP_ATOMIC_FAIL_MODIFIER(seq_cst)
146+
OPENMP_ATOMIC_FAIL_MODIFIER(acquire)
147+
OPENMP_ATOMIC_FAIL_MODIFIER(acq_rel)
148+
OPENMP_ATOMIC_FAIL_MODIFIER(relaxed)
149+
OPENMP_ATOMIC_FAIL_MODIFIER(release)
150+
141151
// Modifiers for 'at' clause.
142152
OPENMP_AT_KIND(compilation)
143153
OPENMP_AT_KIND(execution)
@@ -226,6 +236,7 @@ OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration)
226236
#undef OPENMP_SCHEDULE_MODIFIER
227237
#undef OPENMP_SCHEDULE_KIND
228238
#undef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND
239+
#undef OPENMP_ATOMIC_FAIL_MODIFIER
229240
#undef OPENMP_AT_KIND
230241
#undef OPENMP_SEVERITY_KIND
231242
#undef OPENMP_MAP_KIND

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12186,6 +12186,13 @@ class Sema final {
1218612186
/// Called on well-formed 'compare' clause.
1218712187
OMPClause *ActOnOpenMPCompareClause(SourceLocation StartLoc,
1218812188
SourceLocation EndLoc);
12189+
/// Called on well-formed 'fail' clause.
12190+
OMPClause *ActOnOpenMPFailClause(SourceLocation StartLoc,
12191+
SourceLocation EndLoc);
12192+
OMPClause *ActOnOpenMPFailClause(
12193+
OpenMPClauseKind Kind, SourceLocation KindLoc,
12194+
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
12195+
1218912196
/// Called on well-formed 'seq_cst' clause.
1219012197
OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
1219112198
SourceLocation EndLoc);

clang/lib/AST/OpenMPClause.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
130130
case OMPC_update:
131131
case OMPC_capture:
132132
case OMPC_compare:
133+
case OMPC_fail:
133134
case OMPC_seq_cst:
134135
case OMPC_acq_rel:
135136
case OMPC_acquire:
@@ -227,6 +228,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
227228
case OMPC_update:
228229
case OMPC_capture:
229230
case OMPC_compare:
231+
case OMPC_fail:
230232
case OMPC_seq_cst:
231233
case OMPC_acq_rel:
232234
case OMPC_acquire:
@@ -1925,6 +1927,16 @@ void OMPClausePrinter::VisitOMPCompareClause(OMPCompareClause *) {
19251927
OS << "compare";
19261928
}
19271929

1930+
void OMPClausePrinter::VisitOMPFailClause(OMPFailClause *Node) {
1931+
OS << "fail";
1932+
if (Node) {
1933+
OS << "(";
1934+
OS << getOpenMPSimpleClauseTypeName(
1935+
Node->getClauseKind(), static_cast<int>(Node->getFailParameter()));
1936+
OS << ")";
1937+
}
1938+
}
1939+
19281940
void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
19291941
OS << "seq_cst";
19301942
}

clang/lib/AST/StmtProfile.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,8 @@ void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {}
582582

583583
void OMPClauseProfiler::VisitOMPCompareClause(const OMPCompareClause *) {}
584584

585+
void OMPClauseProfiler::VisitOMPFailClause(const OMPFailClause *) {}
586+
585587
void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
586588

587589
void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}

clang/lib/Basic/OpenMPKinds.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
104104
.Case(#Name, OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name)
105105
#include "clang/Basic/OpenMPKinds.def"
106106
.Default(OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown);
107+
case OMPC_fail:
108+
return static_cast<unsigned int>(llvm::StringSwitch<llvm::omp::Clause>(Str)
109+
#define OPENMP_ATOMIC_FAIL_MODIFIER(Name) .Case(#Name, OMPC_##Name)
110+
#include "clang/Basic/OpenMPKinds.def"
111+
.Default(OMPC_unknown));
107112
case OMPC_device_type:
108113
return llvm::StringSwitch<OpenMPDeviceType>(Str)
109114
#define OPENMP_DEVICE_TYPE_KIND(Name) .Case(#Name, OMPC_DEVICE_TYPE_##Name)
@@ -434,6 +439,18 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
434439
#include "clang/Basic/OpenMPKinds.def"
435440
}
436441
llvm_unreachable("Invalid OpenMP 'depend' clause type");
442+
case OMPC_fail: {
443+
OpenMPClauseKind CK = static_cast<OpenMPClauseKind>(Type);
444+
switch (CK) {
445+
case OMPC_unknown:
446+
return "unknown";
447+
#define OPENMP_ATOMIC_FAIL_MODIFIER(Name) \
448+
case OMPC_##Name: \
449+
return #Name;
450+
#include "clang/Basic/OpenMPKinds.def"
451+
}
452+
llvm_unreachable("Invalid OpenMP 'fail' clause modifier");
453+
}
437454
case OMPC_device:
438455
switch (Type) {
439456
case OMPC_DEVICE_unknown:

clang/lib/CodeGen/CGStmtOpenMP.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6516,6 +6516,10 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
65166516
IsPostfixUpdate, IsFailOnly, Loc);
65176517
break;
65186518
}
6519+
case OMPC_fail: {
6520+
//TODO
6521+
break;
6522+
}
65196523
default:
65206524
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
65216525
}

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3248,6 +3248,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
32483248
else
32493249
Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
32503250
break;
3251+
case OMPC_fail:
32513252
case OMPC_default:
32523253
case OMPC_proc_bind:
32533254
case OMPC_atomic_default_mem_order:

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12682,6 +12682,23 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
1268212682
}
1268312683
break;
1268412684
}
12685+
case OMPC_fail: {
12686+
if (AtomicKind != OMPC_compare) {
12687+
Diag(C->getBeginLoc(), diag::err_omp_atomic_fail_no_compare)
12688+
<< SourceRange(C->getBeginLoc(), C->getEndLoc());
12689+
return StmtError();
12690+
}
12691+
const auto *FC = cast<OMPFailClause>(C);
12692+
OpenMPClauseKind FailParameter = FC->getFailParameter();
12693+
SourceLocation DisplayLocation = FailParameter == OMPC_unknown
12694+
? FC->getBeginLoc()
12695+
: FC->getFailParameterLoc();
12696+
if (FailParameter != OMPC_acq_rel && FailParameter != OMPC_acquire &&
12697+
FailParameter != OMPC_relaxed && FailParameter != OMPC_release &&
12698+
FailParameter != OMPC_seq_cst)
12699+
Diag(DisplayLocation, diag::err_omp_atomic_fail_wrong_or_no_clauses);
12700+
break;
12701+
}
1268512702
case OMPC_seq_cst:
1268612703
case OMPC_acq_rel:
1268712704
case OMPC_acquire:
@@ -16883,6 +16900,11 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
1688316900
static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
1688416901
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
1688516902
break;
16903+
case OMPC_fail:
16904+
Res = ActOnOpenMPFailClause(
16905+
static_cast<OpenMPClauseKind>(Argument),
16906+
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16907+
break;
1688616908
case OMPC_update:
1688716909
Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
1688816910
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
@@ -17523,6 +17545,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
1752317545
case OMPC_compare:
1752417546
Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
1752517547
break;
17548+
case OMPC_fail:
17549+
Res = ActOnOpenMPFailClause(StartLoc, EndLoc);
17550+
break;
1752617551
case OMPC_seq_cst:
1752717552
Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
1752817553
break;
@@ -17683,6 +17708,20 @@ OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc,
1768317708
return new (Context) OMPCompareClause(StartLoc, EndLoc);
1768417709
}
1768517710

17711+
OMPClause *Sema::ActOnOpenMPFailClause(SourceLocation StartLoc,
17712+
SourceLocation EndLoc) {
17713+
return new (Context) OMPFailClause(StartLoc, EndLoc);
17714+
}
17715+
17716+
OMPClause *Sema::ActOnOpenMPFailClause(
17717+
OpenMPClauseKind Parameter, SourceLocation KindLoc,
17718+
SourceLocation StartLoc, SourceLocation LParenLoc,
17719+
SourceLocation EndLoc) {
17720+
17721+
return new (Context)
17722+
OMPFailClause(Parameter, KindLoc, StartLoc, LParenLoc, EndLoc);
17723+
}
17724+
1768617725
OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
1768717726
SourceLocation EndLoc) {
1768817727
return new (Context) OMPSeqCstClause(StartLoc, EndLoc);

clang/lib/Sema/TreeTransform.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9866,6 +9866,12 @@ TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
98669866
return C;
98679867
}
98689868

9869+
template <typename Derived>
9870+
OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
9871+
// No need to rebuild this clause, no template-dependent parameters.
9872+
return C;
9873+
}
9874+
98699875
template <typename Derived>
98709876
OMPClause *
98719877
TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {

clang/lib/Serialization/ASTReader.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10274,6 +10274,9 @@ OMPClause *OMPClauseReader::readClause() {
1027410274
case llvm::omp::OMPC_compare:
1027510275
C = new (Context) OMPCompareClause();
1027610276
break;
10277+
case llvm::omp::OMPC_fail:
10278+
C = new (Context) OMPFailClause();
10279+
break;
1027710280
case llvm::omp::OMPC_seq_cst:
1027810281
C = new (Context) OMPSeqCstClause();
1027910282
break;
@@ -10667,6 +10670,16 @@ void OMPClauseReader::VisitOMPCaptureClause(OMPCaptureClause *) {}
1066710670

1066810671
void OMPClauseReader::VisitOMPCompareClause(OMPCompareClause *) {}
1066910672

10673+
// Read the parameter of fail clause. This will have been saved when
10674+
// OMPClauseWriter is called.
10675+
void OMPClauseReader::VisitOMPFailClause(OMPFailClause *C) {
10676+
C->setLParenLoc(Record.readSourceLocation());
10677+
SourceLocation FailParameterLoc = Record.readSourceLocation();
10678+
C->setFailParameterLoc(FailParameterLoc);
10679+
OpenMPClauseKind CKind = Record.readEnum<OpenMPClauseKind>();
10680+
C->setFailParameter(CKind);
10681+
}
10682+
1067010683
void OMPClauseReader::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
1067110684

1067210685
void OMPClauseReader::VisitOMPAcqRelClause(OMPAcqRelClause *) {}

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6620,6 +6620,13 @@ void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {}
66206620

66216621
void OMPClauseWriter::VisitOMPCompareClause(OMPCompareClause *) {}
66226622

6623+
// Save the parameter of fail clause.
6624+
void OMPClauseWriter::VisitOMPFailClause(OMPFailClause *C) {
6625+
Record.AddSourceLocation(C->getLParenLoc());
6626+
Record.AddSourceLocation(C->getFailParameterLoc());
6627+
Record.writeEnum(C->getFailParameter());
6628+
}
6629+
66236630
void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
66246631

66256632
void OMPClauseWriter::VisitOMPAcqRelClause(OMPAcqRelClause *) {}

0 commit comments

Comments
 (0)