From: Alexey Bataev Date: Tue, 16 Feb 2016 11:18:12 +0000 (+0000) Subject: [OPENMP] Improved handling of pseudo-captured expressions in OpenMP. X-Git-Tag: llvmorg-3.9.0-rc1~14042 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3392d760816d869c9589c81275c7c98ecefc226d;p=platform%2Fupstream%2Fllvm.git [OPENMP] Improved handling of pseudo-captured expressions in OpenMP. Expressions inside 'schedule'|'dist_schedule' clause must be captured in combined directives to avoid possible crash during codegen. Patch improves handling of such constructs llvm-svn: 260954 --- diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 58765e7..3845c40 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -70,6 +70,28 @@ public: static bool classof(const OMPClause *) { return true; } }; +/// Class that handles pre-initialization statement for some clauses, like +/// 'shedule', 'firstprivate' etc. +class OMPClauseWithPreInit { + friend class OMPClauseReader; + /// Pre-initialization statement for the clause. + Stmt *PreInit; +protected: + /// Set pre-initialization statement for the clause. + void setPreInitStmt(Stmt *S) { PreInit = S; } + OMPClauseWithPreInit(const OMPClause *This) : PreInit(nullptr) { + assert(get(This) && "get is not tuned."); + } + +public: + /// Get pre-initialization statement for the clause. + const Stmt *getPreInitStmt() const { return PreInit; } + /// Get pre-initialization statement for the clause. + Stmt *getPreInitStmt() { return PreInit; } + static OMPClauseWithPreInit *get(OMPClause *C); + static const OMPClauseWithPreInit *get(const OMPClause *C); +}; + /// \brief This represents clauses with the list of variables like 'private', /// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the /// '#pragma omp ...' directives. @@ -650,7 +672,7 @@ public: /// In this example directive '#pragma omp for' has 'schedule' clause with /// arguments 'static' and '3'. /// -class OMPScheduleClause : public OMPClause { +class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { friend class OMPClauseReader; /// \brief Location of '('. SourceLocation LParenLoc; @@ -665,10 +687,8 @@ class OMPScheduleClause : public OMPClause { SourceLocation KindLoc; /// \brief Location of ',' (if any). SourceLocation CommaLoc; - /// \brief Chunk size and a reference to pseudo variable for combined - /// directives. - enum { CHUNK_SIZE, HELPER_CHUNK_SIZE, NUM_EXPRS }; - Stmt *ChunkSizes[NUM_EXPRS]; + /// \brief Chunk size. + Expr *ChunkSize; /// \brief Set schedule kind. /// @@ -730,12 +750,7 @@ class OMPScheduleClause : public OMPClause { /// /// \param E Chunk size. /// - void setChunkSize(Expr *E) { ChunkSizes[CHUNK_SIZE] = E; } - /// \brief Set helper chunk size. - /// - /// \param E Helper chunk size. - /// - void setHelperChunkSize(Expr *E) { ChunkSizes[HELPER_CHUNK_SIZE] = E; } + void setChunkSize(Expr *E) { ChunkSize = E; } public: /// \brief Build 'schedule' clause with schedule kind \a Kind and chunk size @@ -757,13 +772,13 @@ public: OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KLoc, SourceLocation CommaLoc, SourceLocation EndLoc, OpenMPScheduleClauseKind Kind, - Expr *ChunkSize, Expr *HelperChunkSize, + Expr *ChunkSize, Stmt *HelperChunkSize, OpenMPScheduleClauseModifier M1, SourceLocation M1Loc, OpenMPScheduleClauseModifier M2, SourceLocation M2Loc) - : OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc) { - ChunkSizes[CHUNK_SIZE] = ChunkSize; - ChunkSizes[HELPER_CHUNK_SIZE] = HelperChunkSize; + : OMPClause(OMPC_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), + ChunkSize(ChunkSize) { + setPreInitStmt(HelperChunkSize); Modifiers[FIRST] = M1; Modifiers[SECOND] = M2; ModifiersLoc[FIRST] = M1Loc; @@ -774,9 +789,8 @@ public: /// explicit OMPScheduleClause() : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()), - Kind(OMPC_SCHEDULE_unknown) { - ChunkSizes[CHUNK_SIZE] = nullptr; - ChunkSizes[HELPER_CHUNK_SIZE] = nullptr; + OMPClauseWithPreInit(this), Kind(OMPC_SCHEDULE_unknown), + ChunkSize(nullptr) { Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; } @@ -815,29 +829,18 @@ public: SourceLocation getCommaLoc() { return CommaLoc; } /// \brief Get chunk size. /// - Expr *getChunkSize() { return dyn_cast_or_null(ChunkSizes[CHUNK_SIZE]); } + Expr *getChunkSize() { return ChunkSize; } /// \brief Get chunk size. /// - Expr *getChunkSize() const { - return dyn_cast_or_null(ChunkSizes[CHUNK_SIZE]); - } - /// \brief Get helper chunk size. - /// - Expr *getHelperChunkSize() { - return dyn_cast_or_null(ChunkSizes[HELPER_CHUNK_SIZE]); - } - /// \brief Get helper chunk size. - /// - Expr *getHelperChunkSize() const { - return dyn_cast_or_null(ChunkSizes[HELPER_CHUNK_SIZE]); - } + const Expr *getChunkSize() const { return ChunkSize; } static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_schedule; } child_range children() { - return child_range(&ChunkSizes[CHUNK_SIZE], &ChunkSizes[CHUNK_SIZE] + 1); + return child_range(reinterpret_cast(&ChunkSize), + reinterpret_cast(&ChunkSize) + 1); } }; @@ -3218,7 +3221,7 @@ public: /// In this example directive '#pragma omp distribute' has 'dist_schedule' /// clause with arguments 'static' and '3'. /// -class OMPDistScheduleClause : public OMPClause { +class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { friend class OMPClauseReader; /// \brief Location of '('. SourceLocation LParenLoc; @@ -3228,10 +3231,8 @@ class OMPDistScheduleClause : public OMPClause { SourceLocation KindLoc; /// \brief Location of ',' (if any). SourceLocation CommaLoc; - /// \brief Chunk size and a reference to pseudo variable for combined - /// directives. - enum { CHUNK_SIZE, HELPER_CHUNK_SIZE, NUM_EXPRS }; - Stmt *ChunkSizes[NUM_EXPRS]; + /// \brief Chunk size. + Expr *ChunkSize; /// \brief Set schedule kind. /// @@ -3257,12 +3258,7 @@ class OMPDistScheduleClause : public OMPClause { /// /// \param E Chunk size. /// - void setChunkSize(Expr *E) { ChunkSizes[CHUNK_SIZE] = E; } - /// \brief Set helper chunk size. - /// - /// \param E Helper chunk size. - /// - void setHelperChunkSize(Expr *E) { ChunkSizes[HELPER_CHUNK_SIZE] = E; } + void setChunkSize(Expr *E) { ChunkSize = E; } public: /// \brief Build 'dist_schedule' clause with schedule kind \a Kind and chunk @@ -3281,21 +3277,19 @@ public: SourceLocation KLoc, SourceLocation CommaLoc, SourceLocation EndLoc, OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, - Expr *HelperChunkSize) - : OMPClause(OMPC_dist_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc) { - ChunkSizes[CHUNK_SIZE] = ChunkSize; - ChunkSizes[HELPER_CHUNK_SIZE] = HelperChunkSize; + Stmt *HelperChunkSize) + : OMPClause(OMPC_dist_schedule, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), + KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { + setPreInitStmt(HelperChunkSize); } /// \brief Build an empty clause. /// explicit OMPDistScheduleClause() : OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()), - Kind(OMPC_DIST_SCHEDULE_unknown) { - ChunkSizes[CHUNK_SIZE] = nullptr; - ChunkSizes[HELPER_CHUNK_SIZE] = nullptr; - } + OMPClauseWithPreInit(this), Kind(OMPC_DIST_SCHEDULE_unknown), + ChunkSize(nullptr) {} /// \brief Get kind of the clause. /// @@ -3311,31 +3305,18 @@ public: SourceLocation getCommaLoc() { return CommaLoc; } /// \brief Get chunk size. /// - Expr *getChunkSize() { - return dyn_cast_or_null(ChunkSizes[CHUNK_SIZE]); - } + Expr *getChunkSize() { return ChunkSize; } /// \brief Get chunk size. /// - Expr *getChunkSize() const { - return dyn_cast_or_null(ChunkSizes[CHUNK_SIZE]); - } - /// \brief Get helper chunk size. - /// - Expr *getHelperChunkSize() { - return dyn_cast_or_null(ChunkSizes[HELPER_CHUNK_SIZE]); - } - /// \brief Get helper chunk size. - /// - Expr *getHelperChunkSize() const { - return dyn_cast_or_null(ChunkSizes[HELPER_CHUNK_SIZE]); - } + const Expr *getChunkSize() const { return ChunkSize; } static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_dist_schedule; } child_range children() { - return child_range(&ChunkSizes[CHUNK_SIZE], &ChunkSizes[CHUNK_SIZE] + 1); + return child_range(reinterpret_cast(&ChunkSize), + reinterpret_cast(&ChunkSize) + 1); } }; diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 442882a..904609a 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2549,7 +2549,7 @@ template bool RecursiveASTVisitor::VisitOMPScheduleClause(OMPScheduleClause *C) { TRY_TO(TraverseStmt(C->getChunkSize())); - TRY_TO(TraverseStmt(C->getHelperChunkSize())); + TRY_TO(TraverseStmt(C->getPreInitStmt())); return true; } @@ -2819,7 +2819,7 @@ template bool RecursiveASTVisitor::VisitOMPDistScheduleClause( OMPDistScheduleClause *C) { TRY_TO(TraverseStmt(C->getChunkSize())); - TRY_TO(TraverseStmt(C->getHelperChunkSize())); + TRY_TO(TraverseStmt(C->getPreInitStmt())); return true; } diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 1d1da53..284ef81 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -29,6 +29,65 @@ OMPClause::child_range OMPClause::children() { llvm_unreachable("unknown OMPClause"); } +OMPClauseWithPreInit *OMPClauseWithPreInit::get(OMPClause *C) { + auto *Res = OMPClauseWithPreInit::get(const_cast(C)); + return Res ? const_cast(Res) : nullptr; +} + +const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { + switch (C->getClauseKind()) { + case OMPC_schedule: + return static_cast(C); + case OMPC_dist_schedule: + return static_cast(C); + case OMPC_default: + case OMPC_proc_bind: + case OMPC_if: + case OMPC_final: + case OMPC_num_threads: + case OMPC_safelen: + case OMPC_simdlen: + case OMPC_collapse: + case OMPC_private: + case OMPC_firstprivate: + case OMPC_lastprivate: + case OMPC_shared: + case OMPC_reduction: + case OMPC_linear: + case OMPC_aligned: + case OMPC_copyin: + case OMPC_copyprivate: + case OMPC_ordered: + case OMPC_nowait: + case OMPC_untied: + case OMPC_mergeable: + case OMPC_threadprivate: + case OMPC_flush: + case OMPC_read: + case OMPC_write: + case OMPC_update: + case OMPC_capture: + case OMPC_seq_cst: + case OMPC_depend: + case OMPC_device: + case OMPC_threads: + case OMPC_simd: + case OMPC_map: + case OMPC_num_teams: + case OMPC_thread_limit: + case OMPC_priority: + case OMPC_grainsize: + case OMPC_nogroup: + case OMPC_num_tasks: + case OMPC_hint: + case OMPC_defaultmap: + case OMPC_unknown: + break; + } + + return nullptr; +} + void OMPPrivateClause::setPrivateCopies(ArrayRef VL) { assert(VL.size() == varlist_size() && "Number of private copies is not the same as the preallocated buffer"); diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 3ee63e0..5013fa6 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -664,9 +664,16 @@ void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) { OS << ": "; } OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind()); - if (Node->getChunkSize()) { + if (auto *E = Node->getChunkSize()) { OS << ", "; - Node->getChunkSize()->printPretty(OS, nullptr, Policy); + if (Node->getPreInitStmt()) { + cast( + cast(E->IgnoreImpCasts())->getDecl()) + ->getInit() + ->IgnoreImpCasts() + ->printPretty(OS, nullptr, Policy); + } else + E->printPretty(OS, nullptr, Policy); } OS << ")"; } @@ -769,7 +776,7 @@ void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) { OS << (I == Node->varlist_begin() ? StartSym : ','); if (DeclRefExpr *DRE = dyn_cast(*I)) { if (auto *CED = dyn_cast(DRE->getDecl())) - CED->getInit()->printPretty(OS, nullptr, Policy, 0); + CED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy, 0); else DRE->getDecl()->printQualifiedName(OS); } else @@ -915,9 +922,16 @@ void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) { void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) { OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName( OMPC_dist_schedule, Node->getDistScheduleKind()); - if (Node->getChunkSize()) { + if (auto *E = Node->getChunkSize()) { OS << ", "; - Node->getChunkSize()->printPretty(OS, nullptr, Policy); + if (Node->getPreInitStmt()) { + cast( + cast(E->IgnoreImpCasts())->getDecl()) + ->getInit() + ->IgnoreImpCasts() + ->printPretty(OS, nullptr, Policy); + } else + E->printPretty(OS, nullptr, Policy); } OS << ")"; } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index d2f241c..02b5975 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -268,8 +268,15 @@ public: #define OPENMP_CLAUSE(Name, Class) \ void Visit##Class(const Class *C); #include "clang/Basic/OpenMPKinds.def" + void VistOMPClauseWithPreInit(const OMPClauseWithPreInit *C); }; +void OMPClauseProfiler::VistOMPClauseWithPreInit( + const OMPClauseWithPreInit *C) { + if (auto *S = C->getPreInitStmt()) + Profiler->VisitStmt(S); +} + void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) { if (C->getCondition()) Profiler->VisitStmt(C->getCondition()); @@ -305,12 +312,9 @@ void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { } void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { } void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) { - if (C->getChunkSize()) { - Profiler->VisitStmt(C->getChunkSize()); - if (C->getHelperChunkSize()) { - Profiler->VisitStmt(C->getChunkSize()); - } - } + VistOMPClauseWithPreInit(C); + if (auto *S = C->getChunkSize()) + Profiler->VisitStmt(S); } void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *C) { @@ -633,12 +637,9 @@ void StmtProfiler::VisitOMPDistributeDirective( void OMPClauseProfiler::VisitOMPDistScheduleClause( const OMPDistScheduleClause *C) { - if (C->getChunkSize()) { - Profiler->VisitStmt(C->getChunkSize()); - if (C->getHelperChunkSize()) { - Profiler->VisitStmt(C->getChunkSize()); - } - } + VistOMPClauseWithPreInit(C); + if (auto *S = C->getChunkSize()) + Profiler->VisitStmt(S); } void OMPClauseProfiler::VisitOMPDefaultmapClause(const OMPDefaultmapClause *) {} diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 1a9ff6e..e0d1a50 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "CGCleanup.h" #include "CGOpenMPRuntime.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" @@ -20,6 +21,45 @@ using namespace clang; using namespace CodeGen; +namespace { +/// Lexical scope for OpenMP executable constructs, that handles correct codegen +/// for captured expressions. +class OMPLexicalScope { + CodeGenFunction::LexicalScope Scope; + void emitPreInitStmt(CodeGenFunction &CGF, const OMPExecutableDirective &S) { + for (const auto *C : S.clauses()) { + if (auto *CPI = OMPClauseWithPreInit::get(C)) { + if (auto *PreInit = cast_or_null(CPI->getPreInitStmt())) { + for (const auto *I : PreInit->decls()) + CGF.EmitVarDecl(cast(*I)); + } + } + } + } + + class PostUpdateCleanup final : public EHScopeStack::Cleanup { + const OMPExecutableDirective &S; + + public: + PostUpdateCleanup(const OMPExecutableDirective &S) : S(S) {} + + void Emit(CodeGenFunction &CGF, Flags /*flags*/) override { + if (!CGF.HaveInsertPoint()) + return; + (void)S; + // TODO: add cleanups for clauses that require post update. + } + }; + +public: + OMPLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S) + : Scope(CGF, S.getSourceRange()) { + emitPreInitStmt(CGF, S); + CGF.EHStack.pushCleanup(NormalAndEHCleanup, S); + } +}; +} // namespace + llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) { auto &C = getContext(); llvm::Value *Size = nullptr; @@ -967,7 +1007,7 @@ static void emitCommonOMPParallelDirective(CodeGenFunction &CGF, } void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { - LexicalScope Scope(*this, S.getSourceRange()); + OMPLexicalScope Scope(*this, S); // Emit parallel region as a standalone region. auto &&CodeGen = [&S](CodeGenFunction &CGF) { OMPPrivateScope PrivateScope(CGF); @@ -1528,36 +1568,6 @@ namespace { }; } // namespace -static std::pair -emitScheduleClause(CodeGenFunction &CGF, const OMPLoopDirective &S, - bool OuterRegion) { - // Detect the loop schedule kind and chunk. - auto ScheduleKind = OMPC_SCHEDULE_unknown; - OpenMPScheduleClauseModifier M1 = OMPC_SCHEDULE_MODIFIER_unknown; - OpenMPScheduleClauseModifier M2 = OMPC_SCHEDULE_MODIFIER_unknown; - llvm::Value *Chunk = nullptr; - if (const auto *C = S.getSingleClause()) { - ScheduleKind = C->getScheduleKind(); - M1 = C->getFirstScheduleModifier(); - M2 = C->getSecondScheduleModifier(); - if (const auto *Ch = C->getChunkSize()) { - if (auto *ImpRef = cast_or_null(C->getHelperChunkSize())) { - if (OuterRegion) - CGF.EmitVarDecl(*cast(ImpRef->getDecl())); - else - Ch = ImpRef; - } - if (!C->getHelperChunkSize() || !OuterRegion) { - Chunk = CGF.EmitScalarExpr(Ch); - Chunk = CGF.EmitScalarConversion(Chunk, Ch->getType(), - S.getIterationVariable()->getType(), - S.getLocStart()); - } - } - } - return std::make_pair(Chunk, ScheduleKindModifiersTy(ScheduleKind, M1, M2)); -} - bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { // Emit the loop iteration variable. auto IVExpr = cast(S.getIterationVariable()); @@ -1627,14 +1637,21 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { (void)LoopScope.Privatize(); // Detect the loop schedule kind and chunk. - llvm::Value *Chunk; - OpenMPScheduleClauseKind ScheduleKind; - auto ScheduleInfo = - emitScheduleClause(*this, S, /*OuterRegion=*/false); - Chunk = ScheduleInfo.first; - ScheduleKind = ScheduleInfo.second.Kind; - const OpenMPScheduleClauseModifier M1 = ScheduleInfo.second.M1; - const OpenMPScheduleClauseModifier M2 = ScheduleInfo.second.M2; + llvm::Value *Chunk = nullptr; + OpenMPScheduleClauseKind ScheduleKind = OMPC_SCHEDULE_unknown; + OpenMPScheduleClauseModifier M1 = OMPC_SCHEDULE_MODIFIER_unknown; + OpenMPScheduleClauseModifier M2 = OMPC_SCHEDULE_MODIFIER_unknown; + if (auto *C = S.getSingleClause()) { + ScheduleKind = C->getScheduleKind(); + M1 = C->getFirstScheduleModifier(); + M2 = C->getSecondScheduleModifier(); + if (const auto *Ch = C->getChunkSize()) { + Chunk = EmitScalarExpr(Ch); + Chunk = EmitScalarConversion(Chunk, Ch->getType(), + S.getIterationVariable()->getType(), + S.getLocStart()); + } + } const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); const bool Ordered = S.getSingleClause() != nullptr; @@ -1704,13 +1721,15 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { } void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { - LexicalScope Scope(*this, S.getSourceRange()); bool HasLastprivates = false; - auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) { - HasLastprivates = CGF.EmitOMPWorksharingLoop(S); - }; - CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen, - S.hasCancel()); + { + OMPLexicalScope Scope(*this, S); + auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) { + HasLastprivates = CGF.EmitOMPWorksharingLoop(S); + }; + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen, + S.hasCancel()); + } // Emit an implicit barrier at the end. if (!S.getSingleClause() || HasLastprivates) { @@ -1719,12 +1738,14 @@ void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { } void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) { - LexicalScope Scope(*this, S.getSourceRange()); bool HasLastprivates = false; - auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) { - HasLastprivates = CGF.EmitOMPWorksharingLoop(S); - }; - CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); + { + OMPLexicalScope Scope(*this, S); + auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) { + HasLastprivates = CGF.EmitOMPWorksharingLoop(S); + }; + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); + } // Emit an implicit barrier at the end. if (!S.getSingleClause() || HasLastprivates) { @@ -1741,8 +1762,7 @@ static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty, return LVal; } -OpenMPDirectiveKind -CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { +void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { auto *Stmt = cast(S.getAssociatedStmt())->getCapturedStmt(); auto *CS = dyn_cast(Stmt); bool HasLastprivates = false; @@ -1865,20 +1885,22 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_unknown); } - return OMPD_sections; } void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) { - LexicalScope Scope(*this, S.getSourceRange()); - OpenMPDirectiveKind EmittedAs = EmitSections(S); + { + OMPLexicalScope Scope(*this, S); + EmitSections(S); + } // Emit an implicit barrier at the end. if (!S.getSingleClause()) { - CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), EmittedAs); + CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), + OMPD_sections); } } void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) { - LexicalScope Scope(*this, S.getSourceRange()); + OMPLexicalScope Scope(*this, S); auto &&CodeGen = [&S](CodeGenFunction &CGF) { CGF.EmitStmt(cast(S.getAssociatedStmt())->getCapturedStmt()); }; @@ -1903,22 +1925,27 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { AssignmentOps.append(C->assignment_ops().begin(), C->assignment_ops().end()); } - LexicalScope Scope(*this, S.getSourceRange()); - // Emit code for 'single' region along with 'copyprivate' clauses - auto &&CodeGen = [&S](CodeGenFunction &CGF) { - CodeGenFunction::OMPPrivateScope SingleScope(CGF); - (void)CGF.EmitOMPFirstprivateClause(S, SingleScope); - CGF.EmitOMPPrivateClause(S, SingleScope); - (void)SingleScope.Privatize(); + bool HasFirstprivates; + { + OMPLexicalScope Scope(*this, S); + // Emit code for 'single' region along with 'copyprivate' clauses + auto &&CodeGen = [&S, &HasFirstprivates](CodeGenFunction &CGF) { + CodeGenFunction::OMPPrivateScope SingleScope(CGF); + HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope); + CGF.EmitOMPPrivateClause(S, SingleScope); + (void)SingleScope.Privatize(); - CGF.EmitStmt(cast(S.getAssociatedStmt())->getCapturedStmt()); - }; - CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(), - CopyprivateVars, DestExprs, SrcExprs, - AssignmentOps); - // Emit an implicit barrier at the end (to avoid data race if no 'nowait' - // clause was specified and no 'copyprivate' clause). - if (!S.getSingleClause() && CopyprivateVars.empty()) { + CGF.EmitStmt( + cast(S.getAssociatedStmt())->getCapturedStmt()); + }; + CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(), + CopyprivateVars, DestExprs, + SrcExprs, AssignmentOps); + } + // Emit an implicit barrier at the end (to avoid data race on firstprivate + // init or if no 'nowait' clause was specified and no 'copyprivate' clause). + if ((!S.getSingleClause() || HasFirstprivates) && + CopyprivateVars.empty()) { CGM.getOpenMPRuntime().emitBarrierCall( *this, S.getLocStart(), S.getSingleClause() ? OMPD_unknown : OMPD_single); @@ -1926,7 +1953,7 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { } void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { - LexicalScope Scope(*this, S.getSourceRange()); + OMPLexicalScope Scope(*this, S); auto &&CodeGen = [&S](CodeGenFunction &CGF) { CGF.EmitStmt(cast(S.getAssociatedStmt())->getCapturedStmt()); }; @@ -1934,7 +1961,7 @@ void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { } void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { - LexicalScope Scope(*this, S.getSourceRange()); + OMPLexicalScope Scope(*this, S); auto &&CodeGen = [&S](CodeGenFunction &CGF) { CGF.EmitStmt(cast(S.getAssociatedStmt())->getCapturedStmt()); }; @@ -1950,8 +1977,7 @@ void CodeGenFunction::EmitOMPParallelForDirective( const OMPParallelForDirective &S) { // Emit directive as a combined directive that consists of two implicit // directives: 'parallel' with 'for' directive. - LexicalScope Scope(*this, S.getSourceRange()); - (void)emitScheduleClause(*this, S, /*OuterRegion=*/true); + OMPLexicalScope Scope(*this, S); auto &&CodeGen = [&S](CodeGenFunction &CGF) { CGF.EmitOMPWorksharingLoop(S); }; @@ -1962,8 +1988,7 @@ void CodeGenFunction::EmitOMPParallelForSimdDirective( const OMPParallelForSimdDirective &S) { // Emit directive as a combined directive that consists of two implicit // directives: 'parallel' with 'for' directive. - LexicalScope Scope(*this, S.getSourceRange()); - (void)emitScheduleClause(*this, S, /*OuterRegion=*/true); + OMPLexicalScope Scope(*this, S); auto &&CodeGen = [&S](CodeGenFunction &CGF) { CGF.EmitOMPWorksharingLoop(S); }; @@ -1974,16 +1999,16 @@ void CodeGenFunction::EmitOMPParallelSectionsDirective( const OMPParallelSectionsDirective &S) { // Emit directive as a combined directive that consists of two implicit // directives: 'parallel' with 'sections' directive. - LexicalScope Scope(*this, S.getSourceRange()); + OMPLexicalScope Scope(*this, S); auto &&CodeGen = [&S](CodeGenFunction &CGF) { - (void)CGF.EmitSections(S); + CGF.EmitSections(S); }; emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen); } void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { // Emit outlined function for task construct. - LexicalScope Scope(*this, S.getSourceRange()); + OMPLexicalScope Scope(*this, S); auto CS = cast(S.getAssociatedStmt()); auto CapturedStruct = GenerateCapturedStmtArgument(*CS); auto *I = CS->getCapturedDecl()->param_begin(); @@ -2122,7 +2147,7 @@ void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) { void CodeGenFunction::EmitOMPTaskgroupDirective( const OMPTaskgroupDirective &S) { - LexicalScope Scope(*this, S.getSourceRange()); + OMPLexicalScope Scope(*this, S); auto &&CodeGen = [&S](CodeGenFunction &CGF) { CGF.EmitStmt(cast(S.getAssociatedStmt())->getCapturedStmt()); }; @@ -2157,7 +2182,7 @@ static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM, void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) { if (!S.getAssociatedStmt()) return; - LexicalScope Scope(*this, S.getSourceRange()); + OMPLexicalScope Scope(*this, S); auto *C = S.getSingleClause(); auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF) { if (C) { @@ -2616,7 +2641,7 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { } } - LexicalScope Scope(*this, S.getSourceRange()); + OMPLexicalScope Scope(*this, S); auto &&CodeGen = [&S, Kind, IsSeqCst, CS](CodeGenFunction &CGF) { CGF.EmitStopPoint(CS); EmitOMPAtomicExpr(CGF, Kind, IsSeqCst, S.isPostfixUpdate(), S.getX(), @@ -2627,7 +2652,7 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { } void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) { - LexicalScope Scope(*this, S.getSourceRange()); + OMPLexicalScope Scope(*this, S); const CapturedStmt &CS = *cast(S.getAssociatedStmt()); llvm::SmallVector CapturedVars; diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 55bbf48..1254a0f 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2392,7 +2392,7 @@ private: Address UB, Address ST, Address IL, llvm::Value *Chunk); /// \brief Emit code for sections directive. - OpenMPDirectiveKind EmitSections(const OMPExecutableDirective &S); + void EmitSections(const OMPExecutableDirective &S); public: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 41013c4..33f809b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1714,8 +1714,8 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { } } -static DeclRefExpr *buildCapture(Sema &S, IdentifierInfo *Id, - Expr *CaptureExpr) { +static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, + Expr *CaptureExpr) { ASTContext &C = S.getASTContext(); Expr *Init = CaptureExpr->IgnoreImpCasts(); QualType Ty = Init->getType(); @@ -1735,7 +1735,21 @@ static DeclRefExpr *buildCapture(Sema &S, IdentifierInfo *Id, S.CurContext->addHiddenDecl(CED); S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false, /*TypeMayContainAuto=*/true); - return buildDeclRefExpr(S, CED, Ty.getNonReferenceType(), SourceLocation()); + return CED; +} + +static DeclRefExpr *buildCapture(Sema &S, IdentifierInfo *Id, + Expr *CaptureExpr) { + auto *CD = buildCaptureDecl(S, Id, CaptureExpr); + return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), + SourceLocation()); +} + +static DeclRefExpr *buildCapture(Sema &S, StringRef Name, Expr *CaptureExpr) { + auto *CD = + buildCaptureDecl(S, &S.getASTContext().Idents.get(Name), CaptureExpr); + return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), + SourceLocation()); } StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, @@ -1763,18 +1777,15 @@ StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, } } DSAStack->setForceVarCapturing(/*V=*/false); - } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && - (Clause->getClauseKind() == OMPC_schedule || - Clause->getClauseKind() == OMPC_dist_schedule)) { + } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { // Mark all variables in private list clauses as used in inner region. // Required for proper codegen of combined directives. // TODO: add processing for other clauses. - if (auto *SC = dyn_cast(Clause)) { - if (SC->getHelperChunkSize()) - MarkDeclarationsReferencedInExpr(SC->getHelperChunkSize()); - } else if (auto *DSC = dyn_cast(Clause)) { - if (DSC->getHelperChunkSize()) - MarkDeclarationsReferencedInExpr(DSC->getHelperChunkSize()); + if (auto *C = OMPClauseWithPreInit::get(Clause)) { + if (auto *S = cast_or_null(C->getPreInitStmt())) { + for (auto *D : S->decls()) + MarkVariableReferenced(D->getLocation(), cast(D)); + } } } if (Clause->getClauseKind() == OMPC_schedule) @@ -6740,7 +6751,7 @@ OMPClause *Sema::ActOnOpenMPScheduleClause( return nullptr; } Expr *ValExpr = ChunkSize; - Expr *HelperValExpr = nullptr; + Stmt *HelperValStmt = nullptr; if (ChunkSize) { if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && !ChunkSize->isInstantiationDependent() && @@ -6764,15 +6775,20 @@ OMPClause *Sema::ActOnOpenMPScheduleClause( return nullptr; } } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { - HelperValExpr = - buildCapture(*this, &Context.Idents.get(".chunk."), ValExpr); + ValExpr = buildCapture(*this, ".chunk.", ValExpr); + Decl *D = cast(ValExpr)->getDecl(); + HelperValStmt = + new (Context) DeclStmt(DeclGroupRef::Create(Context, &D, + /*NumDecls=*/1), + SourceLocation(), SourceLocation()); + ValExpr = DefaultLvalueConversion(ValExpr).get(); } } } return new (Context) OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, - ValExpr, HelperValExpr, M1, M1Loc, M2, M2Loc); + ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); } OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, @@ -9526,7 +9542,7 @@ OMPClause *Sema::ActOnOpenMPDistScheduleClause( return nullptr; } Expr *ValExpr = ChunkSize; - Expr *HelperValExpr = nullptr; + Stmt *HelperValStmt = nullptr; if (ChunkSize) { if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && !ChunkSize->isInstantiationDependent() && @@ -9550,15 +9566,20 @@ OMPClause *Sema::ActOnOpenMPDistScheduleClause( return nullptr; } } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { - HelperValExpr = - buildCapture(*this, &Context.Idents.get(".chunk."), ValExpr); + ValExpr = buildCapture(*this, ".chunk.", ValExpr); + Decl *D = cast(ValExpr)->getDecl(); + HelperValStmt = + new (Context) DeclStmt(DeclGroupRef::Create(Context, &D, + /*NumDecls=*/1), + SourceLocation(), SourceLocation()); + ValExpr = DefaultLvalueConversion(ValExpr).get(); } } } return new (Context) OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, - Kind, ValExpr, HelperValExpr); + Kind, ValExpr, HelperValStmt); } OMPClause *Sema::ActOnOpenMPDefaultmapClause( diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index f9c21e6..2328dea 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1749,9 +1749,10 @@ public: const ASTReader::RecordData &Record, unsigned &Idx) : Reader(R), Context(C), Record(Record), Idx(Idx) { } #define OPENMP_CLAUSE(Name, Class) \ - void Visit##Class(Class *S); + void Visit##Class(Class *C); #include "clang/Basic/OpenMPKinds.def" OMPClause *readClause(); + void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); }; } @@ -1892,6 +1893,10 @@ OMPClause *OMPClauseReader::readClause() { return C; } +void OMPClauseReader::VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C) { + C->setPreInitStmt(Reader->Reader.ReadSubStmt()); +} + void OMPClauseReader::VisitOMPIfClause(OMPIfClause *C) { C->setNameModifier(static_cast(Record[Idx++])); C->setNameModifierLoc(Reader->ReadSourceLocation(Record, Idx)); @@ -1940,6 +1945,7 @@ void OMPClauseReader::VisitOMPProcBindClause(OMPProcBindClause *C) { } void OMPClauseReader::VisitOMPScheduleClause(OMPScheduleClause *C) { + VisitOMPClauseWithPreInit(C); C->setScheduleKind( static_cast(Record[Idx++])); C->setFirstScheduleModifier( @@ -1947,7 +1953,6 @@ void OMPClauseReader::VisitOMPScheduleClause(OMPScheduleClause *C) { C->setSecondScheduleModifier( static_cast(Record[Idx++])); C->setChunkSize(Reader->Reader.ReadSubExpr()); - C->setHelperChunkSize(Reader->Reader.ReadSubExpr()); C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); C->setFirstScheduleModifierLoc(Reader->ReadSourceLocation(Record, Idx)); C->setSecondScheduleModifierLoc(Reader->ReadSourceLocation(Record, Idx)); @@ -2247,10 +2252,10 @@ void OMPClauseReader::VisitOMPHintClause(OMPHintClause *C) { } void OMPClauseReader::VisitOMPDistScheduleClause(OMPDistScheduleClause *C) { + VisitOMPClauseWithPreInit(C); C->setDistScheduleKind( static_cast(Record[Idx++])); C->setChunkSize(Reader->Reader.ReadSubExpr()); - C->setHelperChunkSize(Reader->Reader.ReadSubExpr()); C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); C->setDistScheduleKindLoc(Reader->ReadSourceLocation(Record, Idx)); C->setCommaLoc(Reader->ReadSourceLocation(Record, Idx)); @@ -2293,7 +2298,8 @@ void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) { D->setCond(Reader.ReadSubExpr()); D->setInit(Reader.ReadSubExpr()); D->setInc(Reader.ReadSubExpr()); - if (isOpenMPWorksharingDirective(D->getDirectiveKind())) { + if (isOpenMPWorksharingDirective(D->getDirectiveKind()) || + isOpenMPTaskLoopDirective(D->getDirectiveKind())) { D->setIsLastIterVariable(Reader.ReadSubExpr()); D->setLowerBoundVariable(Reader.ReadSubExpr()); D->setUpperBoundVariable(Reader.ReadSubExpr()); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 8a6d915..b409939 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1754,6 +1754,7 @@ public: void Visit##Class(Class *S); #include "clang/Basic/OpenMPKinds.def" void writeClause(OMPClause *C); + void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); }; } @@ -1764,6 +1765,10 @@ void OMPClauseWriter::writeClause(OMPClause *C) { Writer->Writer.AddSourceLocation(C->getLocEnd(), Record); } +void OMPClauseWriter::VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C) { + Writer->Writer.AddStmt(C->getPreInitStmt()); +} + void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) { Record.push_back(C->getNameModifier()); Writer->Writer.AddSourceLocation(C->getNameModifierLoc(), Record); @@ -1810,11 +1815,11 @@ void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) { } void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) { + VisitOMPClauseWithPreInit(C); Record.push_back(C->getScheduleKind()); Record.push_back(C->getFirstScheduleModifier()); Record.push_back(C->getSecondScheduleModifier()); Writer->Writer.AddStmt(C->getChunkSize()); - Writer->Writer.AddStmt(C->getHelperChunkSize()); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); Writer->Writer.AddSourceLocation(C->getFirstScheduleModifierLoc(), Record); Writer->Writer.AddSourceLocation(C->getSecondScheduleModifierLoc(), Record); @@ -2038,9 +2043,9 @@ void OMPClauseWriter::VisitOMPHintClause(OMPHintClause *C) { } void OMPClauseWriter::VisitOMPDistScheduleClause(OMPDistScheduleClause *C) { + VisitOMPClauseWithPreInit(C); Record.push_back(C->getDistScheduleKind()); Writer->Writer.AddStmt(C->getChunkSize()); - Writer->Writer.AddStmt(C->getHelperChunkSize()); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); Writer->Writer.AddSourceLocation(C->getDistScheduleKindLoc(), Record); Writer->Writer.AddSourceLocation(C->getCommaLoc(), Record); @@ -2080,7 +2085,8 @@ void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) { Writer.AddStmt(D->getCond()); Writer.AddStmt(D->getInit()); Writer.AddStmt(D->getInc()); - if (isOpenMPWorksharingDirective(D->getDirectiveKind())) { + if (isOpenMPWorksharingDirective(D->getDirectiveKind()) || + isOpenMPTaskLoopDirective(D->getDirectiveKind())) { Writer.AddStmt(D->getIsLastIterVariable()); Writer.AddStmt(D->getLowerBoundVariable()); Writer.AddStmt(D->getUpperBoundVariable()); diff --git a/clang/test/OpenMP/parallel_num_threads_codegen.cpp b/clang/test/OpenMP/parallel_num_threads_codegen.cpp index d744e5e..ae6409f 100644 --- a/clang/test/OpenMP/parallel_num_threads_codegen.cpp +++ b/clang/test/OpenMP/parallel_num_threads_codegen.cpp @@ -72,11 +72,11 @@ int main() { // CHECK: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEF_LOC_2]]) // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 1) // CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call( -// CHECK: call {{.*}} [[S_TY_CONSTR]]([[S_TY]]* [[S_TEMP:%.+]], [[INTPTR_T_TY]] [[INTPTR_T_TY_ATTR]]23) +// CHECK: invoke {{.*}} [[S_TY_CONSTR]]([[S_TY]]* [[S_TEMP:%.+]], [[INTPTR_T_TY]] [[INTPTR_T_TY_ATTR]]23) // CHECK: [[S_CHAR_OP:%.+]] = invoke{{.*}} i8 [[S_TY_CHAR_OP]]([[S_TY]]* [[S_TEMP]]) // CHECK: [[RES:%.+]] = sext {{.*}}i8 [[S_CHAR_OP]] to i32 // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 [[RES]]) -// CHECK: call {{.*}} [[S_TY_DESTR]]([[S_TY]]* [[S_TEMP]]) +// CHECK: {{(invoke|call)}} {{.*}} [[S_TY_DESTR]]([[S_TY]]* [[S_TEMP]]) // CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call( // CHECK: ret [[INT_TY]] 0 // CHECK: } diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 1526900..bb673d1 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2030,8 +2030,14 @@ public: #define OPENMP_CLAUSE(Name, Class) \ void Visit##Class(const Class *C); #include "clang/Basic/OpenMPKinds.def" + void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C); }; +void OMPClauseEnqueue::VisitOMPClauseWithPreInit( + const OMPClauseWithPreInit *C) { + Visitor->AddStmt(C->getPreInitStmt()); +} + void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) { Visitor->AddStmt(C->getCondition()); } @@ -2061,8 +2067,8 @@ void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { } void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { } void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) { + VisitOMPClauseWithPreInit(C); Visitor->AddStmt(C->getChunkSize()); - Visitor->AddStmt(C->getHelperChunkSize()); } void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) { @@ -2227,11 +2233,11 @@ void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) { } void OMPClauseEnqueue::VisitOMPDistScheduleClause( const OMPDistScheduleClause *C) { + VisitOMPClauseWithPreInit(C); Visitor->AddStmt(C->getChunkSize()); - Visitor->AddStmt(C->getHelperChunkSize()); -} -void OMPClauseEnqueue::VisitOMPDefaultmapClause(const OMPDefaultmapClause *C) { } +void OMPClauseEnqueue::VisitOMPDefaultmapClause( + const OMPDefaultmapClause * /*C*/) {} } void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {