Author: abataev Date: Wed Apr 13 08:36:48 2016 New Revision: 266198 URL: http://llvm.org/viewvc/llvm-project?rev=266198&view=rev Log: [OPENMP 4.0] Fixed DSA analysis for taskloop directives.
Patch make clang to perform analysis for task-based directives also for taskloop-based directives. Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.h cfe/trunk/lib/Basic/OpenMPKinds.cpp cfe/trunk/lib/Sema/SemaOpenMP.cpp cfe/trunk/test/OpenMP/taskloop_firstprivate_messages.cpp cfe/trunk/test/OpenMP/taskloop_simd_firstprivate_messages.cpp Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.h?rev=266198&r1=266197&r2=266198&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/OpenMPKinds.h (original) +++ cfe/trunk/include/clang/Basic/OpenMPKinds.h Wed Apr 13 08:36:48 2016 @@ -203,6 +203,9 @@ bool isOpenMPPrivate(OpenMPClauseKind Ki /// \return true - the clause is a threadprivate clause, otherwise - false. bool isOpenMPThreadPrivate(OpenMPClauseKind Kind); +/// Checks if the specified directive kind is one of tasking directives - task, +/// taskloop or taksloop simd. +bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind); } #endif Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=266198&r1=266197&r2=266198&view=diff ============================================================================== --- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original) +++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Wed Apr 13 08:36:48 2016 @@ -632,3 +632,6 @@ bool clang::isOpenMPThreadPrivate(OpenMP return Kind == OMPC_threadprivate || Kind == OMPC_copyin; } +bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind) { + return Kind == OMPD_task || isOpenMPTaskLoopDirective(Kind); +} Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=266198&r1=266197&r2=266198&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Wed Apr 13 08:36:48 2016 @@ -376,9 +376,8 @@ public: } }; bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { - return isOpenMPParallelDirective(DKind) || DKind == OMPD_task || - isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown || - isOpenMPTaskLoopDirective(DKind); + return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || + isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; } } // namespace @@ -474,27 +473,24 @@ DSAStackTy::DSAVarData DSAStackTy::getDS // In a task construct, if no default clause is present, a variable that in // the enclosing context is determined to be shared by all implicit tasks // bound to the current team is shared. - if (DVar.DKind == OMPD_task) { + if (isOpenMPTaskingDirective(DVar.DKind)) { DSAVarData DVarTemp; for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend(); I != EE; ++I) { // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables - // Referenced - // in a Construct, implicitly determined, p.6] + // Referenced in a Construct, implicitly determined, p.6] // In a task construct, if no default clause is present, a variable // whose data-sharing attribute is not determined by the rules above is // firstprivate. DVarTemp = getDSA(I, D); if (DVarTemp.CKind != OMPC_shared) { DVar.RefExpr = nullptr; - DVar.DKind = OMPD_task; DVar.CKind = OMPC_firstprivate; return DVar; } if (isParallelOrTaskRegion(I->Directive)) break; } - DVar.DKind = OMPD_task; DVar.CKind = (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; return DVar; @@ -1337,7 +1333,8 @@ static void ReportOriginalDSA(Sema &Sema Reason = PDSA_LoopIterVarLastprivate; else Reason = PDSA_LoopIterVarLinear; - } else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) { + } else if (isOpenMPTaskingDirective(DVar.DKind) && + DVar.CKind == OMPC_firstprivate) { Reason = PDSA_TaskVarFirstprivate; ReportLoc = DVar.ImplicitDSALoc; } else if (VD && VD->isStaticLocal()) @@ -1406,7 +1403,7 @@ public: isOpenMPTeamsDirective(K); }, false); - if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) { + if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { ErrorFound = true; SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); ReportOriginalDSA(SemaRef, Stack, VD, DVar); @@ -1415,7 +1412,8 @@ public: // Define implicit data-sharing attributes for task. DVar = Stack->getImplicitDSA(VD, false); - if (DKind == OMPD_task && DVar.CKind != OMPC_shared) + if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && + !Stack->isLoopControlVariable(VD).first) ImplicitFirstprivate.push_back(E); } } @@ -1442,7 +1440,7 @@ public: isOpenMPTeamsDirective(K); }, false); - if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) { + if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { ErrorFound = true; SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); ReportOriginalDSA(SemaRef, Stack, FD, DVar); @@ -1451,7 +1449,8 @@ public: // Define implicit data-sharing attributes for task. DVar = Stack->getImplicitDSA(FD, false); - if (DKind == OMPD_task && DVar.CKind != OMPC_shared) + if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && + !Stack->isLoopControlVariable(FD).first) ImplicitFirstprivate.push_back(E); } } @@ -2763,8 +2762,7 @@ static bool CheckNestingOfRegions(Sema & // A master region may not be closely nested inside a worksharing, // atomic, or explicit task region. NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || - ParentRegion == OMPD_task || - isOpenMPTaskLoopDirective(ParentRegion); + isOpenMPTaskingDirective(ParentRegion); } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { // OpenMP [2.16, Nesting of Regions] // A critical region may not be nested (closely or otherwise) inside a @@ -2798,21 +2796,21 @@ static bool CheckNestingOfRegions(Sema & // OpenMP [2.16, Nesting of Regions] // A barrier region may not be closely nested inside a worksharing, // explicit task, critical, ordered, atomic, or master region. - NestingProhibited = - isOpenMPWorksharingDirective(ParentRegion) || - ParentRegion == OMPD_task || ParentRegion == OMPD_master || - ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered || - isOpenMPTaskLoopDirective(ParentRegion); + NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || + isOpenMPTaskingDirective(ParentRegion) || + ParentRegion == OMPD_master || + ParentRegion == OMPD_critical || + ParentRegion == OMPD_ordered; } else if (isOpenMPWorksharingDirective(CurrentRegion) && !isOpenMPParallelDirective(CurrentRegion)) { // OpenMP [2.16, Nesting of Regions] // A worksharing region may not be closely nested inside a worksharing, // explicit task, critical, ordered, atomic, or master region. - NestingProhibited = - isOpenMPWorksharingDirective(ParentRegion) || - ParentRegion == OMPD_task || ParentRegion == OMPD_master || - ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered || - isOpenMPTaskLoopDirective(ParentRegion); + NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || + isOpenMPTaskingDirective(ParentRegion) || + ParentRegion == OMPD_master || + ParentRegion == OMPD_critical || + ParentRegion == OMPD_ordered; Recommend = ShouldBeInParallelRegion; } else if (CurrentRegion == OMPD_ordered) { // OpenMP [2.16, Nesting of Regions] @@ -2824,8 +2822,7 @@ static bool CheckNestingOfRegions(Sema & // An ordered construct with the simd clause is the only OpenMP construct // that can appear in the simd region. NestingProhibited = ParentRegion == OMPD_critical || - ParentRegion == OMPD_task || - isOpenMPTaskLoopDirective(ParentRegion) || + isOpenMPTaskingDirective(ParentRegion) || !(isOpenMPSimdDirective(ParentRegion) || Stack->isParentOrderedRegion()); Recommend = ShouldBeInOrderedRegion; @@ -7495,7 +7492,7 @@ OMPClause *Sema::ActOnOpenMPPrivateClaus // Variably modified types are not supported for tasks. if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && - DSAStack->getCurrentDirective() == OMPD_task) { + isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) << getOpenMPClauseName(OMPC_private) << Type << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); @@ -7693,7 +7690,7 @@ OMPClause *Sema::ActOnOpenMPFirstprivate // construct must not appear in a firstprivate clause in a task construct // encountered during execution of any of the worksharing regions arising // from the worksharing construct. - if (CurrDir == OMPD_task) { + if (isOpenMPTaskingDirective(CurrDir)) { DVar = DSAStack->hasInnermostDSA(D, MatchesAnyClause(OMPC_reduction), [](OpenMPDirectiveKind K) -> bool { @@ -7770,7 +7767,7 @@ OMPClause *Sema::ActOnOpenMPFirstprivate // Variably modified types are not supported for tasks. if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && - DSAStack->getCurrentDirective() == OMPD_task) { + isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) << getOpenMPClauseName(OMPC_firstprivate) << Type << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); Modified: cfe/trunk/test/OpenMP/taskloop_firstprivate_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/taskloop_firstprivate_messages.cpp?rev=266198&r1=266197&r2=266198&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/taskloop_firstprivate_messages.cpp (original) +++ cfe/trunk/test/OpenMP/taskloop_firstprivate_messages.cpp Wed Apr 13 08:36:48 2016 @@ -295,9 +295,9 @@ int main(int argc, char **argv) { #pragma omp taskloop firstprivate(i) // expected-note {{defined as firstprivate}} for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop' directive may not be firstprivate, predetermined as private}} foo(); -#pragma omp parallel reduction(+ : i) -#pragma omp taskloop firstprivate(i) // expected-note {{defined as firstprivate}} - for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop' directive may not be firstprivate, predetermined as private}} +#pragma omp parallel reduction(+ : i) // expected-note 4 {{defined as reduction}} +#pragma omp taskloop firstprivate(i) //expected-error {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}} + for (i = 0; i < argc; ++i) // expected-error 3 {{reduction variables may not be accessed in an explicit task}} foo(); #pragma omp parallel #pragma omp taskloop firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} Modified: cfe/trunk/test/OpenMP/taskloop_simd_firstprivate_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/taskloop_simd_firstprivate_messages.cpp?rev=266198&r1=266197&r2=266198&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/taskloop_simd_firstprivate_messages.cpp (original) +++ cfe/trunk/test/OpenMP/taskloop_simd_firstprivate_messages.cpp Wed Apr 13 08:36:48 2016 @@ -295,9 +295,9 @@ int main(int argc, char **argv) { #pragma omp taskloop simd firstprivate(i) // expected-note {{defined as firstprivate}} for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop simd' directive may not be firstprivate, predetermined as linear}} foo(); -#pragma omp parallel reduction(+ : i) -#pragma omp taskloop simd firstprivate(i) // expected-note {{defined as firstprivate}} - for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop simd' directive may not be firstprivate, predetermined as linear}} +#pragma omp parallel reduction(+ : i) // expected-note 4 {{defined as reduction}} +#pragma omp taskloop simd firstprivate(i) // expected-error {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}} + for (i = 0; i < argc; ++i) // expected-error 3 {{reduction variables may not be accessed in an explicit task}} foo(); #pragma omp parallel #pragma omp taskloop simd firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits