[OPENMP 4.0] Initial support for 'omp cancellation point' construct.
Add parsing and sema analysis for 'omp cancellation point' directive.
llvm-svn: 241145
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 7c1746f..8d6d01e 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -95,19 +95,20 @@
Scope *CurScope;
SourceLocation ConstructLoc;
bool OrderedRegion;
+ bool NowaitRegion;
unsigned CollapseNumber;
SourceLocation InnerTeamsRegionLoc;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Scope *CurScope, SourceLocation Loc)
: SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
- ConstructLoc(Loc), OrderedRegion(false), CollapseNumber(1),
- InnerTeamsRegionLoc() {}
+ ConstructLoc(Loc), OrderedRegion(false), NowaitRegion(false),
+ CollapseNumber(1), InnerTeamsRegionLoc() {}
SharingMapTy()
: SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
- ConstructLoc(), OrderedRegion(false), CollapseNumber(1),
- InnerTeamsRegionLoc() {}
+ ConstructLoc(), OrderedRegion(false), NowaitRegion(false),
+ CollapseNumber(1), InnerTeamsRegionLoc() {}
};
typedef SmallVector<SharingMapTy, 64> StackTy;
@@ -232,6 +233,17 @@
return Stack[Stack.size() - 2].OrderedRegion;
return false;
}
+ /// \brief Marks current region as nowait (it has a 'nowait' clause).
+ void setNowaitRegion(bool IsNowait = true) {
+ Stack.back().NowaitRegion = IsNowait;
+ }
+ /// \brief Returns true, if parent region is nowait (has associated
+ /// 'nowait' clause), false - otherwise.
+ bool isParentNowaitRegion() const {
+ if (Stack.size() > 2)
+ return Stack[Stack.size() - 2].NowaitRegion;
+ return false;
+ }
/// \brief Set collapse value for the region.
void setCollapseNumber(unsigned Val) { Stack.back().CollapseNumber = Val; }
@@ -1312,6 +1324,7 @@
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
+ case OMPD_cancellation_point:
case OMPD_flush:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
@@ -1352,6 +1365,7 @@
static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
OpenMPDirectiveKind CurrentRegion,
const DeclarationNameInfo &CurrentName,
+ OpenMPDirectiveKind CancelRegion,
SourceLocation StartLoc) {
// Allowed nesting of constructs
// +------------------+-----------------+------------------------------------+
@@ -1379,6 +1393,8 @@
// | parallel | atomic | * |
// | parallel | target | * |
// | parallel | teams | + |
+ // | parallel | cancellation | |
+ // | | point | ! |
// +------------------+-----------------+------------------------------------+
// | for | parallel | * |
// | for | for | + |
@@ -1402,6 +1418,8 @@
// | for | atomic | * |
// | for | target | * |
// | for | teams | + |
+ // | for | cancellation | |
+ // | | point | ! |
// +------------------+-----------------+------------------------------------+
// | master | parallel | * |
// | master | for | + |
@@ -1425,6 +1443,8 @@
// | master | atomic | * |
// | master | target | * |
// | master | teams | + |
+ // | master | cancellation | |
+ // | | point | |
// +------------------+-----------------+------------------------------------+
// | critical | parallel | * |
// | critical | for | + |
@@ -1447,6 +1467,8 @@
// | critical | atomic | * |
// | critical | target | * |
// | critical | teams | + |
+ // | critical | cancellation | |
+ // | | point | |
// +------------------+-----------------+------------------------------------+
// | simd | parallel | |
// | simd | for | |
@@ -1470,6 +1492,8 @@
// | simd | atomic | |
// | simd | target | |
// | simd | teams | |
+ // | simd | cancellation | |
+ // | | point | |
// +------------------+-----------------+------------------------------------+
// | for simd | parallel | |
// | for simd | for | |
@@ -1493,6 +1517,8 @@
// | for simd | atomic | |
// | for simd | target | |
// | for simd | teams | |
+ // | for simd | cancellation | |
+ // | | point | |
// +------------------+-----------------+------------------------------------+
// | parallel for simd| parallel | |
// | parallel for simd| for | |
@@ -1516,6 +1542,8 @@
// | parallel for simd| atomic | |
// | parallel for simd| target | |
// | parallel for simd| teams | |
+ // | parallel for simd| cancellation | |
+ // | | point | |
// +------------------+-----------------+------------------------------------+
// | sections | parallel | * |
// | sections | for | + |
@@ -1539,6 +1567,8 @@
// | sections | atomic | * |
// | sections | target | * |
// | sections | teams | + |
+ // | sections | cancellation | |
+ // | | point | ! |
// +------------------+-----------------+------------------------------------+
// | section | parallel | * |
// | section | for | + |
@@ -1562,6 +1592,8 @@
// | section | atomic | * |
// | section | target | * |
// | section | teams | + |
+ // | section | cancellation | |
+ // | | point | ! |
// +------------------+-----------------+------------------------------------+
// | single | parallel | * |
// | single | for | + |
@@ -1585,6 +1617,8 @@
// | single | atomic | * |
// | single | target | * |
// | single | teams | + |
+ // | single | cancellation | |
+ // | | point | |
// +------------------+-----------------+------------------------------------+
// | parallel for | parallel | * |
// | parallel for | for | + |
@@ -1608,6 +1642,8 @@
// | parallel for | atomic | * |
// | parallel for | target | * |
// | parallel for | teams | + |
+ // | parallel for | cancellation | |
+ // | | point | ! |
// +------------------+-----------------+------------------------------------+
// | parallel sections| parallel | * |
// | parallel sections| for | + |
@@ -1631,6 +1667,8 @@
// | parallel sections| atomic | * |
// | parallel sections| target | * |
// | parallel sections| teams | + |
+ // | parallel sections| cancellation | |
+ // | | point | ! |
// +------------------+-----------------+------------------------------------+
// | task | parallel | * |
// | task | for | + |
@@ -1654,6 +1692,8 @@
// | task | atomic | * |
// | task | target | * |
// | task | teams | + |
+ // | task | cancellation | |
+ // | | point | ! |
// +------------------+-----------------+------------------------------------+
// | ordered | parallel | * |
// | ordered | for | + |
@@ -1677,6 +1717,8 @@
// | ordered | atomic | * |
// | ordered | target | * |
// | ordered | teams | + |
+ // | ordered | cancellation | |
+ // | | point | |
// +------------------+-----------------+------------------------------------+
// | atomic | parallel | |
// | atomic | for | |
@@ -1700,6 +1742,8 @@
// | atomic | atomic | |
// | atomic | target | |
// | atomic | teams | |
+ // | atomic | cancellation | |
+ // | | point | |
// +------------------+-----------------+------------------------------------+
// | target | parallel | * |
// | target | for | * |
@@ -1723,6 +1767,8 @@
// | target | atomic | * |
// | target | target | * |
// | target | teams | * |
+ // | target | cancellation | |
+ // | | point | |
// +------------------+-----------------+------------------------------------+
// | teams | parallel | * |
// | teams | for | + |
@@ -1746,6 +1792,8 @@
// | teams | atomic | + |
// | teams | target | + |
// | teams | teams | + |
+ // | teams | cancellation | |
+ // | | point | |
// +------------------+-----------------+------------------------------------+
if (Stack->getCurScope()) {
auto ParentRegion = Stack->getParentDirective();
@@ -1787,7 +1835,20 @@
// called from OpenMP regions with the required preconditions).
if (ParentRegion == OMPD_unknown)
return false;
- if (CurrentRegion == OMPD_master) {
+ if (CurrentRegion == OMPD_cancellation_point) {
+ // OpenMP [2.16, Nesting of Regions]
+ // A cancellation point construct for which construct-type-clause is
+ // taskgroup must be nested inside a task construct. A cancellation
+ // point construct for which construct-type-clause is not taskgroup must
+ // be closely nested inside an OpenMP construct that matches the type
+ // specified in construct-type-clause.
+ NestingProhibited =
+ !((CancelRegion == OMPD_parallel && ParentRegion == OMPD_parallel) ||
+ (CancelRegion == OMPD_for && ParentRegion == OMPD_for) ||
+ (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
+ (CancelRegion == OMPD_sections &&
+ (ParentRegion == OMPD_section || ParentRegion == OMPD_sections)));
+ } else if (CurrentRegion == OMPD_master) {
// OpenMP [2.16, Nesting of Regions]
// A master region may not be closely nested inside a worksharing,
// atomic, or explicit task region.
@@ -1877,14 +1938,13 @@
return false;
}
-StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
- const DeclarationNameInfo &DirName,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AStmt,
- SourceLocation StartLoc,
- SourceLocation EndLoc) {
+StmtResult Sema::ActOnOpenMPExecutableDirective(
+ OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
+ OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
StmtResult Res = StmtError();
- if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, StartLoc))
+ if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
+ StartLoc))
return StmtError();
llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
@@ -2018,6 +2078,13 @@
Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
EndLoc);
break;
+ case OMPD_cancellation_point:
+ assert(ClausesWithImplicit.empty() &&
+ "No clauses are allowed for 'omp cancellation point' directive");
+ assert(AStmt == nullptr && "No associated statement allowed for 'omp "
+ "cancellation point' directive");
+ Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
+ break;
case OMPD_threadprivate:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
@@ -4204,6 +4271,28 @@
return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
}
+StmtResult
+Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ OpenMPDirectiveKind CancelRegion) {
+ if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
+ CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
+ Diag(StartLoc, diag::err_omp_wrong_cancel_region)
+ << getOpenMPDirectiveName(CancelRegion);
+ return StmtError();
+ }
+ if (DSAStack->isParentNowaitRegion()) {
+ Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
+ return StmtError();
+ }
+ if (DSAStack->isParentOrderedRegion()) {
+ Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
+ return StmtError();
+ }
+ return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
+ CancelRegion);
+}
+
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -4722,6 +4811,7 @@
OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
SourceLocation EndLoc) {
+ DSAStack->setNowaitRegion();
return new (Context) OMPNowaitClause(StartLoc, EndLoc);
}