Skip to content

Commit 1408f91

Browse files
committedSep 26, 2018
[OPENMP] Add support for OMP5 requires directive + unified_address clause
Add support for OMP5.0 requires directive and unified_address clause. Patches to follow will include support for additional clauses. Differential Revision: https://reviews.llvm.org/D52359 llvm-svn: 343063
1 parent 55321d8 commit 1408f91

35 files changed

+483
-3
lines changed
 

‎clang/include/clang/AST/DeclOpenMP.h

+71
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/AST/Decl.h"
1919
#include "clang/AST/Expr.h"
2020
#include "clang/AST/ExternalASTSource.h"
21+
#include "clang/AST/OpenMPClause.h"
2122
#include "clang/AST/Type.h"
2223
#include "llvm/ADT/ArrayRef.h"
2324
#include "llvm/Support/TrailingObjects.h"
@@ -239,6 +240,76 @@ class OMPCapturedExprDecl final : public VarDecl {
239240
static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
240241
};
241242

243+
/// This represents '#pragma omp requires...' directive.
244+
/// For example
245+
///
246+
/// \code
247+
/// #pragma omp requires unified_address
248+
/// \endcode
249+
///
250+
class OMPRequiresDecl final
251+
: public Decl,
252+
private llvm::TrailingObjects<OMPRequiresDecl, OMPClause *> {
253+
friend class ASTDeclReader;
254+
friend TrailingObjects;
255+
256+
// Number of clauses associated with this requires declaration
257+
unsigned NumClauses = 0;
258+
259+
virtual void anchor();
260+
261+
OMPRequiresDecl(Kind DK, DeclContext *DC, SourceLocation L)
262+
: Decl(DK, DC, L), NumClauses(0) {}
263+
264+
/// Returns an array of immutable clauses associated with this requires
265+
/// declaration
266+
ArrayRef<const OMPClause *> getClauses() const {
267+
return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
268+
}
269+
270+
/// Returns an array of clauses associated with this requires declaration
271+
MutableArrayRef<OMPClause *> getClauses() {
272+
return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
273+
NumClauses);
274+
}
275+
276+
/// Sets an array of clauses to this requires declaration
277+
void setClauses(ArrayRef<OMPClause *> CL);
278+
279+
public:
280+
/// Create requires node.
281+
static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC,
282+
SourceLocation L, ArrayRef<OMPClause *> CL);
283+
/// Create deserialized requires node.
284+
static OMPRequiresDecl *CreateDeserialized(ASTContext &C, unsigned ID,
285+
unsigned N);
286+
287+
using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
288+
using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
289+
using clauselist_range = llvm::iterator_range<clauselist_iterator>;
290+
using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
291+
292+
unsigned clauselist_size() const { return NumClauses; }
293+
bool clauselist_empty() const { return NumClauses == 0; }
294+
295+
clauselist_range clauselists() {
296+
return clauselist_range(clauselist_begin(), clauselist_end());
297+
}
298+
clauselist_const_range clauselists() const {
299+
return clauselist_const_range(clauselist_begin(), clauselist_end());
300+
}
301+
clauselist_iterator clauselist_begin() { return getClauses().begin(); }
302+
clauselist_iterator clauselist_end() { return getClauses().end(); }
303+
clauselist_const_iterator clauselist_begin() const {
304+
return getClauses().begin();
305+
}
306+
clauselist_const_iterator clauselist_end() const {
307+
return getClauses().end();
308+
}
309+
310+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
311+
static bool classofKind(Kind K) { return K == OMPRequires; }
312+
};
242313
} // end namespace clang
243314

244315
#endif

‎clang/include/clang/AST/OpenMPClause.h

+31
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,37 @@ class OMPProcBindClause : public OMPClause {
734734
}
735735
};
736736

737+
/// This represents 'unified_address' clause in the '#pragma omp requires'
738+
/// directive.
739+
///
740+
/// \code
741+
/// #pragma omp requires unified_address
742+
/// \endcode
743+
/// In this example directive '#pragma omp requires' has 'unified_address'
744+
/// clause.
745+
class OMPUnifiedAddressClause final : public OMPClause {
746+
public:
747+
friend class OMPClauseReader;
748+
/// Build 'unified_address' clause.
749+
///
750+
/// \param StartLoc Starting location of the clause.
751+
/// \param EndLoc Ending location of the clause.
752+
OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
753+
: OMPClause(OMPC_unified_address, StartLoc, EndLoc) {}
754+
755+
/// Build an empty clause.
756+
OMPUnifiedAddressClause()
757+
: OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {}
758+
759+
child_range children() {
760+
return child_range(child_iterator(), child_iterator());
761+
}
762+
763+
static bool classof(const OMPClause *T) {
764+
return T->getClauseKind() == OMPC_unified_address;
765+
}
766+
};
767+
737768
/// This represents 'schedule' clause in the '#pragma omp ...' directive.
738769
///
739770
/// \code

‎clang/include/clang/AST/RecursiveASTVisitor.h

+12
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,12 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
15891589
for (auto *I : D->varlists()) {
15901590
TRY_TO(TraverseStmt(I));
15911591
}
1592+
})
1593+
1594+
DEF_TRAVERSE_DECL(OMPRequiresDecl, {
1595+
for (auto *C : D->clauselists()) {
1596+
TRY_TO(TraverseOMPClause(C));
1597+
}
15921598
})
15931599

15941600
DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, {
@@ -2853,6 +2859,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
28532859
return true;
28542860
}
28552861

2862+
template <typename Derived>
2863+
bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedAddressClause(
2864+
OMPUnifiedAddressClause *) {
2865+
return true;
2866+
}
2867+
28562868
template <typename Derived>
28572869
bool
28582870
RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {

‎clang/include/clang/Basic/DeclNodes.td

+1
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,6 @@ def Captured : Decl, DeclContext;
9797
def ClassScopeFunctionSpecialization : Decl;
9898
def Import : Decl;
9999
def OMPThreadPrivate : Decl;
100+
def OMPRequires : Decl;
100101
def Empty : Decl;
101102

‎clang/include/clang/Basic/DiagnosticParseKinds.td

+2
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,8 @@ def err_expected_end_declare_target : Error<
11251125
"expected '#pragma omp end declare target'">;
11261126
def err_omp_declare_target_unexpected_clause: Error<
11271127
"unexpected '%0' clause, only 'to' or 'link' clauses expected">;
1128+
def err_omp_expected_clause: Error<
1129+
"expected at least one clause on '#pragma omp %0' directive">;
11281130

11291131
// Pragma loop support.
11301132
def err_pragma_loop_missing_argument : Error<

‎clang/include/clang/Basic/DiagnosticSemaKinds.td

+6
Original file line numberDiff line numberDiff line change
@@ -9073,6 +9073,12 @@ def err_omp_linear_distribute_var_non_loop_iteration : Error<
90739073
def warn_omp_non_trivial_type_mapped : Warning<
90749074
"Non-trivial type %0 is mapped, only trivial types are guaranteed to be mapped correctly">,
90759075
InGroup<OpenMPTarget>;
9076+
def err_omp_requires_clause_redeclaration : Error <
9077+
"Only one %0 clause can appear on a requires directive in a single translation unit">;
9078+
def note_omp_requires_previous_clause : Note <
9079+
"%0 clause previously used here">;
9080+
def err_omp_invalid_scope : Error <
9081+
"'#pragma omp %0' directive must appear only in file scope">;
90769082
} // end of OpenMP category
90779083

90789084
let CategoryName = "Related Result Type Issue" in {

‎clang/include/clang/Basic/OpenMPKinds.def

+9
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
#ifndef OPENMP_TARGET_CLAUSE
5858
# define OPENMP_TARGET_CLAUSE(Name)
5959
#endif
60+
#ifndef OPENMP_REQUIRES_CLAUSE
61+
# define OPENMP_REQUIRES_CLAUSE(Name)
62+
#endif
6063
#ifndef OPENMP_TARGET_DATA_CLAUSE
6164
# define OPENMP_TARGET_DATA_CLAUSE(Name)
6265
#endif
@@ -193,6 +196,7 @@ OPENMP_DIRECTIVE(atomic)
193196
OPENMP_DIRECTIVE(target)
194197
OPENMP_DIRECTIVE(teams)
195198
OPENMP_DIRECTIVE(cancel)
199+
OPENMP_DIRECTIVE(requires)
196200
OPENMP_DIRECTIVE_EXT(target_data, "target data")
197201
OPENMP_DIRECTIVE_EXT(target_enter_data, "target enter data")
198202
OPENMP_DIRECTIVE_EXT(target_exit_data, "target exit data")
@@ -275,6 +279,7 @@ OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause)
275279
OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause)
276280
OPENMP_CLAUSE(task_reduction, OMPTaskReductionClause)
277281
OPENMP_CLAUSE(in_reduction, OMPInReductionClause)
282+
OPENMP_CLAUSE(unified_address, OMPUnifiedAddressClause)
278283

279284
// Clauses allowed for OpenMP directive 'parallel'.
280285
OPENMP_PARALLEL_CLAUSE(if)
@@ -456,6 +461,9 @@ OPENMP_TARGET_CLAUSE(firstprivate)
456461
OPENMP_TARGET_CLAUSE(is_device_ptr)
457462
OPENMP_TARGET_CLAUSE(reduction)
458463

464+
// Clauses allowed for OpenMP directive 'requires'.
465+
OPENMP_REQUIRES_CLAUSE(unified_address)
466+
459467
// Clauses allowed for OpenMP directive 'target data'.
460468
OPENMP_TARGET_DATA_CLAUSE(if)
461469
OPENMP_TARGET_DATA_CLAUSE(device)
@@ -883,6 +891,7 @@ OPENMP_TASKGROUP_CLAUSE(task_reduction)
883891
#undef OPENMP_TASK_CLAUSE
884892
#undef OPENMP_ATOMIC_CLAUSE
885893
#undef OPENMP_TARGET_CLAUSE
894+
#undef OPENMP_REQUIRES_CLAUSE
886895
#undef OPENMP_TARGET_DATA_CLAUSE
887896
#undef OPENMP_TARGET_ENTER_DATA_CLAUSE
888897
#undef OPENMP_TARGET_EXIT_DATA_CLAUSE

‎clang/include/clang/Sema/Sema.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ namespace clang {
153153
class ObjCPropertyDecl;
154154
class ObjCProtocolDecl;
155155
class OMPThreadPrivateDecl;
156+
class OMPRequiresDecl;
156157
class OMPDeclareReductionDecl;
157158
class OMPDeclareSimdDecl;
158159
class OMPClause;
@@ -8714,6 +8715,12 @@ class Sema {
87148715
/// Builds a new OpenMPThreadPrivateDecl and checks its correctness.
87158716
OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(SourceLocation Loc,
87168717
ArrayRef<Expr *> VarList);
8718+
/// Called on well-formed '#pragma omp requires'.
8719+
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc,
8720+
ArrayRef<OMPClause *> ClauseList);
8721+
/// Check restrictions on Requires directive
8722+
OMPRequiresDecl *CheckOMPRequiresDecl(SourceLocation Loc,
8723+
ArrayRef<OMPClause *> Clauses);
87178724
/// Check if the specified type is allowed to be used in 'omp declare
87188725
/// reduction' construct.
87198726
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
@@ -9107,7 +9114,7 @@ class Sema {
91079114
SourceLocation StartLoc,
91089115
SourceLocation LParenLoc,
91099116
SourceLocation EndLoc);
9110-
9117+
91119118
OMPClause *ActOnOpenMPSingleExprWithArgClause(
91129119
OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr,
91139120
SourceLocation StartLoc, SourceLocation LParenLoc,
@@ -9155,6 +9162,9 @@ class Sema {
91559162
/// Called on well-formed 'nogroup' clause.
91569163
OMPClause *ActOnOpenMPNogroupClause(SourceLocation StartLoc,
91579164
SourceLocation EndLoc);
9165+
/// Called on well-formed 'unified_address' clause.
9166+
OMPClause *ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
9167+
SourceLocation EndLoc);
91589168

91599169
OMPClause *ActOnOpenMPVarListClause(
91609170
OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr,

‎clang/include/clang/Serialization/ASTBitCodes.h

+3
Original file line numberDiff line numberDiff line change
@@ -1516,6 +1516,9 @@ namespace serialization {
15161516
/// An OMPThreadPrivateDecl record.
15171517
DECL_OMP_THREADPRIVATE,
15181518

1519+
/// An OMPRequiresDecl record.
1520+
DECL_OMP_REQUIRES,
1521+
15191522
/// An EmptyDecl record.
15201523
DECL_EMPTY,
15211524

‎clang/lib/AST/ASTDumper.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ namespace {
450450
// OpenMP decls
451451
void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
452452
void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D);
453+
void VisitOMPRequiresDecl(const OMPRequiresDecl *D);
453454
void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D);
454455

455456
// C++ Decls
@@ -1340,6 +1341,26 @@ void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
13401341
}
13411342
}
13421343

1344+
void ASTDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
1345+
for (auto *C : D->clauselists()) {
1346+
dumpChild([=] {
1347+
if (!C) {
1348+
ColorScope Color(*this, NullColor);
1349+
OS << "<<<NULL>>> OMPClause";
1350+
return;
1351+
}
1352+
{
1353+
ColorScope Color(*this, AttrColor);
1354+
StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
1355+
OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
1356+
<< ClauseName.drop_front() << "Clause";
1357+
}
1358+
dumpPointer(C);
1359+
dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
1360+
});
1361+
}
1362+
}
1363+
13431364
void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
13441365
dumpName(D);
13451366
dumpType(D->getType());

‎clang/lib/AST/DeclBase.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
810810
case ObjCCategoryImpl:
811811
case Import:
812812
case OMPThreadPrivate:
813+
case OMPRequires:
813814
case OMPCapturedExpr:
814815
case Empty:
815816
// Never looked up by name.

‎clang/lib/AST/DeclOpenMP.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,38 @@ void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) {
5353
std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
5454
}
5555

56+
//===----------------------------------------------------------------------===//
57+
// OMPRequiresDecl Implementation.
58+
//===----------------------------------------------------------------------===//
59+
60+
void OMPRequiresDecl::anchor() {}
61+
62+
OMPRequiresDecl *OMPRequiresDecl::Create(ASTContext &C, DeclContext *DC,
63+
SourceLocation L,
64+
ArrayRef<OMPClause *> CL) {
65+
OMPRequiresDecl *D =
66+
new (C, DC, additionalSizeToAlloc<OMPClause *>(CL.size()))
67+
OMPRequiresDecl(OMPRequires, DC, L);
68+
D->NumClauses = CL.size();
69+
D->setClauses(CL);
70+
return D;
71+
}
72+
73+
OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, unsigned ID,
74+
unsigned N) {
75+
OMPRequiresDecl *D = new (C, ID, additionalSizeToAlloc<OMPClause *>(N))
76+
OMPRequiresDecl(OMPRequires, nullptr, SourceLocation());
77+
D->NumClauses = N;
78+
return D;
79+
}
80+
81+
void OMPRequiresDecl::setClauses(ArrayRef<OMPClause *> CL) {
82+
assert(CL.size() == NumClauses &&
83+
"Number of clauses is not the same as the preallocated buffer");
84+
std::uninitialized_copy(CL.begin(), CL.end(),
85+
getTrailingObjects<OMPClause *>());
86+
}
87+
5688
//===----------------------------------------------------------------------===//
5789
// OMPDeclareReductionDecl Implementation.
5890
//===----------------------------------------------------------------------===//

‎clang/lib/AST/DeclPrinter.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ namespace {
100100
void VisitUsingDecl(UsingDecl *D);
101101
void VisitUsingShadowDecl(UsingShadowDecl *D);
102102
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
103+
void VisitOMPRequiresDecl(OMPRequiresDecl *D);
103104
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
104105
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
105106

@@ -422,7 +423,8 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
422423

423424
// FIXME: Need to be able to tell the DeclPrinter when
424425
const char *Terminator = nullptr;
425-
if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D))
426+
if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D) ||
427+
isa<OMPRequiresDecl>(*D))
426428
Terminator = nullptr;
427429
else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody())
428430
Terminator = nullptr;
@@ -1544,6 +1546,17 @@ void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
15441546
}
15451547
}
15461548

1549+
void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
1550+
Out << "#pragma omp requires ";
1551+
if (!D->clauselist_empty()) {
1552+
for (auto I = D->clauselist_begin(), E = D->clauselist_end(); I != E; ++I) {
1553+
if (I != D->clauselist_begin())
1554+
Out << ',';
1555+
Out << getOpenMPClauseName((*I)->getClauseKind());
1556+
}
1557+
}
1558+
}
1559+
15471560
void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
15481561
if (!D->isInvalidDecl()) {
15491562
Out << "#pragma omp declare reduction (";

0 commit comments

Comments
 (0)