Skip to content

Commit

Permalink
[OpenMP] Add parsing/sema/serialization for 'bind' clause.
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D113154
  • Loading branch information
mikerice1969 committed Nov 4, 2021
1 parent 5540e27 commit 4eac7bc
Show file tree
Hide file tree
Showing 19 changed files with 323 additions and 24 deletions.
90 changes: 90 additions & 0 deletions clang/include/clang/AST/OpenMPClause.h
Expand Up @@ -8405,6 +8405,96 @@ class OMPFilterClause final : public OMPClause, public OMPClauseWithPreInit {
}
};

/// This represents 'bind' clause in the '#pragma omp ...' directives.
///
/// \code
/// #pragma omp loop bind(parallel)
/// \endcode
class OMPBindClause final : public OMPClause {
friend class OMPClauseReader;

/// Location of '('.
SourceLocation LParenLoc;

/// The binding kind of 'bind' clause.
OpenMPBindClauseKind Kind = OMPC_BIND_unknown;

/// Start location of the kind in source code.
SourceLocation KindLoc;

/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

/// Set the binding kind.
void setBindKind(OpenMPBindClauseKind K) { Kind = K; }

/// Set the binding kind location.
void setBindKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }

/// Build 'bind' clause with kind \a K ('teams', 'parallel', or 'thread').
///
/// \param K Binding kind of the clause ('teams', 'parallel' or 'thread').
/// \param KLoc Starting location of the binding kind.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
OMPBindClause(OpenMPBindClauseKind K, SourceLocation KLoc,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(llvm::omp::OMPC_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
Kind(K), KindLoc(KLoc) {}

/// Build an empty clause.
OMPBindClause()
: OMPClause(llvm::omp::OMPC_bind, SourceLocation(), SourceLocation()) {}

public:
/// Build 'bind' clause with kind \a K ('teams', 'parallel', or 'thread').
///
/// \param C AST context
/// \param K Binding kind of the clause ('teams', 'parallel' or 'thread').
/// \param KLoc Starting location of the binding kind.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
static OMPBindClause *Create(const ASTContext &C, OpenMPBindClauseKind K,
SourceLocation KLoc, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc);

/// Build an empty 'bind' clause.
///
/// \param C AST context
static OMPBindClause *CreateEmpty(const ASTContext &C);

/// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }

/// Returns kind of the clause.
OpenMPBindClauseKind getBindKind() const { return Kind; }

/// Returns location of clause kind.
SourceLocation getBindKindLoc() const { return KindLoc; }

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

const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}

child_range used_children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range used_children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}

static bool classof(const OMPClause *T) {
return T->getClauseKind() == llvm::omp::OMPC_bind;
}
};

/// This class implements a simple visitor for OMPClause
/// subclasses.
template<class ImplClass, template <typename> class Ptr, typename RetTy>
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Expand Up @@ -3676,6 +3676,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFilterClause(OMPFilterClause *C) {
return true;
}

template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPBindClause(OMPBindClause *C) {
return true;
}

// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods
// returning decls or qualtypes or nestednamespecifier -- though I'm
Expand Down
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/OpenMPKinds.def
Expand Up @@ -62,6 +62,9 @@
#ifndef OPENMP_ADJUST_ARGS_KIND
#define OPENMP_ADJUST_ARGS_KIND(Name)
#endif
#ifndef OPENMP_BIND_KIND
#define OPENMP_BIND_KIND(Name)
#endif

// Static attributes for 'schedule' clause.
OPENMP_SCHEDULE_KIND(static)
Expand Down Expand Up @@ -156,6 +159,12 @@ OPENMP_REDUCTION_MODIFIER(task)
OPENMP_ADJUST_ARGS_KIND(nothing)
OPENMP_ADJUST_ARGS_KIND(need_device_ptr)

// Binding kinds for the 'bind' clause.
OPENMP_BIND_KIND(teams)
OPENMP_BIND_KIND(parallel)
OPENMP_BIND_KIND(thread)

#undef OPENMP_BIND_KIND
#undef OPENMP_ADJUST_ARGS_KIND
#undef OPENMP_REDUCTION_MODIFIER
#undef OPENMP_DEVICE_MODIFIER
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/OpenMPKinds.h
Expand Up @@ -174,6 +174,13 @@ enum OpenMPAdjustArgsOpKind {
OMPC_ADJUST_ARGS_unknown,
};

