From f7de5eb2e62f77f2f6a7a3944f8b5a6fe85a25da Mon Sep 17 00:00:00 2001 From: Philippe Virouleau <philippe.virouleau@imag.fr> Date: Tue, 29 Mar 2016 14:18:28 +0200 Subject: [PATCH] Added 'init' clause to parallel directive. This specifies an algorithm for the initial ready tasks in the parallel section. --- include/clang/AST/OpenMPClause.h | 73 +++++++++++++++++++++++++ include/clang/AST/RecursiveASTVisitor.h | 5 ++ include/clang/Basic/OpenMPKinds.def | 14 +++++ include/clang/Basic/OpenMPKinds.h | 8 +++ include/clang/Sema/Sema.h | 7 +++ lib/AST/OpenMPClause.cpp | 4 ++ lib/AST/StmtPrinter.cpp | 6 ++ lib/AST/StmtProfile.cpp | 2 + lib/Basic/OpenMPKinds.cpp | 15 +++++ lib/CodeGen/CGOpenMPRuntime.cpp | 67 +++++++++++++++++++++++ lib/CodeGen/CGOpenMPRuntime.h | 9 +++ lib/CodeGen/CGStmtOpenMP.cpp | 15 +++++ lib/Parse/ParseOpenMP.cpp | 11 ++++ lib/Sema/SemaOpenMP.cpp | 25 +++++++++ lib/Sema/TreeTransform.h | 21 +++++++ lib/Serialization/ASTReaderStmt.cpp | 10 ++++ lib/Serialization/ASTWriterStmt.cpp | 6 ++ tools/libclang/CIndex.cpp | 2 + 18 files changed, 300 insertions(+) diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h index 209c255acee..2a20fdb854e 100644 --- a/include/clang/AST/OpenMPClause.h +++ b/include/clang/AST/OpenMPClause.h @@ -614,6 +614,79 @@ public: } }; +/// \brief This represents 'init' clause in the '#pragma omp paralle ...' +/// directive. +/// +/// \code +/// #pragma omp parallel init(cyclicnuma) +/// \endcode +/// In this example directive '#pragma omp parallel' has simple 'init' +/// clause with kind 'cyclicnuma'. +/// +class OMPInitClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief A kind of the 'init' clause. + OpenMPInitClauseKind Kind; + /// \brief Start location of the kind in source code. + SourceLocation KindKwLoc; + + /// \brief Set kind of the clause. + /// + /// \param K Kind of clause. + /// + void setInitKind(OpenMPInitClauseKind K) { Kind = K; } + + /// \brief Set clause kind location. + /// + /// \param KLoc Kind location. + /// + void setInitKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } + +public: + /// \brief Build 'init' clause with argument \a A ('runtime', 'rand', 'cyclic', + /// 'randnuma', 'cyclicnuma' or 'cyclicnumastrict'). + /// + /// \param A Argument of the clause (eg : 'runtime', 'rand'). + /// \param ALoc Starting location of the argument. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// + OMPInitClause(OpenMPInitClauseKind A, SourceLocation ALoc, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_init, StartLoc, EndLoc), LParenLoc(LParenLoc), + Kind(A), KindKwLoc(ALoc) {} + + /// \brief Build an empty clause. + /// + OMPInitClause() + : OMPClause(OMPC_init, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), Kind(OMPC_INIT_unknown), + KindKwLoc(SourceLocation()) {} + + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Returns kind of the clause. + OpenMPInitClauseKind getInitKind() const { return Kind; } + + /// \brief Returns location of clause kind. + SourceLocation getInitKindKwLoc() const { return KindKwLoc; } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_init; + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } +}; + /// \brief This represents 'proc_bind' clause in the '#pragma omp ...' /// directive. /// diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index c4bfdc98a7a..99a08f67d79 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -2656,6 +2656,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) { return true; } +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPInitClause(OMPInitClause *) { + return true; +} + template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) { diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def index d9fc5391c48..6894e7cf0c4 100644 --- a/include/clang/Basic/OpenMPKinds.def +++ b/include/clang/Basic/OpenMPKinds.def @@ -102,6 +102,9 @@ #ifndef OPENMP_PROC_BIND_KIND # define OPENMP_PROC_BIND_KIND(Name) #endif +#ifndef OPENMP_INIT_KIND +#define OPENMP_INIT_KIND(Name) +#endif #ifndef OPENMP_SCHEDULE_KIND #define OPENMP_SCHEDULE_KIND(Name) #endif @@ -231,12 +234,14 @@ OPENMP_CLAUSE(from, OMPFromClause) OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause) OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause) OPENMP_CLAUSE(affinity, OMPAffinityClause) +OPENMP_CLAUSE(init, OMPInitClause) // Clauses allowed for OpenMP directive 'parallel'. OPENMP_PARALLEL_CLAUSE(if) OPENMP_PARALLEL_CLAUSE(num_threads) OPENMP_PARALLEL_CLAUSE(default) OPENMP_PARALLEL_CLAUSE(proc_bind) +OPENMP_PARALLEL_CLAUSE(init) OPENMP_PARALLEL_CLAUSE(private) OPENMP_PARALLEL_CLAUSE(firstprivate) OPENMP_PARALLEL_CLAUSE(shared) @@ -310,6 +315,14 @@ OPENMP_SCHEDULE_KIND(guided) OPENMP_SCHEDULE_KIND(auto) OPENMP_SCHEDULE_KIND(runtime) +// Static attributes for 'init' clause. +OPENMP_INIT_KIND(runtime) +OPENMP_INIT_KIND(rand) +OPENMP_INIT_KIND(cyclic) +OPENMP_INIT_KIND(randnuma) +OPENMP_INIT_KIND(cyclicnuma) +OPENMP_INIT_KIND(cyclicnumastrict) + // Modifiers for 'schedule' clause. OPENMP_SCHEDULE_MODIFIER(monotonic) OPENMP_SCHEDULE_MODIFIER(nonmonotonic) @@ -628,6 +641,7 @@ OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned) #undef OPENMP_DEPEND_KIND #undef OPENMP_SCHEDULE_MODIFIER #undef OPENMP_SCHEDULE_KIND +#undef OPENMP_INIT_KIND #undef OPENMP_PROC_BIND_KIND #undef OPENMP_DEFAULT_KIND #undef OPENMP_DIRECTIVE diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h index 0a8e890b7c4..285ce0b5d8b 100644 --- a/include/clang/Basic/OpenMPKinds.h +++ b/include/clang/Basic/OpenMPKinds.h @@ -55,6 +55,14 @@ enum OpenMPProcBindClauseKind { OMPC_PROC_BIND_unknown }; +/// \brief OpenMP attributes for 'init' clause. +enum OpenMPInitClauseKind { +#define OPENMP_INIT_KIND(Name) \ + OMPC_INIT_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_INIT_unknown +}; + /// \brief OpenMP attributes for 'schedule' clause. enum OpenMPScheduleClauseKind { #define OPENMP_SCHEDULE_KIND(Name) \ diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 722e4bf1d0b..e713067733a 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -8333,6 +8333,13 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'init' clause. + OMPClause *ActOnOpenMPInitClause(OpenMPInitClauseKind Kind, + SourceLocation KindLoc, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + OMPClause *ActOnOpenMPSingleExprWithArgClause( OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp index d04ba727bb0..3f87b900123 100644 --- a/lib/AST/OpenMPClause.cpp +++ b/lib/AST/OpenMPClause.cpp @@ -80,6 +80,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { case OMPC_num_teams: case OMPC_thread_limit: case OMPC_priority: + case OMPC_affinity: + case OMPC_init: case OMPC_grainsize: case OMPC_nogroup: case OMPC_num_tasks: @@ -145,6 +147,8 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) case OMPC_num_teams: case OMPC_thread_limit: case OMPC_priority: + case OMPC_affinity: + case OMPC_init: case OMPC_grainsize: case OMPC_nogroup: case OMPC_num_tasks: diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 116ddde7348..6057b227e23 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -656,6 +656,12 @@ void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) { << ")"; } +void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) { + OS << "init(" + << getOpenMPSimpleClauseTypeName(OMPC_init, Node->getInitKind()) + << ")"; +} + void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) { OS << "schedule("; if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) { diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index f13c885b259..8a3daa128dd 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -320,6 +320,8 @@ void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { } void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { } +void OMPClauseProfiler::VisitOMPInitClause(const OMPInitClause *C) { } + void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) { VistOMPClauseWithPreInit(C); if (auto *S = C->getChunkSize()) diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp index 503db60f561..3bf9f113c89 100644 --- a/lib/Basic/OpenMPKinds.cpp +++ b/lib/Basic/OpenMPKinds.cpp @@ -89,6 +89,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, #define OPENMP_PROC_BIND_KIND(Name) .Case(#Name, OMPC_PROC_BIND_##Name) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_PROC_BIND_unknown); + case OMPC_init: + return llvm::StringSwitch<OpenMPInitClauseKind>(Str) +#define OPENMP_INIT_KIND(Name) .Case(#Name, OMPC_INIT_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_INIT_unknown); case OMPC_schedule: return llvm::StringSwitch<unsigned>(Str) #define OPENMP_SCHEDULE_KIND(Name) \ @@ -195,6 +200,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'proc_bind' clause type"); + case OMPC_init: + switch (Type) { + case OMPC_INIT_unknown: + return "unknown"; +#define OPENMP_INIT_KIND(Name) \ + case OMPC_INIT_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'init' clause type"); case OMPC_schedule: switch (Type) { case OMPC_SCHEDULE_unknown: diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp index ee692d27ae1..36a29e91919 100644 --- a/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/lib/CodeGen/CGOpenMPRuntime.cpp @@ -557,6 +557,10 @@ enum OpenMPRTLFunction { OMPRTL__kmpc_omp_taskyield, // Call to void __kmpc_omp_set_task_affinity(ident_t *, kmp_int32 affinity); OMPRTL__kmpc_omp_set_task_affinity, + // Call to void __kmpc_begin_push_init(int kind); + OMPRTL__kmpc_begin_push_init, + // Call to void __kmpc_end_push_init(); + OMPRTL__kmpc_end_push_init, // Call to kmp_int32 __kmpc_single(ident_t *, kmp_int32 global_tid); OMPRTL__kmpc_single, // Call to void __kmpc_end_single(ident_t *, kmp_int32 global_tid); @@ -1419,6 +1423,21 @@ CGOpenMPRuntime::createRuntimeFunction(unsigned Function) { RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_proc_bind"); break; } + case OMPRTL__kmpc_begin_push_init: { + // Build void __kmpc_begin_push_init(int init_kind) + llvm::Type *TypeParams[] = {CGM.IntTy}; + llvm::FunctionType *FnTy = + llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); + RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_begin_push_init"); + break; + } + case OMPRTL__kmpc_end_push_init: { + // Build void __kmpc_end_push_init() + llvm::FunctionType *FnTy = + llvm::FunctionType::get(CGM.VoidTy, /*isVarArg*/ false); + RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_push_init"); + break; + } case OMPRTL__kmpc_omp_task_with_deps: { // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid, // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list, @@ -2661,6 +2680,54 @@ void CGOpenMPRuntime::emitProcBindClause(CodeGenFunction &CGF, CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_proc_bind), Args); } +void CGOpenMPRuntime::emitBeginInitClause(CodeGenFunction &CGF, + OpenMPInitClauseKind Init) { + if (!CGF.HaveInsertPoint()) + return; + // Constants for proc bind value accepted by the runtime. + enum InitTy { + InitRuntime = 0, + InitRand, + InitCyclic, + InitRandNuma, + InitCyclicNuma, + InitCyclicNumaStrict + } RuntimeInit; + switch (Init) { + case OMPC_INIT_runtime: + RuntimeInit = InitRuntime; + break; + case OMPC_INIT_rand: + RuntimeInit = InitRand; + break; + case OMPC_INIT_cyclic: + RuntimeInit = InitCyclic; + break; + case OMPC_INIT_randnuma: + RuntimeInit = InitRandNuma; + break; + case OMPC_INIT_cyclicnuma: + RuntimeInit = InitCyclicNuma; + break; + case OMPC_INIT_cyclicnumastrict: + RuntimeInit = InitCyclicNumaStrict; + break; + case OMPC_INIT_unknown: + llvm_unreachable("Unsupported init value."); + } + // Build call __kmpc_begin_push_init(init) + llvm::Value *Args[] = { + llvm::ConstantInt::get(CGM.IntTy, RuntimeInit, /*isSigned=*/true)}; + CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_begin_push_init), Args); +} + +void CGOpenMPRuntime::emitEndInitClause(CodeGenFunction &CGF) { + if (!CGF.HaveInsertPoint()) + return; + // Build call __kmpc_end_push_init(init) + CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_end_push_init)); +} + void CGOpenMPRuntime::emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *>, SourceLocation Loc) { if (!CGF.HaveInsertPoint()) diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h index 270de8dd505..1f62bf1e9fe 100644 --- a/lib/CodeGen/CGOpenMPRuntime.h +++ b/lib/CodeGen/CGOpenMPRuntime.h @@ -749,6 +749,15 @@ public: OpenMPProcBindClauseKind ProcBind, SourceLocation Loc); + /// \brief Emit call to void __kmpc_begin_push_init(int init) + /// to generate code for begin 'init' clause. + virtual void emitBeginInitClause(CodeGenFunction &CGF, + OpenMPInitClauseKind Init); + + /// \brief Emit call to void __kmpc_end_push_init() + /// to generate code for end 'init' clause. + virtual void emitEndInitClause(CodeGenFunction &CGF); + /// \brief Returns address of the threadprivate variable for the current /// thread. /// \param VD Threadprivate variable. diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index f7ba30efc2d..678de8369aa 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -1232,8 +1232,22 @@ static void emitCommonOMPParallelDirective(CodeGenFunction &CGF, OMPLexicalScope Scope(CGF, S); llvm::SmallVector<llvm::Value *, 16> CapturedVars; CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); + + if (const auto *InitClause = S.getSingleClause<OMPInitClause>()) { + llvm::errs() << "Got an init : " << + getOpenMPSimpleClauseTypeName(OMPC_init, InitClause->getInitKind()) << "\n"; + CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); + CGF.CGM.getOpenMPRuntime().emitBeginInitClause( + CGF, InitClause->getInitKind()); + } + CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn, CapturedVars, IfCond); + + if (const auto *InitClause = S.getSingleClause<OMPInitClause>()) { + CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); + CGF.CGM.getOpenMPRuntime().emitEndInitClause(CGF); + } } void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { @@ -3220,6 +3234,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_copyprivate: case OMPC_flush: case OMPC_proc_bind: + case OMPC_init: case OMPC_schedule: case OMPC_ordered: case OMPC_nowait: diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index aadcb631a3e..f81938486ba 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -1133,6 +1133,17 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, ErrorFound = true; } + Clause = ParseOpenMPSimpleClause(CKind); + break; + case OMPC_init: + // Extension + // At most one init clause can appear on the directive. + if (!FirstClause) { + Diag(Tok, diag::err_omp_more_one_clause) + << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + ErrorFound = true; + } + Clause = ParseOpenMPSimpleClause(CKind); break; case OMPC_schedule: diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 8214b78c3f4..315d830c684 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -7258,6 +7258,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_if: case OMPC_default: case OMPC_proc_bind: + case OMPC_init: case OMPC_schedule: case OMPC_private: case OMPC_firstprivate: @@ -7532,6 +7533,11 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, LParenLoc, EndLoc); break; + case OMPC_init: + Res = ActOnOpenMPInitClause( + static_cast<OpenMPInitClauseKind>(Argument), ArgumentLoc, StartLoc, + LParenLoc, EndLoc); + break; case OMPC_if: case OMPC_final: case OMPC_num_threads: @@ -7653,6 +7659,22 @@ OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); } +OMPClause *Sema::ActOnOpenMPInitClause(OpenMPInitClauseKind Kind, + SourceLocation KindKwLoc, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + if (Kind == OMPC_INIT_unknown) { + Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) + << getListOfPossibleValues(OMPC_init, /*First=*/0, + /*Last=*/OMPC_INIT_unknown) + << getOpenMPClauseName(OMPC_init); + return nullptr; + } + return new (Context) + OMPInitClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); +} + OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -7697,6 +7719,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_collapse: case OMPC_default: case OMPC_proc_bind: + case OMPC_init: case OMPC_private: case OMPC_firstprivate: case OMPC_lastprivate: @@ -7906,6 +7929,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_copyprivate: case OMPC_default: case OMPC_proc_bind: + case OMPC_init: case OMPC_threadprivate: case OMPC_flush: case OMPC_depend: @@ -8059,6 +8083,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_collapse: case OMPC_default: case OMPC_proc_bind: + case OMPC_init: case OMPC_schedule: case OMPC_ordered: case OMPC_nowait: diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 752b7629b7f..47f856cd032 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1486,6 +1486,19 @@ public: StartLoc, LParenLoc, EndLoc); } + /// \brief Build a new OpenMP 'init' clause. + /// + /// By default, performs semantic analysis to build the new OpenMP clause. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPInitClause(OpenMPInitClauseKind Kind, + SourceLocation KindKwLoc, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPInitClause(Kind, KindKwLoc, + StartLoc, LParenLoc, EndLoc); + } + /// \brief Build a new OpenMP 'schedule' clause. /// /// By default, performs semantic analysis to build the new OpenMP clause. @@ -7715,6 +7728,14 @@ TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) { C->getLParenLoc(), C->getLocEnd()); } +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) { + return getDerived().RebuildOMPInitClause( + C->getInitKind(), C->getInitKindKwLoc(), C->getLocStart(), + C->getLParenLoc(), C->getLocEnd()); +} + template <typename Derived> OMPClause * TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) { diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index b87710592e9..9778f75251f 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -1806,6 +1806,9 @@ OMPClause *OMPClauseReader::readClause() { case OMPC_proc_bind: C = new (Context) OMPProcBindClause(); break; + case OMPC_init: + C = new (Context) OMPInitClause(); + break; case OMPC_schedule: C = new (Context) OMPScheduleClause(); break; @@ -2005,6 +2008,13 @@ void OMPClauseReader::VisitOMPProcBindClause(OMPProcBindClause *C) { C->setProcBindKindKwLoc(Reader->ReadSourceLocation(Record, Idx)); } +void OMPClauseReader::VisitOMPInitClause(OMPInitClause *C) { + C->setInitKind( + static_cast<OpenMPInitClauseKind>(Record[Idx++])); + C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); + C->setInitKindKwLoc(Reader->ReadSourceLocation(Record, Idx)); +} + void OMPClauseReader::VisitOMPScheduleClause(OMPScheduleClause *C) { VisitOMPClauseWithPreInit(C); C->setScheduleKind( diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 7e766b2daf1..fa2eeeea301 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -1846,6 +1846,12 @@ void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) { Record.AddSourceLocation(C->getProcBindKindKwLoc()); } +void OMPClauseWriter::VisitOMPInitClause(OMPInitClause *C) { + Record.push_back(C->getInitKind()); + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getInitKindKwLoc()); +} + void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) { VisitOMPClauseWithPreInit(C); Record.push_back(C->getScheduleKind()); diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index e872c78a515..654fab21298 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2090,6 +2090,8 @@ void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { } void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { } +void OMPClauseEnqueue::VisitOMPInitClause(const OMPInitClause *C) { } + void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) { VisitOMPClauseWithPreInit(C); Visitor->AddStmt(C->getChunkSize()); -- GitLab