Skip to content

Commit

Permalink
[OpenMP] Initial parsing/sema for the 'omp teams loop' construct
Browse files Browse the repository at this point in the history
Adds basic parsing/sema/serialization support for the #pragma omp teams loop
directive.

Differential Revision: https://reviews.llvm.org/D121713
  • Loading branch information
mikerice1969 committed Mar 16, 2022
1 parent f5ddcf2 commit 79f661e
Show file tree
Hide file tree
Showing 25 changed files with 578 additions and 18 deletions.
6 changes: 5 additions & 1 deletion clang/include/clang-c/Index.h
Original file line number Diff line number Diff line change
Expand Up @@ -2600,7 +2600,11 @@ enum CXCursorKind {
*/
CXCursor_OMPGenericLoopDirective = 295,

CXCursor_LastStmt = CXCursor_OMPGenericLoopDirective,
/** OpenMP teams loop directive.
*/
CXCursor_OMPTeamsGenericLoopDirective = 296,

CXCursor_LastStmt = CXCursor_OMPTeamsGenericLoopDirective,

/**
* Cursor that represents the translation unit itself.
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -3074,6 +3074,9 @@ DEF_TRAVERSE_STMT(OMPMaskedDirective,
DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })

DEF_TRAVERSE_STMT(OMPTeamsGenericLoopDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })

// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
Expand Down
66 changes: 66 additions & 0 deletions clang/include/clang/AST/StmtOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -1526,6 +1526,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
T->getStmtClass() == OMPGenericLoopDirectiveClass ||
T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
T->getStmtClass() == OMPDistributeDirectiveClass ||
Expand Down Expand Up @@ -5569,6 +5570,71 @@ class OMPGenericLoopDirective final : public OMPLoopDirective {
}
};

/// This represents '#pragma omp teams loop' directive.
///
/// \code
/// #pragma omp teams loop private(a,b) order(concurrent)
/// \endcode
/// In this example directive '#pragma omp teams loop' has
/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
///
class OMPTeamsGenericLoopDirective final : public OMPLoopDirective {
friend class ASTStmtReader;
friend class OMPExecutableDirective;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
/// \param CollapsedNum Number of collapsed nested loops.
///
OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum)
: OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
llvm::omp::OMPD_teams_loop, StartLoc, EndLoc,
CollapsedNum) {}

/// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
///
explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum)
: OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
llvm::omp::OMPD_teams_loop, SourceLocation(),
SourceLocation(), CollapsedNum) {}

public:
/// Creates directive with a list of \p Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
///
static OMPTeamsGenericLoopDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);

/// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses,
unsigned CollapsedNum,
EmptyShell);

static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass;
}
};

} // end namespace clang

#endif
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -10898,7 +10898,7 @@ def note_omp_exits_structured_block
: Note<"jump exits scope of OpenMP structured block">;
def err_omp_lastprivate_loop_var_non_loop_iteration : Error<
"only loop iteration variables are allowed in 'lastprivate' clause in "
"'omp loop' directives">;
"'omp %0' directives">;
def err_omp_interop_variable_expected : Error<
"expected%select{| non-const}0 variable of type 'omp_interop_t'">;
def err_omp_interop_variable_wrong_type : Error<
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/StmtNodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,4 @@ def OMPInteropDirective : StmtNode<OMPExecutableDirective>;
def OMPDispatchDirective : StmtNode<OMPExecutableDirective>;
def OMPMaskedDirective : StmtNode<OMPExecutableDirective>;
def OMPGenericLoopDirective : StmtNode<OMPLoopDirective>;
def OMPTeamsGenericLoopDirective : StmtNode<OMPLoopDirective>;
5 changes: 5 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -10904,6 +10904,11 @@ class Sema final {
StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
/// Called on well-formed '\#pragma omp teams loop' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPTeamsGenericLoopDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp cancellation point'.
StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1961,6 +1961,7 @@ enum StmtCode {
STMT_OMP_DISPATCH_DIRECTIVE,
STMT_OMP_MASKED_DIRECTIVE,
STMT_OMP_GENERIC_LOOP_DIRECTIVE,
STMT_OMP_TEAMS_GENERIC_LOOP_DIRECTIVE,
EXPR_OMP_ARRAY_SECTION,
EXPR_OMP_ARRAY_SHAPING,
EXPR_OMP_ITERATOR,
Expand Down
44 changes: 44 additions & 0 deletions clang/lib/AST/StmtOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2136,3 +2136,47 @@ OMPGenericLoopDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses,
C, NumClauses, /*HasAssociatedStmt=*/true,
numLoopChildren(CollapsedNum, OMPD_loop), CollapsedNum);
}

OMPTeamsGenericLoopDirective *OMPTeamsGenericLoopDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
const HelperExprs &Exprs) {
auto *Dir = createDirective<OMPTeamsGenericLoopDirective>(
C, Clauses, AssociatedStmt,
numLoopChildren(CollapsedNum, OMPD_teams_loop), StartLoc, EndLoc,
CollapsedNum);
Dir->setIterationVariable(Exprs.IterationVarRef);
Dir->setLastIteration(Exprs.LastIteration);
Dir->setCalcLastIteration(Exprs.CalcLastIteration);
Dir->setPreCond(Exprs.PreCond);
Dir->setCond(Exprs.Cond);
Dir->setInit(Exprs.Init);
Dir->setInc(Exprs.Inc);
Dir->setIsLastIterVariable(Exprs.IL);
Dir->setLowerBoundVariable(Exprs.LB);
Dir->setUpperBoundVariable(Exprs.UB);
Dir->setStrideVariable(Exprs.ST);
Dir->setEnsureUpperBound(Exprs.EUB);
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
Dir->setDependentCounters(Exprs.DependentCounters);
Dir->setDependentInits(Exprs.DependentInits);
Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}