/// OpenMP bindings for the 'bind' clause.
enum OpenMPBindClauseKind {
#define OPENMP_BIND_KIND(Name) OMPC_BIND_##Name,
#include "clang/Basic/OpenMPKinds.def"
OMPC_BIND_unknown
};

unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str,
const LangOptions &LangOpts);
const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type);
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Sema/Sema.h
Expand Up @@ -11424,6 +11424,12 @@ class Sema final {
SourceLocation ColonLoc,
SourceLocation EndLoc, Expr *Modifier,
ArrayRef<Expr *> Locators);
/// Called on a well-formed 'bind' clause.
OMPClause *ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
SourceLocation KindLoc,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);

/// The kind of conversion being performed.
enum CheckedConversionKind {
Expand Down
18 changes: 18 additions & 0 deletions clang/lib/AST/OpenMPClause.cpp
Expand Up @@ -161,6 +161,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_uses_allocators:
case OMPC_affinity:
case OMPC_when:
case OMPC_bind:
break;
default:
break;
Expand Down Expand Up @@ -259,6 +260,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_uses_allocators:
case OMPC_affinity:
case OMPC_when:
case OMPC_bind:
break;
default:
break;
Expand Down Expand Up @@ -1586,6 +1588,16 @@ OMPInitClause *OMPInitClause::CreateEmpty(const ASTContext &C, unsigned N) {
return new (Mem) OMPInitClause(N);
}

OMPBindClause *
OMPBindClause::Create(const ASTContext &C, OpenMPBindClauseKind K,
SourceLocation KLoc, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc) {
return new (C) OMPBindClause(K, KLoc, StartLoc, LParenLoc, EndLoc);
}

OMPBindClause *OMPBindClause::CreateEmpty(const ASTContext &C) {
return new (C) OMPBindClause();
}
//===----------------------------------------------------------------------===//
// OpenMP clauses printing methods
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -2297,6 +2309,12 @@ void OMPClausePrinter::VisitOMPFilterClause(OMPFilterClause *Node) {
OS << ")";
}

void OMPClausePrinter::VisitOMPBindClause(OMPBindClause *Node) {
OS << "bind("
<< getOpenMPSimpleClauseTypeName(OMPC_bind, unsigned(Node->getBindKind()))
<< ")";
}

void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx,
VariantMatchInfo &VMI) const {
for (const OMPTraitSet &Set : Sets) {
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/StmtProfile.cpp
Expand Up @@ -878,6 +878,7 @@ void OMPClauseProfiler::VisitOMPAffinityClause(const OMPAffinityClause *C) {
Profiler->VisitStmt(E);
}
void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause *C) {}
void OMPClauseProfiler::VisitOMPBindClause(const OMPBindClause *C) {}
} // namespace

void
Expand Down
15 changes: 15 additions & 0 deletions clang/lib/Basic/OpenMPKinds.cpp
Expand Up @@ -130,6 +130,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
#define OPENMP_ADJUST_ARGS_KIND(Name) .Case(#Name, OMPC_ADJUST_ARGS_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_ADJUST_ARGS_unknown);
case OMPC_bind:
return llvm::StringSwitch<unsigned>(Str)
#define OPENMP_BIND_KIND(Name) .Case(#Name, OMPC_BIND_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_BIND_unknown);
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
Expand Down Expand Up @@ -385,6 +390,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'adjust_args' clause kind");
case OMPC_bind:
switch (Type) {
case OMPC_BIND_unknown:
return "unknown";
#define OPENMP_BIND_KIND(Name) \
case OMPC_BIND_##Name: \
return #Name;
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'bind' clause type");
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGStmtOpenMP.cpp
Expand Up @@ -5992,6 +5992,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
case OMPC_adjust_args:
case OMPC_append_args:
case OMPC_memory_order:
case OMPC_bind:
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
}
}
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/Parse/ParseOpenMP.cpp
Expand Up @@ -3056,7 +3056,7 @@ OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
/// clause:
/// if-clause | final-clause | num_threads-clause | safelen-clause |
/// default-clause | private-clause | firstprivate-clause | shared-clause
/// | linear-clause | aligned-clause | collapse-clause |
/// | linear-clause | aligned-clause | collapse-clause | bind-clause |
/// lastprivate-clause | reduction-clause | proc_bind-clause |
/// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
/// mergeable-clause | flush-clause | read-clause | write-clause |
Expand Down Expand Up @@ -3146,6 +3146,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_proc_bind:
case OMPC_atomic_default_mem_order:
case OMPC_order:
case OMPC_bind:
// OpenMP [2.14.3.1, Restrictions]
// Only a single default clause may be specified on a parallel, task or
// teams directive.
Expand All @@ -3154,6 +3155,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
// OpenMP [5.0, Requires directive, Restrictions]
// At most one atomic_default_mem_order clause can appear
// on the directive
// OpenMP 5.1, 2.11.7 loop Construct, Restrictions.
// At most one bind clause can appear on a loop directive.
if (!FirstClause && CKind != OMPC_order) {
Diag(Tok, diag::err_omp_more_one_clause)
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
Expand Down Expand Up @@ -3500,6 +3503,9 @@ OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
/// proc_bind-clause:
/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')'
///
/// bind-clause:
/// 'bind' '(' 'teams' | 'parallel' | 'thread' ')'
///
/// update-clause:
/// 'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' ')'
///
Expand Down
43 changes: 42 additions & 1 deletion clang/lib/Sema/SemaOpenMP.cpp
Expand Up @@ -4687,6 +4687,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
OpenMPDirectiveKind CurrentRegion,
const DeclarationNameInfo &CurrentName,
OpenMPDirectiveKind CancelRegion,
OpenMPBindClauseKind BindKind,
SourceLocation StartLoc) {
if (Stack->getCurScope()) {
OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
Expand Down Expand Up @@ -4897,6 +4898,16 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
CurrentRegion != OMPD_loop;
Recommend = ShouldBeInParallelRegion;
}
if (!NestingProhibited && CurrentRegion == OMPD_loop) {
// OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
// If the bind clause is present on the loop construct and binding is
// teams then the corresponding loop region must be strictly nested inside
// a teams region.
NestingProhibited = BindKind == OMPC_BIND_teams &&
ParentRegion != OMPD_teams &&
ParentRegion != OMPD_target_teams;
Recommend = ShouldBeInTeamsRegion;
}
if (!NestingProhibited &&
isOpenMPNestingDistributeDirective(CurrentRegion)) {
// OpenMP 4.5 [2.17 Nesting of Regions]
Expand Down Expand Up @@ -5770,10 +5781,14 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
StmtResult Res = StmtError();
OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
if (const OMPBindClause *BC =
OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
BindKind = BC->getBindKind();
// First check CancelRegion which is then used in checkNestingOfRegions.
if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
StartLoc))
BindKind, StartLoc))
return StmtError();

llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
Expand Down Expand Up @@ -6352,6 +6367,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
case OMPC_exclusive:
case OMPC_uses_allocators:
case OMPC_affinity:
case OMPC_bind:
continue;
case OMPC_allocator:
case OMPC_flush:
Expand Down Expand Up @@ -13460,6 +13476,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_uses_allocators:
case OMPC_affinity:
case OMPC_when:
case OMPC_bind:
default:
llvm_unreachable("Clause is not allowed.");
}
Expand Down Expand Up @@ -14290,6 +14307,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPC_exclusive:
case OMPC_uses_allocators:
case OMPC_affinity:
case OMPC_bind:
default:
llvm_unreachable("Unexpected OpenMP clause.");
}
Expand Down Expand Up @@ -14681,6 +14699,10 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
break;
case OMPC_bind:
Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
Expand Down Expand Up @@ -15047,6 +15069,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
case OMPC_uses_allocators:
case OMPC_affinity:
case OMPC_when:
case OMPC_bind:
default:
llvm_unreachable("Clause is not allowed.");
}
Expand Down Expand Up @@ -15840,6 +15863,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
case OMPC_detach:
case OMPC_uses_allocators:
case OMPC_when:
case OMPC_bind:
default:
llvm_unreachable("Clause is not allowed.");
}
Expand Down Expand Up @@ -21521,3 +21545,20 @@ OMPClause *Sema::ActOnOpenMPAffinityClause(
return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
EndLoc, Modifier, Vars);
}

OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
SourceLocation KindLoc,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
if (Kind == OMPC_BIND_unknown) {
Diag(KindLoc, diag::err_omp_unexpected_clause_value)
<< getListOfPossibleValues(OMPC_bind, /*First=*/0,
/*Last=*/unsigned(OMPC_BIND_unknown))
<< getOpenMPClauseName(OMPC_bind);
return nullptr;
}

return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
EndLoc);
}

0 comments on commit 4eac7bc

Please sign in to comment.