Skip to content

Commit

Permalink
[OPENMP] Add support for OMP5 requires directive + unified_address cl…
Browse files Browse the repository at this point in the history
…ause

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
  • Loading branch information
kkwli committed Sep 26, 2018
1 parent 55321d8 commit 1408f91
Show file tree
Hide file tree
Showing 35 changed files with 483 additions and 3 deletions.
71 changes: 71 additions & 0 deletions clang/include/clang/AST/DeclOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/TrailingObjects.h"
Expand Down Expand Up @@ -239,6 +240,76 @@ class OMPCapturedExprDecl final : public VarDecl {
static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
};

/// This represents '#pragma omp requires...' directive.
/// For example
///
/// \code
/// #pragma omp requires unified_address
/// \endcode
///
class OMPRequiresDecl final
: public Decl,
private llvm::TrailingObjects<OMPRequiresDecl, OMPClause *> {
friend class ASTDeclReader;
friend TrailingObjects;

// Number of clauses associated with this requires declaration
unsigned NumClauses = 0;

virtual void anchor();

OMPRequiresDecl(Kind DK, DeclContext *DC, SourceLocation L)
: Decl(DK, DC, L), NumClauses(0) {}

/// Returns an array of immutable clauses associated with this requires
/// declaration
ArrayRef<const OMPClause *> getClauses() const {
return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
}

/// Returns an array of clauses associated with this requires declaration
MutableArrayRef<OMPClause *> getClauses() {
return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
NumClauses);
}

/// Sets an array of clauses to this requires declaration
void setClauses(ArrayRef<OMPClause *> CL);

public:
/// Create requires node.
static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, ArrayRef<OMPClause *> CL);
/// Create deserialized requires node.
static OMPRequiresDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned N);

using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
using clauselist_range = llvm::iterator_range<clauselist_iterator>;
using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;

unsigned clauselist_size() const { return NumClauses; }
bool clauselist_empty() const { return NumClauses == 0; }

clauselist_range clauselists() {
return clauselist_range(clauselist_begin(), clauselist_end());
}
clauselist_const_range clauselists() const {
return clauselist_const_range(clauselist_begin(), clauselist_end());
}
clauselist_iterator clauselist_begin() { return getClauses().begin(); }
clauselist_iterator clauselist_end() { return getClauses().end(); }
clauselist_const_iterator clauselist_begin() const {
return getClauses().begin();
}
clauselist_const_iterator clauselist_end() const {
return getClauses().end();
}

static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == OMPRequires; }
};
} // end namespace clang

#endif
31 changes: 31 additions & 0 deletions clang/include/clang/AST/OpenMPClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,37 @@ class OMPProcBindClause : public OMPClause {
}
};

/// This represents 'unified_address' clause in the '#pragma omp requires'
/// directive.
///
/// \code
/// #pragma omp requires unified_address
/// \endcode
/// In this example directive '#pragma omp requires' has 'unified_address'
/// clause.
class OMPUnifiedAddressClause final : public OMPClause {
public:
friend class OMPClauseReader;
/// Build 'unified_address' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_unified_address, StartLoc, EndLoc) {}

/// Build an empty clause.
OMPUnifiedAddressClause()
: OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {}

child_range children() {
return child_range(child_iterator(), child_iterator());
}

static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_unified_address;
}
};

/// This represents 'schedule' clause in the '#pragma omp ...' directive.
///
/// \code
Expand Down
12 changes: 12 additions & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,12 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
for (auto *I : D->varlists()) {
TRY_TO(TraverseStmt(I));
}
})

DEF_TRAVERSE_DECL(OMPRequiresDecl, {
for (auto *C : D->clauselists()) {
TRY_TO(TraverseOMPClause(C));
}
})

DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, {
Expand Down Expand Up @@ -2853,6 +2859,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
return true;
}

template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedAddressClause(
OMPUnifiedAddressClause *) {
return true;
}

template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/DeclNodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,6 @@ def Captured : Decl, DeclContext;
def ClassScopeFunctionSpecialization : Decl;
def Import : Decl;
def OMPThreadPrivate : Decl;
def OMPRequires : Decl;
def Empty : Decl;

2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,8 @@ def err_expected_end_declare_target : Error<
"expected '#pragma omp end declare target'">;
def err_omp_declare_target_unexpected_clause: Error<
"unexpected '%0' clause, only 'to' or 'link' clauses expected">;
def err_omp_expected_clause: Error<
"expected at least one clause on '#pragma omp %0' directive">;

