Author: abataev Date: Fri Jul 21 10:24:30 2017 New Revision: 308759 URL: http://llvm.org/viewvc/llvm-project?rev=308759&view=rev Log: [OPENMP] Simplify analysis of data-sharing attributes.
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaOpenMP.cpp cfe/trunk/test/OpenMP/distribute_firstprivate_messages.cpp cfe/trunk/test/OpenMP/distribute_private_messages.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=308759&r1=308758&r2=308759&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jul 21 10:24:30 2017 @@ -8822,12 +8822,6 @@ def note_omp_critical_hint_here : Note< "%select{|previous }0'hint' clause with value '%1'">; def note_omp_critical_no_hint : Note< "%select{|previous }0directive with no 'hint' clause specified">; -def err_omp_firstprivate_distribute_private_teams : Error< - "private variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">; -def err_omp_firstprivate_and_lastprivate_in_distribute : Error< - "lastprivate variable cannot be firstprivate in '#pragma omp distribute'">; -def err_omp_firstprivate_distribute_in_teams_reduction : Error< - "reduction variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">; def err_omp_depend_clause_thread_simd : Error< "'depend' clauses cannot be mixed with '%0' clause">; def err_omp_depend_sink_expected_loop_iteration : Error< Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=308759&r1=308758&r2=308759&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Jul 21 10:24:30 2017 @@ -540,7 +540,6 @@ DSAStackTy::DSAVarData DSAStackTy::getDS return DVar; } - DVar.DKind = Iter->Directive; // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced // in a Construct, C/C++, predetermined, p.1] // Variables with automatic storage duration that are declared in a scope @@ -551,6 +550,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDS return DVar; } + DVar.DKind = Iter->Directive; // Explicitly specified attributes and local variables with predetermined // attributes. if (Iter->SharingMap.count(D)) { @@ -829,11 +829,10 @@ DSAStackTy::DSAVarData DSAStackTy::getTo // Explicitly specified attributes and local variables with predetermined // attributes. - auto StartI = std::next(Stack.back().first.rbegin()); + auto I = Stack.back().first.rbegin(); auto EndI = Stack.back().first.rend(); - if (FromParent && StartI != EndI) - StartI = std::next(StartI); - auto I = std::prev(StartI); + if (FromParent && I != EndI) + std::advance(I, 1); if (I->SharingMap.count(D)) { DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer(); DVar.PrivateCopy = I->SharingMap[D].PrivateCopy; @@ -855,7 +854,7 @@ DSAStackTy::DSAVarData DSAStackTy::getIm auto StartI = Stack.back().first.rbegin(); auto EndI = Stack.back().first.rend(); if (FromParent && StartI != EndI) - StartI = std::next(StartI); + std::advance(StartI, 1); return getDSA(StartI, D); } @@ -867,16 +866,16 @@ DSAStackTy::hasDSA(ValueDecl *D, if (isStackEmpty()) return {}; D = getCanonicalDecl(D); - auto I = (FromParent && Stack.back().first.size() > 1) - ? std::next(Stack.back().first.rbegin()) - : Stack.back().first.rbegin(); + auto I = Stack.back().first.rbegin(); auto EndI = Stack.back().first.rend(); - while (std::distance(I, EndI) > 1) { + if (FromParent && I != EndI) std::advance(I, 1); + for (; I != EndI; std::advance(I, 1)) { if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) continue; - DSAVarData DVar = getDSA(I, D); - if (CPred(DVar.CKind)) + auto NewI = I; + DSAVarData DVar = getDSA(NewI, D); + if (I == NewI && CPred(DVar.CKind)) return DVar; } return {}; @@ -889,14 +888,15 @@ DSAStackTy::DSAVarData DSAStackTy::hasIn if (isStackEmpty()) return {}; D = getCanonicalDecl(D); - auto StartI = std::next(Stack.back().first.rbegin()); + auto StartI = Stack.back().first.rbegin(); auto EndI = Stack.back().first.rend(); if (FromParent && StartI != EndI) - StartI = std::next(StartI); + std::advance(StartI, 1); if (StartI == EndI || !DPred(StartI->Directive)) return {}; - DSAVarData DVar = getDSA(StartI, D); - return CPred(DVar.CKind) ? DVar : DSAVarData(); + auto NewI = StartI; + DSAVarData DVar = getDSA(NewI, D); + return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); } bool DSAStackTy::hasExplicitDSA( @@ -1627,7 +1627,7 @@ public: return isOpenMPParallelDirective(K) || isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); }, - false); + /*FromParent=*/true); if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { ErrorFound = true; SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); @@ -1667,7 +1667,7 @@ public: isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); }, - false); + /*FromParent=*/true); if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { ErrorFound = true; SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); @@ -8300,13 +8300,18 @@ OMPClause *Sema::ActOnOpenMPFirstprivate if (!IsImplicitClause) { DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); TopDVar = DVar; + OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); bool IsConstant = ElemType.isConstant(Context); // OpenMP [2.4.13, Data-sharing Attribute Clauses] // A list item that specifies a given variable may not appear in more // than one clause on the same directive, except that a variable may be // specified in both firstprivate and lastprivate clauses. + // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] + // A list item may appear in a firstprivate or lastprivate clause but not + // both. if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && - DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { + (CurrDir == OMPD_distribute || DVar.CKind != OMPC_lastprivate) && + DVar.RefExpr) { Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) << getOpenMPClauseName(OMPC_firstprivate); @@ -8334,18 +8339,29 @@ OMPClause *Sema::ActOnOpenMPFirstprivate continue; } - OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); // OpenMP [2.9.3.4, Restrictions, p.2] // A list item that is private within a parallel region must not appear // in a firstprivate clause on a worksharing construct if any of the // worksharing regions arising from the worksharing construct ever bind // to any of the parallel regions arising from the parallel construct. - if (isOpenMPWorksharingDirective(CurrDir) && + // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] + // A list item that is private within a teams region must not appear in a + // firstprivate clause on a distribute construct if any of the distribute + // regions arising from the distribute construct ever bind to any of the + // teams regions arising from the teams construct. + // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] + // A list item that appears in a reduction clause of a teams construct + // must not appear in a firstprivate clause on a distribute construct if + // any of the distribute regions arising from the distribute construct + // ever bind to any of the teams regions arising from the teams construct. + if ((isOpenMPWorksharingDirective(CurrDir) || + isOpenMPDistributeDirective(CurrDir)) && !isOpenMPParallelDirective(CurrDir) && !isOpenMPTeamsDirective(CurrDir)) { DVar = DSAStack->getImplicitDSA(D, true); if (DVar.CKind != OMPC_shared && (isOpenMPParallelDirective(DVar.DKind) || + isOpenMPTeamsDirective(DVar.DKind) || DVar.DKind == OMPD_unknown)) { Diag(ELoc, diag::err_omp_required_access) << getOpenMPClauseName(OMPC_firstprivate) @@ -8370,12 +8386,14 @@ OMPClause *Sema::ActOnOpenMPFirstprivate D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, [](OpenMPDirectiveKind K) -> bool { return isOpenMPParallelDirective(K) || - isOpenMPWorksharingDirective(K); + isOpenMPWorksharingDirective(K) || + isOpenMPTeamsDirective(K); }, - false); + /*FromParent=*/true); if (DVar.CKind == OMPC_reduction && (isOpenMPParallelDirective(DVar.DKind) || - isOpenMPWorksharingDirective(DVar.DKind))) { + isOpenMPWorksharingDirective(DVar.DKind) || + isOpenMPTeamsDirective(DVar.DKind))) { Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) << getOpenMPDirectiveName(DVar.DKind); ReportOriginalDSA(*this, DSAStack, D, DVar); @@ -8383,50 +8401,6 @@ OMPClause *Sema::ActOnOpenMPFirstprivate } } - // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] - // A list item that is private within a teams region must not appear in a - // firstprivate clause on a distribute construct if any of the distribute - // regions arising from the distribute construct ever bind to any of the - // teams regions arising from the teams construct. - // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] - // A list item that appears in a reduction clause of a teams construct - // must not appear in a firstprivate clause on a distribute construct if - // any of the distribute regions arising from the distribute construct - // ever bind to any of the teams regions arising from the teams construct. - // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] - // A list item may appear in a firstprivate or lastprivate clause but not - // both. - if (CurrDir == OMPD_distribute) { - DVar = DSAStack->hasInnermostDSA( - D, [](OpenMPClauseKind C) -> bool { return C == OMPC_private; }, - [](OpenMPDirectiveKind K) -> bool { - return isOpenMPTeamsDirective(K); - }, - false); - if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) { - Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams); - ReportOriginalDSA(*this, DSAStack, D, DVar); - continue; - } - DVar = DSAStack->hasInnermostDSA( - D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, - [](OpenMPDirectiveKind K) -> bool { - return isOpenMPTeamsDirective(K); - }, - false); - if (DVar.CKind == OMPC_reduction && - isOpenMPTeamsDirective(DVar.DKind)) { - Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction); - ReportOriginalDSA(*this, DSAStack, D, DVar); - continue; - } - DVar = DSAStack->getTopDSA(D, false); - if (DVar.CKind == OMPC_lastprivate) { - Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); - ReportOriginalDSA(*this, DSAStack, D, DVar); - continue; - } - } // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] // A list item cannot appear in both a map clause and a data-sharing // attribute clause on the same construct @@ -8586,14 +8560,18 @@ OMPClause *Sema::ActOnOpenMPLastprivateC continue; Type = Type.getNonReferenceType(); + OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced // in a Construct] // Variables with the predetermined data-sharing attributes may not be // listed in data-sharing attributes clauses, except for the cases // listed below. + // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] + // A list item may appear in a firstprivate or lastprivate clause but not + // both. DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && - DVar.CKind != OMPC_firstprivate && + (CurrDir == OMPD_distribute || DVar.CKind != OMPC_firstprivate) && (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) @@ -8602,7 +8580,6 @@ OMPClause *Sema::ActOnOpenMPLastprivateC continue; } - OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); // OpenMP [2.14.3.5, Restrictions, p.2] // A list item that is private within a parallel region, or that appears in // the reduction clause of a parallel construct, must not appear in a @@ -8623,18 +8600,6 @@ OMPClause *Sema::ActOnOpenMPLastprivateC } } - // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] - // A list item may appear in a firstprivate or lastprivate clause but not - // both. - if (CurrDir == OMPD_distribute) { - DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); - if (DVar.CKind == OMPC_firstprivate) { - Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); - ReportOriginalDSA(*this, DSAStack, D, DVar); - continue; - } - } - // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] // A variable of class type (or array thereof) that appears in a // lastprivate clause requires an accessible, unambiguous default @@ -8771,7 +8736,7 @@ public: return true; DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, - false); + /*FromParent=*/true); if (DVarPrivate.CKind != OMPC_unknown) return true; return false; Modified: cfe/trunk/test/OpenMP/distribute_firstprivate_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/distribute_firstprivate_messages.cpp?rev=308759&r1=308758&r2=308759&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/distribute_firstprivate_messages.cpp (original) +++ cfe/trunk/test/OpenMP/distribute_firstprivate_messages.cpp Fri Jul 21 10:24:30 2017 @@ -135,11 +135,11 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp distribute' directive may not be firstprivate, predetermined as private}} #pragma omp target #pragma omp teams private(argc) // expected-note {{defined as private}} - #pragma omp distribute firstprivate(argc) // expected-error {{private variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'}} + #pragma omp distribute firstprivate(argc) // expected-error {{firstprivate variable must be shared}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams reduction(+:argc) // expected-note {{defined as reduction}} - #pragma omp distribute firstprivate(argc) // expected-error {{reduction variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'}} + #pragma omp distribute firstprivate(argc) // expected-error {{firstprivate variable must be shared}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams @@ -147,11 +147,11 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams - #pragma omp distribute lastprivate(argc), firstprivate(argc) // expected-error {{lastprivate variable cannot be firstprivate in '#pragma omp distribute'}} expected-note{{defined as lastprivate}} + #pragma omp distribute lastprivate(argc), firstprivate(argc) // expected-error {{lastprivate variable cannot be firstprivate}} expected-note{{defined as lastprivate}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute firstprivate(argc), lastprivate(argc) // expected-error {{lastprivate variable cannot be firstprivate in '#pragma omp distribute'}} expected-note{{defined as firstprivate}} +#pragma omp distribute firstprivate(argc), lastprivate(argc) // expected-error {{firstprivate variable cannot be lastprivate}} expected-note{{defined as firstprivate}} for (i = 0; i < argc; ++i) foo(); return 0; } Modified: cfe/trunk/test/OpenMP/distribute_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/distribute_private_messages.cpp?rev=308759&r1=308758&r2=308759&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/distribute_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/distribute_private_messages.cpp Fri Jul 21 10:24:30 2017 @@ -87,7 +87,7 @@ int main(int argc, char **argv) { #pragma omp teams { int i; // expected-note {{predetermined as private}} - #pragma omp distribute firstprivate(i), private(i) // expected-error {{private variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'}} + #pragma omp distribute firstprivate(i) // expected-error {{firstprivate variable must be shared}} for (int k = 0; k < argc; ++k) ++k; } #pragma omp target _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits