From: Alexey Bataev Date: Wed, 22 Nov 2017 20:19:50 +0000 (+0000) Subject: [OPENMP] Add support for cancel constructs in [teams] distribute X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=058809db8ecd355548e166fccd7b80f682524bde;p=clang [OPENMP] Add support for cancel constructs in [teams] distribute parallel for directives. Added codegen/sema support for cancel constructs in [teams] distribute parallel for directives. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@318872 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index beb7b6034c..d26c4bdb30 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -3033,6 +3033,8 @@ public: /// class OMPDistributeParallelForDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// true if the construct has inner cancel directive. + bool HasCancel = false; /// \brief Build directive with the given start and end location. /// @@ -3046,7 +3048,7 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective { unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, OMPD_distribute_parallel_for, StartLoc, EndLoc, - CollapsedNum, NumClauses) {} + CollapsedNum, NumClauses), HasCancel(false) {} /// \brief Build an empty directive. /// @@ -3057,7 +3059,11 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective { unsigned NumClauses) : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, OMPD_distribute_parallel_for, SourceLocation(), - SourceLocation(), CollapsedNum, NumClauses) {} + SourceLocation(), CollapsedNum, NumClauses), + HasCancel(false) {} + + /// Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -3069,11 +3075,12 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs); + Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); /// \brief Creates an empty directive with the place /// for \a NumClauses clauses. @@ -3087,6 +3094,9 @@ public: unsigned CollapsedNum, EmptyShell); + /// Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; } @@ -3583,6 +3593,8 @@ public: /// class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { friend class ASTStmtReader; + /// true if the construct has inner cancel directive. + bool HasCancel = false; /// Build directive with the given start and end location. /// @@ -3597,7 +3609,7 @@ class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { unsigned NumClauses) : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass, OMPD_teams_distribute_parallel_for, StartLoc, EndLoc, - CollapsedNum, NumClauses) {} + CollapsedNum, NumClauses), HasCancel(false) {} /// Build an empty directive. /// @@ -3608,7 +3620,11 @@ class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { unsigned NumClauses) : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass, OMPD_teams_distribute_parallel_for, SourceLocation(), - SourceLocation(), CollapsedNum, NumClauses) {} + SourceLocation(), CollapsedNum, NumClauses), + HasCancel(false) {} + + /// Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// Creates directive with a list of \a Clauses. @@ -3620,11 +3636,12 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs); + Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); /// Creates an empty directive with the place for \a NumClauses clauses. /// @@ -3636,6 +3653,9 @@ public: CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell); + /// Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; } diff --git a/lib/AST/StmtOpenMP.cpp b/lib/AST/StmtOpenMP.cpp index af90ea531d..c0e9e72cfb 100644 --- a/lib/AST/StmtOpenMP.cpp +++ b/lib/AST/StmtOpenMP.cpp @@ -1035,7 +1035,7 @@ OMPTargetUpdateDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, OMPDistributeParallelForDirective *OMPDistributeParallelForDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, Stmt *AssociatedStmt, - const HelperExprs &Exprs) { + const HelperExprs &Exprs, bool HasCancel) { unsigned Size = llvm::alignTo(sizeof(OMPDistributeParallelForDirective), alignof(OMPClause *)); void *Mem = C.Allocate( @@ -1079,6 +1079,7 @@ OMPDistributeParallelForDirective *OMPDistributeParallelForDirective::Create( Dir->setCombinedCond(Exprs.DistCombinedFields.Cond); Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB); Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB); + Dir->HasCancel = HasCancel; return Dir; } @@ -1479,7 +1480,7 @@ OMPTeamsDistributeParallelForDirective * OMPTeamsDistributeParallelForDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, Stmt *AssociatedStmt, - const HelperExprs &Exprs) { + const HelperExprs &Exprs, bool HasCancel) { auto Size = llvm::alignTo(sizeof(OMPTeamsDistributeParallelForDirective), alignof(OMPClause *)); void *Mem = C.Allocate( @@ -1523,6 +1524,7 @@ OMPTeamsDistributeParallelForDirective::Create( Dir->setCombinedCond(Exprs.DistCombinedFields.Cond); Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB); Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB); + Dir->HasCancel = HasCancel; return Dir; } diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index 697367f793..7942189b87 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -2008,13 +2008,24 @@ emitInnerParallelForWhenCombined(CodeGenFunction &CGF, CodeGenFunction::JumpDest LoopExit) { auto &&CGInlinedWorksharingLoop = [&S](CodeGenFunction &CGF, PrePostActionTy &) { + bool HasCancel = false; + if (!isOpenMPSimdDirective(S.getDirectiveKind())) { + if (const auto *D = dyn_cast(&S)) + HasCancel = D->hasCancel(); + else if (const auto *D = dyn_cast(&S)) + HasCancel = D->hasCancel(); + } + CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, S.getDirectiveKind(), + HasCancel); CGF.EmitOMPWorksharingLoop(S, S.getPrevEnsureUpperBound(), emitDistributeParallelForInnerBounds, emitDistributeParallelForDispatchBounds); }; emitCommonOMPParallelDirective( - CGF, S, OMPD_for, CGInlinedWorksharingLoop, + CGF, S, + isOpenMPSimdDirective(S.getDirectiveKind()) ? OMPD_for_simd : OMPD_for, + CGInlinedWorksharingLoop, emitDistributeParallelForDistributeInnerBoundParams); } @@ -2025,10 +2036,8 @@ void CodeGenFunction::EmitOMPDistributeParallelForDirective( S.getDistInc()); }; OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); - OMPCancelStackRAII CancelRegion(*this, OMPD_distribute_parallel_for, - /*HasCancel=*/false); CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen, - /*HasCancel=*/false); + S.hasCancel()); } void CodeGenFunction::EmitOMPDistributeParallelForSimdDirective( @@ -3903,8 +3912,8 @@ void CodeGenFunction::EmitOMPTeamsDistributeParallelForDirective( OMPPrivateScope PrivateScope(CGF); CGF.EmitOMPReductionClauseInit(S, PrivateScope); (void)PrivateScope.Privatize(); - CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute, - CodeGenDistribute); + CGF.CGM.getOpenMPRuntime().emitInlinedDirective( + CGF, OMPD_distribute, CodeGenDistribute, S.hasCancel()); CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); }; emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_parallel_for, CodeGen); @@ -3939,7 +3948,8 @@ CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) { assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections || Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for || Kind == OMPD_distribute_parallel_for || - Kind == OMPD_target_parallel_for); + Kind == OMPD_target_parallel_for || + Kind == OMPD_teams_distribute_parallel_for); return OMPCancelStack.getExitBlock(); } diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 86ae474323..939d75bddc 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -2591,7 +2591,9 @@ static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, ParentRegion == OMPD_target_parallel)) || (CancelRegion == OMPD_for && (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || - ParentRegion == OMPD_target_parallel_for)) || + ParentRegion == OMPD_target_parallel_for || + ParentRegion == OMPD_distribute_parallel_for || + ParentRegion == OMPD_teams_distribute_parallel_for)) || (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || (CancelRegion == OMPD_sections && (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || @@ -6817,7 +6819,8 @@ StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( getCurFunction()->setHasBranchProtectedScope(); return OMPDistributeParallelForDirective::Create( - Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); + Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, + DSAStack->isCancelRegion()); } StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( @@ -7210,7 +7213,8 @@ StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( getCurFunction()->setHasBranchProtectedScope(); return OMPTeamsDistributeParallelForDirective::Create( - Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); + Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, + DSAStack->isCancelRegion()); } StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef Clauses, diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 2b8a10f174..a94b2e78e6 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -2920,6 +2920,7 @@ void ASTStmtReader::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) { void ASTStmtReader::VisitOMPDistributeParallelForDirective( OMPDistributeParallelForDirective *D) { VisitOMPLoopDirective(D); + D->setHasCancel(Record.readInt()); } void ASTStmtReader::VisitOMPDistributeParallelForSimdDirective( @@ -2959,6 +2960,7 @@ void ASTStmtReader::VisitOMPTeamsDistributeParallelForSimdDirective( void ASTStmtReader::VisitOMPTeamsDistributeParallelForDirective( OMPTeamsDistributeParallelForDirective *D) { VisitOMPLoopDirective(D); + D->setHasCancel(Record.readInt()); } void ASTStmtReader::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) { diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 15d2425713..a695dbd15e 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -2568,6 +2568,7 @@ void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) { void ASTStmtWriter::VisitOMPDistributeParallelForDirective( OMPDistributeParallelForDirective *D) { VisitOMPLoopDirective(D); + Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE; } @@ -2615,6 +2616,7 @@ void ASTStmtWriter::VisitOMPTeamsDistributeParallelForSimdDirective( void ASTStmtWriter::VisitOMPTeamsDistributeParallelForDirective( OMPTeamsDistributeParallelForDirective *D) { VisitOMPLoopDirective(D); + Record.push_back(D->hasCancel() ? 1 : 0); Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE; } diff --git a/test/OpenMP/distribute_parallel_for_codegen.cpp b/test/OpenMP/distribute_parallel_for_codegen.cpp index 62c38f1888..4fbca7d2f2 100644 --- a/test/OpenMP/distribute_parallel_for_codegen.cpp +++ b/test/OpenMP/distribute_parallel_for_codegen.cpp @@ -28,6 +28,7 @@ T tmain() { #pragma omp teams #pragma omp distribute parallel for for (int i = 0; i < n; ++i) { + #pragma omp cancel for a[i] = b[i] + c[i]; } diff --git a/test/OpenMP/distribute_parallel_for_messages.cpp b/test/OpenMP/distribute_parallel_for_messages.cpp index 35a61df39e..b61c4e7a46 100644 --- a/test/OpenMP/distribute_parallel_for_messages.cpp +++ b/test/OpenMP/distribute_parallel_for_messages.cpp @@ -116,3 +116,14 @@ void test_ordered() { ; } +void test_cancel() { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 16; ++i) + for (int j = 0; j < 16; ++j) { +#pragma omp cancel for + ; + } +} + diff --git a/test/OpenMP/teams_distribute_parallel_for_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_codegen.cpp index 0f31db0794..d2dd9aa8d6 100644 --- a/test/OpenMP/teams_distribute_parallel_for_codegen.cpp +++ b/test/OpenMP/teams_distribute_parallel_for_codegen.cpp @@ -32,6 +32,7 @@ int teams_argument_global(int n){ #pragma omp teams distribute parallel for num_teams(te), thread_limit(th) for(int i = 0; i < n; i++) { a[i] = 0; + #pragma omp cancel for } // CK1: call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)) diff --git a/test/OpenMP/teams_distribute_parallel_for_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_messages.cpp index 12010dc3dd..dd88abd566 100644 --- a/test/OpenMP/teams_distribute_parallel_for_messages.cpp +++ b/test/OpenMP/teams_distribute_parallel_for_messages.cpp @@ -107,3 +107,12 @@ void test_ordered() { ; } +void test_cancel() { +#pragma omp target +#pragma omp teams distribute parallel for + for (int i = 0; i < 16; ++i) { +#pragma omp cancel for + ; + } +} +