// Pragma loop support.
def err_pragma_loop_missing_argument : Error<
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -9073,6 +9073,12 @@ def err_omp_linear_distribute_var_non_loop_iteration : Error<
def warn_omp_non_trivial_type_mapped : Warning<
"Non-trivial type %0 is mapped, only trivial types are guaranteed to be mapped correctly">,
InGroup<OpenMPTarget>;
def err_omp_requires_clause_redeclaration : Error <
"Only one %0 clause can appear on a requires directive in a single translation unit">;
def note_omp_requires_previous_clause : Note <
"%0 clause previously used here">;
def err_omp_invalid_scope : Error <
"'#pragma omp %0' directive must appear only in file scope">;
} // end of OpenMP category

let CategoryName = "Related Result Type Issue" in {
Expand Down
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/OpenMPKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@
#ifndef OPENMP_TARGET_CLAUSE
# define OPENMP_TARGET_CLAUSE(Name)
#endif
#ifndef OPENMP_REQUIRES_CLAUSE
# define OPENMP_REQUIRES_CLAUSE(Name)
#endif
#ifndef OPENMP_TARGET_DATA_CLAUSE
# define OPENMP_TARGET_DATA_CLAUSE(Name)
#endif
Expand Down Expand Up @@ -193,6 +196,7 @@ OPENMP_DIRECTIVE(atomic)
OPENMP_DIRECTIVE(target)
OPENMP_DIRECTIVE(teams)
OPENMP_DIRECTIVE(cancel)
OPENMP_DIRECTIVE(requires)
OPENMP_DIRECTIVE_EXT(target_data, "target data")
OPENMP_DIRECTIVE_EXT(target_enter_data, "target enter data")
OPENMP_DIRECTIVE_EXT(target_exit_data, "target exit data")
Expand Down Expand Up @@ -275,6 +279,7 @@ OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause)
OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause)
OPENMP_CLAUSE(task_reduction, OMPTaskReductionClause)
OPENMP_CLAUSE(in_reduction, OMPInReductionClause)
OPENMP_CLAUSE(unified_address, OMPUnifiedAddressClause)

// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
Expand Down Expand Up @@ -456,6 +461,9 @@ OPENMP_TARGET_CLAUSE(firstprivate)
OPENMP_TARGET_CLAUSE(is_device_ptr)
OPENMP_TARGET_CLAUSE(reduction)

// Clauses allowed for OpenMP directive 'requires'.
OPENMP_REQUIRES_CLAUSE(unified_address)

// Clauses allowed for OpenMP directive 'target data'.
OPENMP_TARGET_DATA_CLAUSE(if)
OPENMP_TARGET_DATA_CLAUSE(device)
Expand Down Expand Up @@ -883,6 +891,7 @@ OPENMP_TASKGROUP_CLAUSE(task_reduction)
#undef OPENMP_TASK_CLAUSE
#undef OPENMP_ATOMIC_CLAUSE
#undef OPENMP_TARGET_CLAUSE
#undef OPENMP_REQUIRES_CLAUSE
#undef OPENMP_TARGET_DATA_CLAUSE
#undef OPENMP_TARGET_ENTER_DATA_CLAUSE
#undef OPENMP_TARGET_EXIT_DATA_CLAUSE
Expand Down
12 changes: 11 additions & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ namespace clang {
class ObjCPropertyDecl;
class ObjCProtocolDecl;
class OMPThreadPrivateDecl;
class OMPRequiresDecl;
class OMPDeclareReductionDecl;
class OMPDeclareSimdDecl;
class OMPClause;
Expand Down Expand Up @@ -8714,6 +8715,12 @@ class Sema {
/// Builds a new OpenMPThreadPrivateDecl and checks its correctness.
OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(SourceLocation Loc,
ArrayRef<Expr *> VarList);
/// Called on well-formed '#pragma omp requires'.
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc,
ArrayRef<OMPClause *> ClauseList);
/// Check restrictions on Requires directive
OMPRequiresDecl *CheckOMPRequiresDecl(SourceLocation Loc,
ArrayRef<OMPClause *> Clauses);
/// Check if the specified type is allowed to be used in 'omp declare
/// reduction' construct.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
Expand Down Expand Up @@ -9107,7 +9114,7 @@ class Sema {
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);

OMPClause *ActOnOpenMPSingleExprWithArgClause(
OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr,
SourceLocation StartLoc, SourceLocation LParenLoc,
Expand Down Expand Up @@ -9155,6 +9162,9 @@ class Sema {
/// Called on well-formed 'nogroup' clause.
OMPClause *ActOnOpenMPNogroupClause(SourceLocation StartLoc,
SourceLocation EndLoc);
/// Called on well-formed 'unified_address' clause.
OMPClause *ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
SourceLocation EndLoc);

OMPClause *ActOnOpenMPVarListClause(
OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr,
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1516,6 +1516,9 @@ namespace serialization {
/// An OMPThreadPrivateDecl record.
DECL_OMP_THREADPRIVATE,

/// An OMPRequiresDecl record.
DECL_OMP_REQUIRES,

/// An EmptyDecl record.
DECL_EMPTY,

Expand Down
21 changes: 21 additions & 0 deletions clang/lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ namespace {
// OpenMP decls
void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D);
void VisitOMPRequiresDecl(const OMPRequiresDecl *D);
void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D);

// C++ Decls
Expand Down Expand Up @@ -1340,6 +1341,26 @@ void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
}
}

void ASTDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
for (auto *C : D->clauselists()) {
dumpChild([=] {
if (!C) {
ColorScope Color(*this, NullColor);
OS << "<<<NULL>>> OMPClause";
return;
}
{
ColorScope Color(*this, AttrColor);
StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
<< ClauseName.drop_front() << "Clause";
}
dumpPointer(C);
dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
});
}
}

void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
dumpName(D);
dumpType(D->getType());
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/DeclBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ObjCCategoryImpl:
case Import:
case OMPThreadPrivate:
case OMPRequires:
case OMPCapturedExpr:
case Empty:
// Never looked up by name.
Expand Down
32 changes: 32 additions & 0 deletions clang/lib/AST/DeclOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,38 @@ void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) {
std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
}

//===----------------------------------------------------------------------===//
// OMPRequiresDecl Implementation.
//===----------------------------------------------------------------------===//

void OMPRequiresDecl::anchor() {}

OMPRequiresDecl *OMPRequiresDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
ArrayRef<OMPClause *> CL) {
OMPRequiresDecl *D =
new (C, DC, additionalSizeToAlloc<OMPClause *>(CL.size()))
OMPRequiresDecl(OMPRequires, DC, L);
D->NumClauses = CL.size();
D->setClauses(CL);
return D;
}

OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned N) {
OMPRequiresDecl *D = new (C, ID, additionalSizeToAlloc<OMPClause *>(N))
OMPRequiresDecl(OMPRequires, nullptr, SourceLocation());
D->NumClauses = N;
return D;
}

void OMPRequiresDecl::setClauses(ArrayRef<OMPClause *> CL) {
assert(CL.size() == NumClauses &&
"Number of clauses is not the same as the preallocated buffer");
std::uninitialized_copy(CL.begin(), CL.end(),
getTrailingObjects<OMPClause *>());
}

//===----------------------------------------------------------------------===//
// OMPDeclareReductionDecl Implementation.
//===----------------------------------------------------------------------===//
Expand Down
15 changes: 14 additions & 1 deletion clang/lib/AST/DeclPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ namespace {
void VisitUsingDecl(UsingDecl *D);
void VisitUsingShadowDecl(UsingShadowDecl *D);
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
void VisitOMPRequiresDecl(OMPRequiresDecl *D);
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);

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

// FIXME: Need to be able to tell the DeclPrinter when
const char *Terminator = nullptr;
if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D))
if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D) ||
isa<OMPRequiresDecl>(*D))
Terminator = nullptr;
else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody())
Terminator = nullptr;
Expand Down Expand Up @@ -1544,6 +1546,17 @@ void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
}
}

void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
Out << "#pragma omp requires ";
if (!D->clauselist_empty()) {
for (auto I = D->clauselist_begin(), E = D->clauselist_end(); I != E; ++I) {
if (I != D->clauselist_begin())
Out << ',';
Out << getOpenMPClauseName((*I)->getClauseKind());
}
}
}

void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
if (!D->isInvalidDecl()) {
Out << "#pragma omp declare reduction (";
Expand Down

0 comments on commit 1408f91

Please sign in to comment.