OMPTeamsGenericLoopDirective *
OMPTeamsGenericLoopDirective::CreateEmpty(const ASTContext &C,
unsigned NumClauses,
unsigned CollapsedNum, EmptyShell) {
return createEmptyDirective<OMPTeamsGenericLoopDirective>(
C, NumClauses, /*HasAssociatedStmt=*/true,
numLoopChildren(CollapsedNum, OMPD_teams_loop), CollapsedNum);
}
6 changes: 6 additions & 0 deletions clang/lib/AST/StmtPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,12 @@ void StmtPrinter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *Node) {
PrintOMPExecutableDirective(Node);
}

void StmtPrinter::VisitOMPTeamsGenericLoopDirective(
OMPTeamsGenericLoopDirective *Node) {
Indent() << "#pragma omp teams loop";
PrintOMPExecutableDirective(Node);
}

//===----------------------------------------------------------------------===//
// Expr printing methods.
//===----------------------------------------------------------------------===//
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/StmtProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,11 @@ void StmtProfiler::VisitOMPGenericLoopDirective(
VisitOMPLoopDirective(S);
}

void StmtProfiler::VisitOMPTeamsGenericLoopDirective(
const OMPTeamsGenericLoopDirective *S) {
VisitOMPLoopDirective(S);
}

void StmtProfiler::VisitExpr(const Expr *S) {
VisitStmt(S);
}
Expand Down
10 changes: 7 additions & 3 deletions clang/lib/Basic/OpenMPKinds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
DKind == OMPD_target_teams_distribute_parallel_for ||
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
DKind == OMPD_target_teams_distribute_simd || DKind == OMPD_tile ||
DKind == OMPD_unroll || DKind == OMPD_loop;
DKind == OMPD_unroll || DKind == OMPD_loop || DKind == OMPD_teams_loop;
}

bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
Expand Down Expand Up @@ -555,7 +555,8 @@ bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {
return DKind == OMPD_teams || DKind == OMPD_teams_distribute ||
DKind == OMPD_teams_distribute_simd ||
DKind == OMPD_teams_distribute_parallel_for_simd ||
DKind == OMPD_teams_distribute_parallel_for;
DKind == OMPD_teams_distribute_parallel_for ||
DKind == OMPD_teams_loop;
}

bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
Expand Down Expand Up @@ -599,7 +600,7 @@ bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) {
}

bool clang::isOpenMPGenericLoopDirective(OpenMPDirectiveKind Kind) {
return Kind == OMPD_loop;
return Kind == OMPD_loop || Kind == OMPD_teams_loop;
}

bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
Expand Down Expand Up @@ -700,6 +701,9 @@ void clang::getOpenMPCaptureRegions(
CaptureRegions.push_back(OMPD_teams);
CaptureRegions.push_back(OMPD_parallel);
break;
case OMPD_teams_loop:
CaptureRegions.push_back(OMPD_teams);
break;
case OMPD_loop:
// TODO: 'loop' may require different capture regions depending on the bind
// clause or the parent directive when there is no bind clause. Use
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CGStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
case Stmt::OMPGenericLoopDirectiveClass:
EmitOMPGenericLoopDirective(cast<OMPGenericLoopDirective>(*S));
break;
case Stmt::OMPTeamsGenericLoopDirectiveClass:
llvm_unreachable("teams loop directive not supported yet.");
break;
}
}

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ static OpenMPDirectiveKindExWrapper parseOpenMPDirectiveKind(Parser &P) {
OMPD_teams_distribute_parallel_for},
{OMPD_teams_distribute_parallel_for, OMPD_simd,
OMPD_teams_distribute_parallel_for_simd},
{OMPD_teams, OMPD_loop, OMPD_teams_loop},
{OMPD_target, OMPD_teams, OMPD_target_teams},
{OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
{OMPD_target_teams_distribute, OMPD_parallel,
Expand Down Expand Up @@ -2399,6 +2400,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
case OMPD_masked:
case OMPD_metadirective:
case OMPD_loop:
case OMPD_teams_loop:
Diag(Tok, diag::err_omp_unexpected_directive)
<< 1 << getOpenMPDirectiveName(DKind);
break;
Expand Down Expand Up @@ -2754,6 +2756,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
case OMPD_target_parallel:
case OMPD_target_parallel_for:
case OMPD_loop:
case OMPD_teams_loop:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_master_taskloop:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaExceptionSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
case Stmt::OMPMaskedDirectiveClass:
case Stmt::OMPMetaDirectiveClass:
case Stmt::OMPGenericLoopDirectiveClass:
case Stmt::OMPTeamsGenericLoopDirectiveClass:
case Stmt::ReturnStmtClass:
case Stmt::SEHExceptStmtClass:
case Stmt::SEHFinallyStmtClass:
Expand Down
Loading

0 comments on commit 79f661e

Please sign in to comment.