diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Stmt.cpp | 24 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Basic/OpenMPKinds.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 1 | ||||
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 66 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 11 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 8 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 1 |
13 files changed, 164 insertions, 7 deletions
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index 16e7d3c73f1..9cd3831bf26 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -1504,3 +1504,27 @@ OMPParallelForDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses, return new (Mem) OMPParallelForDirective(CollapsedNum, NumClauses); } +OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) { + unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = + C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); + OMPParallelSectionsDirective *Dir = + new (Mem) OMPParallelSectionsDirective(StartLoc, EndLoc, Clauses.size()); + Dir->setClauses(Clauses); + Dir->setAssociatedStmt(AssociatedStmt); + return Dir; +} + +OMPParallelSectionsDirective * +OMPParallelSectionsDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell) { + unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = + C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *)); + return new (Mem) OMPParallelSectionsDirective(NumClauses); +} + diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 9e88ca91186..1d01e655655 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -820,6 +820,12 @@ void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) { PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPParallelSectionsDirective( + OMPParallelSectionsDirective *Node) { + Indent() << "#pragma omp parallel sections "; + PrintOMPExecutableDirective(Node); +} + //===----------------------------------------------------------------------===// // Expr printing methods. //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 73ec8d733a6..db691a93edb 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -385,6 +385,11 @@ StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) { VisitOMPExecutableDirective(S); } +void StmtProfiler::VisitOMPParallelSectionsDirective( + const OMPParallelSectionsDirective *S) { + VisitOMPExecutableDirective(S); +} + void StmtProfiler::VisitExpr(const Expr *S) { VisitStmt(S); } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 6107de16726..b48c02ca266 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -227,6 +227,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, break; } break; + case OMPD_parallel_sections: + switch (CKind) { +#define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; case OMPD_unknown: case OMPD_threadprivate: case OMPD_task: @@ -243,13 +253,13 @@ bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_for || DKind == OMPD_sections || DKind == OMPD_section || - DKind == OMPD_single || - DKind == OMPD_parallel_for; // TODO add next directives. + DKind == OMPD_single || DKind == OMPD_parallel_for || + DKind == OMPD_parallel_sections; // TODO add next directives. } bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) { - return DKind == OMPD_parallel || - DKind == OMPD_parallel_for; // TODO add next directives. + return DKind == OMPD_parallel || DKind == OMPD_parallel_for || + DKind == OMPD_parallel_sections; // TODO add next directives. } bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) { diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 72dd17f5195..cd86eeb1216 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -197,6 +197,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::OMPParallelForDirectiveClass: EmitOMPParallelForDirective(cast<OMPParallelForDirective>(*S)); break; + case Stmt::OMPParallelSectionsDirectiveClass: + EmitOMPParallelSectionsDirective(cast<OMPParallelSectionsDirective>(*S)); + break; } } diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 46c1d783c2e..e253efc2cb3 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -95,3 +95,8 @@ CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) { llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet."); } +void CodeGenFunction::EmitOMPParallelSectionsDirective( + const OMPParallelSectionsDirective &) { + llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet."); +} + diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 6aa3f9a0691..c04fc3e9e70 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1904,6 +1904,7 @@ public: void EmitOMPSectionDirective(const OMPSectionDirective &S); void EmitOMPSingleDirective(const OMPSingleDirective &S); void EmitOMPParallelForDirective(const OMPParallelForDirective &S); + void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S); //===--------------------------------------------------------------------===// // LValue Expression Emission diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index a6bc3a2c332..b3a1063ed23 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -40,6 +40,9 @@ static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) { if (SDKind == OMPD_for) { P.ConsumeToken(); DKind = OMPD_parallel_for; + } else if (SDKind == OMPD_sections) { + P.ConsumeToken(); + DKind = OMPD_parallel_sections; } } return DKind; @@ -85,6 +88,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() { case OMPD_section: case OMPD_single: case OMPD_parallel_for: + case OMPD_parallel_sections: Diag(Tok, diag::err_omp_unexpected_directive) << getOpenMPDirectiveName(DKind); break; @@ -101,7 +105,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() { /// /// executable-directive: /// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' | -/// 'section' | 'single' | 'parallel for' {clause} annot_pragma_openmp_end +/// 'section' | 'single' | 'parallel for' | 'parallel sections' {clause} +/// annot_pragma_openmp_end /// StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() { assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); @@ -141,7 +146,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() { case OMPD_sections: case OMPD_single: case OMPD_section: - case OMPD_parallel_for: { + case OMPD_parallel_for: + case OMPD_parallel_sections: { ConsumeToken(); if (isOpenMPLoopDirective(DKind)) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 5ce0c84f84a..a7ad809778d 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -976,6 +976,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { Params); break; } + case OMPD_parallel_sections: { + Sema::CapturedParamNameType Params[] = { + std::make_pair(StringRef(), QualType()) // __context with shared vars + }; + ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, + Params); + break; + } case OMPD_threadprivate: case OMPD_task: llvm_unreachable("OpenMP Directive is not allowed"); @@ -998,6 +1006,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel | section | + | // | parallel | single | * | // | parallel | parallel for | * | + // | parallel |parallel sections| * | // +------------------+-----------------+------------------------------------+ // | for | parallel | * | // | for | for | + | @@ -1006,6 +1015,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | for | section | + | // | for | single | + | // | for | parallel for | * | + // | for |parallel sections| * | // +------------------+-----------------+------------------------------------+ // | simd | parallel | | // | simd | for | | @@ -1014,6 +1024,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | simd | section | | // | simd | single | | // | simd | parallel for | | + // | simd |parallel sections| | // +------------------+-----------------+------------------------------------+ // | sections | parallel | * | // | sections | for | + | @@ -1022,6 +1033,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | sections | section | * | // | sections | single | + | // | sections | parallel for | * | + // | sections |parallel sections| * | // +------------------+-----------------+------------------------------------+ // | section | parallel | * | // | section | for | + | @@ -1030,6 +1042,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | section | section | + | // | section | single | + | // | section | parallel for | * | + // | section |parallel sections| * | // +------------------+-----------------+------------------------------------+ // | single | parallel | * | // | single | for | + | @@ -1038,6 +1051,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | single | section | + | // | single | single | + | // | single | parallel for | * | + // | single |parallel sections| * | // +------------------+-----------------+------------------------------------+ // | parallel for | parallel | * | // | parallel for | for | + | @@ -1046,6 +1060,16 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel for | section | + | // | parallel for | single | + | // | parallel for | parallel for | * | + // | parallel for |parallel sections| * | + // +------------------+-----------------+------------------------------------+ + // | parallel sections| parallel | * | + // | parallel sections| for | + | + // | parallel sections| simd | * | + // | parallel sections| sections | + | + // | parallel sections| section | * | + // | parallel sections| single | + | + // | parallel sections| parallel for | * | + // | parallel sections|parallel sections| * | // +------------------+-----------------+------------------------------------+ if (Stack->getCurScope()) { auto ParentRegion = Stack->getParentDirective(); @@ -1063,7 +1087,8 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // Orphaned section directives are prohibited. That is, the section // directives must appear within the sections construct and must not be // encountered elsewhere in the sections region. - if (ParentRegion != OMPD_sections) { + if (ParentRegion != OMPD_sections && + ParentRegion != OMPD_parallel_sections) { SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) << (ParentRegion != OMPD_unknown) << getOpenMPDirectiveName(ParentRegion); @@ -1155,6 +1180,10 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); break; + case OMPD_parallel_sections: + Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, + StartLoc, EndLoc); + break; case OMPD_threadprivate: case OMPD_task: llvm_unreachable("OpenMP Directive is not allowed"); @@ -1834,6 +1863,41 @@ StmtResult Sema::ActOnOpenMPParallelForDirective( NestedLoopCount, Clauses, AStmt); } +StmtResult +Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc) { + assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + auto BaseStmt = AStmt; + while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) + BaseStmt = CS->getCapturedStmt(); + if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { + auto S = C->children(); + if (!S) + return StmtError(); + // All associated statements must be '#pragma omp section' except for + // the first one. + for (++S; S; ++S) { + auto SectionStmt = *S; + if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { + if (SectionStmt) + Diag(SectionStmt->getLocStart(), + diag::err_omp_parallel_sections_substmt_not_section); + return StmtError(); + } + } + } else { + Diag(AStmt->getLocStart(), + diag::err_omp_parallel_sections_not_compound_stmt); + return StmtError(); + } + + getCurFunction()->setHasBranchProtectedScope(); + + return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc, + Clauses, AStmt); +} + OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 7a5cc3cb731..5626ad59241 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -6494,6 +6494,17 @@ StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective( return Res; } +template <typename Derived> +StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective( + OMPParallelSectionsDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_sections, DirName, + nullptr, D->getLocStart()); + StmtResult Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().EndOpenMPDSABlock(Res.get()); + return Res; +} + //===----------------------------------------------------------------------===// // OpenMP clause transformation //===----------------------------------------------------------------------===// diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 249a4b23c9e..cee2aa23b98 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1950,6 +1950,14 @@ void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) { VisitOMPExecutableDirective(D); } +void ASTStmtReader::VisitOMPParallelSectionsDirective( + OMPParallelSectionsDirective *D) { + VisitStmt(D); + // The NumClauses field was read in ReadStmtFromStream. + ++Idx; + VisitOMPExecutableDirective(D); +} + //===----------------------------------------------------------------------===// // ASTReader Implementation //===----------------------------------------------------------------------===// @@ -2470,6 +2478,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; } + case STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE: + S = OMPParallelSectionsDirective::CreateEmpty( + Context, Record[ASTStmtReader::NumStmtFields], Empty); + break; + case EXPR_CXX_OPERATOR_CALL: S = new (Context) CXXOperatorCallExpr(Context, Empty); break; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index e1bce17c6fd..8f0c69e4318 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1859,6 +1859,14 @@ void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) { Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE; } +void ASTStmtWriter::VisitOMPParallelSectionsDirective( + OMPParallelSectionsDirective *D) { + VisitStmt(D); + Record.push_back(D->getNumClauses()); + VisitOMPExecutableDirective(D); + Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE; +} + //===----------------------------------------------------------------------===// // ASTWriter Implementation //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 15913f52a72..9b7e746b1c6 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -738,6 +738,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPSectionDirectiveClass: case Stmt::OMPSingleDirectiveClass: case Stmt::OMPParallelForDirectiveClass: + case Stmt::OMPParallelSectionsDirectiveClass: llvm_unreachable("Stmt should not be in analyzer evaluation loop"); case Stmt::ObjCSubscriptRefExprClass: |