[OPENMP] Emit __kmpc_cancel_barrier() and code for 'cancellation point' only if 'cancel' is found.
Patch improves codegen for OpenMP constructs. If the OpenMP region does not have internal 'cancel' construct, a call to 'void __kmpc_barrier()' runtime function is generated for all implicit/explicit barriers. If the region has inner 'cancel' directive, then
```
if (__kmpc_cancel_barrier())
exit from outer construct;
```
code is generated.
Also, the code for 'canellation point' directive is not generated if parent directive does not have 'cancel' directive.
llvm-svn: 247681
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index bc5fadc..cf7ce23 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -98,6 +98,7 @@
SourceLocation ConstructLoc;
bool OrderedRegion;
bool NowaitRegion;
+ bool CancelRegion;
unsigned CollapseNumber;
SourceLocation InnerTeamsRegionLoc;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
@@ -105,12 +106,12 @@
: SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
ConstructLoc(Loc), OrderedRegion(false), NowaitRegion(false),
- CollapseNumber(1), InnerTeamsRegionLoc() {}
+ CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {}
SharingMapTy()
: SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
ConstructLoc(), OrderedRegion(false), NowaitRegion(false),
- CollapseNumber(1), InnerTeamsRegionLoc() {}
+ CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {}
};
typedef SmallVector<SharingMapTy, 64> StackTy;
@@ -251,6 +252,16 @@
return Stack[Stack.size() - 2].NowaitRegion;
return false;
}
+ /// \brief Marks parent region as cancel region.
+ void setParentCancelRegion(bool Cancel = true) {
+ if (Stack.size() > 2)
+ Stack[Stack.size() - 2].CancelRegion =
+ Stack[Stack.size() - 2].CancelRegion || Cancel;
+ }
+ /// \brief Return true if current region has inner cancel construct.
+ bool isCancelRegion() const {
+ return Stack.back().CancelRegion;
+ }
/// \brief Set collapse value for the region.
void setCollapseNumber(unsigned Val) { Stack.back().CollapseNumber = Val; }
@@ -1901,10 +1912,12 @@
// construct-type-clause.
NestingProhibited =
!((CancelRegion == OMPD_parallel && ParentRegion == OMPD_parallel) ||
- (CancelRegion == OMPD_for && ParentRegion == OMPD_for) ||
+ (CancelRegion == OMPD_for &&
+ (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for)) ||
(CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
(CancelRegion == OMPD_sections &&
- (ParentRegion == OMPD_section || ParentRegion == OMPD_sections)));
+ (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
+ ParentRegion == OMPD_parallel_sections)));
} else if (CurrentRegion == OMPD_master) {
// OpenMP [2.16, Nesting of Regions]
// A master region may not be closely nested inside a worksharing,
@@ -2275,8 +2288,8 @@
getCurFunction()->setHasBranchProtectedScope();
- return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
- AStmt);
+ return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
+ DSAStack->isCancelRegion());
}
namespace {
@@ -3741,7 +3754,7 @@
getCurFunction()->setHasBranchProtectedScope();
return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
- Clauses, AStmt, B);
+ Clauses, AStmt, B, DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPForSimdDirective(
@@ -3822,6 +3835,8 @@
diag::err_omp_sections_substmt_not_section);
return StmtError();
}
+ cast<OMPSectionDirective>(SectionStmt)
+ ->setHasCancel(DSAStack->isCancelRegion());
}
} else {
Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
@@ -3830,8 +3845,8 @@
getCurFunction()->setHasBranchProtectedScope();
- return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses,
- AStmt);
+ return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
+ DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
@@ -3843,8 +3858,10 @@
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
getCurFunction()->setHasBranchProtectedScope();
+ DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
- return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt);
+ return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
+ DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
@@ -3946,7 +3963,8 @@
getCurFunction()->setHasBranchProtectedScope();
return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
- NestedLoopCount, Clauses, AStmt, B);
+ NestedLoopCount, Clauses, AStmt, B,
+ DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
@@ -4031,6 +4049,8 @@
diag::err_omp_parallel_sections_substmt_not_section);
return StmtError();
}
+ cast<OMPSectionDirective>(SectionStmt)
+ ->setHasCancel(DSAStack->isCancelRegion());
}
} else {
Diag(AStmt->getLocStart(),
@@ -4040,8 +4060,8 @@
getCurFunction()->setHasBranchProtectedScope();
- return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc,
- Clauses, AStmt);
+ return OMPParallelSectionsDirective::Create(
+ Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
@@ -4060,7 +4080,8 @@
getCurFunction()->setHasBranchProtectedScope();
- return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
+ return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
+ DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
@@ -4899,6 +4920,7 @@
Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
return StmtError();
}
+ DSAStack->setParentCancelRegion(/*Cancel=*/true);
return OMPCancelDirective::Create(Context, StartLoc, EndLoc, CancelRegion);
}