summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp5
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.h22
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp49
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h13
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp3
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp4
6 files changed, 73 insertions, 23 deletions
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 4e6c677f11d..b1e623b861d 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -447,7 +447,8 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
}
bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
- OpenMPClauseKind CKind) {
+ OpenMPClauseKind CKind,
+ unsigned OpenMPVersion) {
assert(DKind <= OMPD_unknown);
assert(CKind <= OMPC_unknown);
switch (DKind) {
@@ -462,6 +463,8 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
}
break;
case OMPD_simd:
+ if (OpenMPVersion < 50 && CKind == OMPC_if)
+ return false;
switch (CKind) {
#define OPENMP_SIMD_CLAUSE(Name) \
case OMPC_##Name: \
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h
index d051170121c..d806c27fdcb 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -241,17 +241,6 @@ protected:
bool IsOffloadEntry,
const RegionCodeGenTy &CodeGen);
- /// Emits code for OpenMP 'if' clause using specified \a CodeGen
- /// function. Here is the logic:
- /// if (Cond) {
- /// ThenGen();
- /// } else {
- /// ElseGen();
- /// }
- void emitIfClause(CodeGenFunction &CGF, const Expr *Cond,
- const RegionCodeGenTy &ThenGen,
- const RegionCodeGenTy &ElseGen);
-
/// Emits object of ident_t type with info for source location.
/// \param Flags Flags for OpenMP location.
///
@@ -819,6 +808,17 @@ public:
virtual ~CGOpenMPRuntime() {}
virtual void clear();
+ /// Emits code for OpenMP 'if' clause using specified \a CodeGen
+ /// function. Here is the logic:
+ /// if (Cond) {
+ /// ThenGen();
+ /// } else {
+ /// ElseGen();
+ /// }
+ void emitIfClause(CodeGenFunction &CGF, const Expr *Cond,
+ const RegionCodeGenTy &ThenGen,
+ const RegionCodeGenTy &ElseGen);
+
/// Checks if the \p Body is the \a CompoundStmt and returns its child
/// statement iff there is only one that is not evaluatable at the compile
/// time.
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 4406fbc4144..476d380139d 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1846,8 +1846,6 @@ static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
CGF.EmitIgnoredExpr(S.getCalcLastIteration());
}
- CGF.EmitOMPSimdInit(S);
-
emitAlignedClause(CGF, S);
(void)CGF.EmitOMPLinearClauseInit(S);
{
@@ -1860,13 +1858,46 @@ static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
(void)LoopScope.Privatize();
if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
- CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
- S.getInc(),
- [&S](CodeGenFunction &CGF) {
- CGF.EmitOMPLoopBody(S, CodeGenFunction::JumpDest());
- CGF.EmitStopPoint(&S);
- },
- [](CodeGenFunction &) {});
+
+ auto &&ThenGen = [&S, &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
+ CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
+ CGF.EmitOMPSimdInit(S);
+
+ CGF.EmitOMPInnerLoop(
+ S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
+ [&S](CodeGenFunction &CGF) {
+ CGF.EmitOMPLoopBody(S, CodeGenFunction::JumpDest());
+ CGF.EmitStopPoint(&S);
+ },
+ [](CodeGenFunction &) {});
+ };
+ auto &&ElseGen = [&S, &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
+ CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
+ CGF.LoopStack.setVectorizeEnable(/*Enable=*/false);
+
+ CGF.EmitOMPInnerLoop(
+ S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
+ [&S](CodeGenFunction &CGF) {
+ CGF.EmitOMPLoopBody(S, CodeGenFunction::JumpDest());
+ CGF.EmitStopPoint(&S);
+ },
+ [](CodeGenFunction &) {});
+ };
+ const Expr *IfCond = nullptr;
+ for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
+ if (CGF.getLangOpts().OpenMP >= 50 &&
+ (C->getNameModifier() == OMPD_unknown ||
+ C->getNameModifier() == OMPD_simd)) {
+ IfCond = C->getCondition();
+ break;
+ }
+ }
+ if (IfCond) {
+ CGF.CGM.getOpenMPRuntime().emitIfClause(CGF, IfCond, ThenGen, ElseGen);
+ } else {
+ RegionCodeGenTy ThenRCG(ThenGen);
+ ThenRCG(CGF);
+ }
CGF.EmitOMPSimdFinal(S, [](CodeGenFunction &) { return nullptr; });
// Emit final copy of the lastprivate variables at the end of loops.
if (HasLastprivateClause)
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 5c3d1764fad..7a2627ccf58 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -947,6 +947,19 @@ public:
}
};
+ /// Save/restore original map of previously emitted local vars in case when we
+ /// need to duplicate emission of the same code several times in the same
+ /// function for OpenMP code.
+ class OMPLocalDeclMapRAII {
+ CodeGenFunction &CGF;
+ DeclMapTy SavedMap;
+
+ public:
+ OMPLocalDeclMapRAII(CodeGenFunction &CGF)
+ : CGF(CGF), SavedMap(CGF.LocalDeclMap) {}
+ ~OMPLocalDeclMapRAII() { SavedMap.swap(CGF.LocalDeclMap); }
+ };
+
/// Takes the old cleanup stack size and emits the cleanup blocks
/// that have been added.
void
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 5b95dbbdea6..208e3247a8b 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -1939,7 +1939,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
bool ErrorFound = false;
bool WrongDirective = false;
// Check if clause is allowed for the given directive.
- if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
+ if (CKind != OMPC_unknown &&
+ !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
<< getOpenMPDirectiveName(DKind);
ErrorFound = true;
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index d0f2e7c30ae..7ced9eea75e 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -4488,6 +4488,8 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
case OMPD_simd:
Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
VarsWithInheritedDSA);
+ if (LangOpts.OpenMP >= 50)
+ AllowedNameModifiers.push_back(OMPD_simd);
break;
case OMPD_for:
Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
@@ -10667,6 +10669,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_master_taskloop:
case OMPD_master_taskloop_simd:
case OMPD_target_data:
+ case OMPD_simd:
// Do not capture if-clause expressions.
break;
case OMPD_threadprivate:
@@ -10683,7 +10686,6 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_teams:
- case OMPD_simd:
case OMPD_for:
case OMPD_for_simd:
case OMPD_sections:
OpenPOWER on IntegriCloud