diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h index 3e05e9e2498c0bb59371f4a846640ad27f6264b7..068a5a835182514dc0c75901e7157b9ada58eb1e 100644 --- a/include/clang/AST/OpenMPClause.h +++ b/include/clang/AST/OpenMPClause.h @@ -3745,55 +3745,105 @@ public: /// directive. /// /// \code -/// #pragma omp task affinity(n) +/// #pragma omp task affinity(numa:n,strict) /// \endcode -/// In this example directive '#pragma omp task' has clause 'affinity' with -/// single expression 'n'. +/// In this example directive '#pragma omp task' has clause 'affinity' to a +/// numa node determined by single expression 'n'. task has the strict binding +/// depending on the boolean expression 'strict' /// -class OMPAffinityClause : public OMPClause { +class OMPAffinityClause final + : public OMPVarListClause<OMPAffinityClause>, + private llvm::TrailingObjects<OMPAffinityClause, Expr *> { + friend TrailingObjects; + friend OMPVarListClause; friend class OMPClauseReader; - /// \brief Location of '('. - SourceLocation LParenLoc; - /// \brief Affinity number. - Stmt *Affinity; + /// \brief Affinity type (one of depend, numa, core). + OpenMPAffinityClauseKind AffKind; + /// \brief Affinity type location. + SourceLocation AffLoc; + /// \brief Colon location. + SourceLocation ColonLoc; /// \brief Set the Affinity number. /// /// \param E Affinity number. /// - void setAffinity(Expr *E) { Affinity = E; } + void setAffinity(Expr *E) { } -public: - /// \brief Build 'affinity' clause. + /// \brief Build clause with two variables (affinity value, strictness) /// - /// \param E Expression associated with this clause. /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. /// - OMPAffinityClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc) - : OMPClause(OMPC_affinity, StartLoc, EndLoc), LParenLoc(LParenLoc), - Affinity(E) {} + OMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause<OMPAffinityClause>(OMPC_affinity, StartLoc, LParenLoc, + EndLoc, N), + AffKind(OMPC_AFFINITY_unknown) {} /// \brief Build an empty clause. /// - OMPAffinityClause() - : OMPClause(OMPC_affinity, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), Affinity(nullptr) {} - /// \brief Sets the location of '('. - void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } - /// \brief Returns the location of '('. - SourceLocation getLParenLoc() const { return LParenLoc; } - /// \brief Return Affinity number. - Expr *getAffinity() { return cast<Expr>(Affinity); } - /// \brief Return Affinity number. - Expr *getAffinity() const { return cast<Expr>(Affinity); } + /// \param N Number of variables. + /// + explicit OMPAffinityClause(unsigned N) + : OMPVarListClause<OMPAffinityClause>(OMPC_affinity, SourceLocation(), + SourceLocation(), SourceLocation(), + N), + AffKind(OMPC_AFFINITY_unknown) {} + /// \brief Set affinity kind. + void setAFfinityKind(OpenMPAffinityClauseKind K) { AffKind = K; } + + /// \brief Set dependency kind and its location. + void setAffinityLoc(SourceLocation Loc) { AffLoc = Loc; } + + /// \brief Set colon location. + void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } + +public: + /// \brief Creates clause with a list of two variables. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param AffLoc Affinity type. + /// \param AffLoc Location of the dependency type. + /// \param ColonLoc Colon location. + /// \param VL List of references to the variables. + /// + static OMPAffinityClause * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, OpenMPAffinityClauseKind AffKind, + SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL); + /// \brief Creates an empty clause with \a 2 variables. + /// + /// \param C AST context. + /// + static OMPAffinityClause *CreateEmpty(const ASTContext &C, unsigned N); + + /// \brief Get affinity type. + OpenMPAffinityClauseKind getAffinityKind() const { return AffKind; } + /// \brief Get affinity type location. + SourceLocation getAffinityLoc() const { return AffLoc; } + /// \brief Get colon location. + SourceLocation getColonLoc() const { return ColonLoc; } + + /// \brief Get 'affinity' expression + const Expr *getAffinity() const { return (getVarRefs().size() > 0)? + getVarRefs()[0]:nullptr; } + + /// \brief Get 'strict' expression + const Expr *getStrict() const { return (getVarRefs().size() > 1)? + getVarRefs()[1]:nullptr; } + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_affinity; } - - child_range children() { return child_range(&Affinity, &Affinity + 1); } }; /// \brief This represents 'grainsize' clause in the '#pragma omp ...' diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 3e31829c8aee2c8933618ef7f9346884aabdf54a..3f2a9f698f3a420275bffbfadfaf3ec99e359063 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -2882,6 +2882,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) { return true; } +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPAffinityClause( + OMPAffinityClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) { TRY_TO(TraverseStmt(C->getDevice())); @@ -2922,13 +2929,6 @@ bool RecursiveASTVisitor<Derived>::VisitOMPOperationalIntensityClause( return true; } -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPAffinityClause( - OMPAffinityClause *C) { - TRY_TO(TraverseStmt(C->getAffinity())); - return true; -} - template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPGrainsizeClause( OMPGrainsizeClause *C) { diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 3963f7581880715485dea145728122ad6caa94d5..55a43489d929f6680d284664f1f5b53e3598c5f9 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -8308,6 +8308,8 @@ def err_omp_firstprivate_and_lastprivate_in_distribute : Error< "lastprivate variable cannot be firstprivate in '#pragma omp distribute'">; def err_omp_firstprivate_distribute_in_teams_reduction : Error< "reduction variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">; +def err_omp_affinity_clause_wrong_number_var : Error< + "'affinity' clause must have one expression and optionally a 'strict' argument">; def err_omp_depend_clause_thread_simd : Error< "'depend' clauses cannot be mixed with '%0' clause">; def err_omp_depend_sink_expected_loop_iteration : Error< diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def index 124837e24a38216796a7a7fd772da89c209b733d..91ffe16babe871f57ee1b3acf22140e294e83dd9 100644 --- a/include/clang/Basic/OpenMPKinds.def +++ b/include/clang/Basic/OpenMPKinds.def @@ -105,6 +105,9 @@ #ifndef OPENMP_INIT_KIND #define OPENMP_INIT_KIND(Name) #endif +#ifndef OPENMP_AFFINITY_KIND +#define OPENMP_AFFINITY_KIND(Name) +#endif #ifndef OPENMP_SCHEDULE_KIND #define OPENMP_SCHEDULE_KIND(Name) #endif @@ -335,6 +338,11 @@ OPENMP_DEFAULTMAP_KIND(scalar) // Modifiers for 'defaultmap' clause. OPENMP_DEFAULTMAP_MODIFIER(tofrom) +// Static attributes for 'affinity' clause. +OPENMP_AFFINITY_KIND(depend) +OPENMP_AFFINITY_KIND(numa) +OPENMP_AFFINITY_KIND(core) + // Static attributes for 'depend' clause. OPENMP_DEPEND_KIND(in) OPENMP_DEPEND_KIND(out) @@ -640,6 +648,7 @@ OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned) #undef OPENMP_TASKLOOP_SIMD_CLAUSE #undef OPENMP_TASKLOOP_CLAUSE #undef OPENMP_LINEAR_KIND +#undef OPENMP_AFFINITY_KIND #undef OPENMP_DEPEND_KIND #undef OPENMP_SCHEDULE_MODIFIER #undef OPENMP_SCHEDULE_KIND diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h index 285ce0b5d8b9a08811dfcf5028f52cf28e54b9bd..3a2f3cedec137a0103f5918bc22fba04bb4fbcd5 100644 --- a/include/clang/Basic/OpenMPKinds.h +++ b/include/clang/Basic/OpenMPKinds.h @@ -88,6 +88,14 @@ enum OpenMPDependClauseKind { OMPC_DEPEND_unknown }; +/// \brief OpenMP attributes for 'affinity' clause. +enum OpenMPAffinityClauseKind { +#define OPENMP_AFFINITY_KIND(Name) \ + OMPC_AFFINITY_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_AFFINITY_unknown +}; + /// \brief OpenMP attributes for 'linear' clause. enum OpenMPLinearClauseKind { #define OPENMP_LINEAR_KIND(Name) \ diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 5838a447c3b91984ace032cd4b0f597f71e67f91..ed5142a38d1c0bd14e10067bd0a4d152cbb479e8 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -2562,6 +2562,7 @@ public: CXXScopeSpec ReductionIdScopeSpec; DeclarationNameInfo ReductionId; OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown; + OpenMPAffinityClauseKind AffKind = OMPC_AFFINITY_unknown; OpenMPLinearClauseKind LinKind = OMPC_LINEAR_val; OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown; OpenMPMapClauseKind MapType = OMPC_MAP_unknown; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 5342d35993f10420d3f9722c0fa250690cbccb57..824e56a24e6f112b4a2d305495fc00d5bd7d00b3 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -8395,6 +8395,7 @@ public: CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, + OpenMPAffinityClauseKind AffKind, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc); /// \brief Called on well-formed 'private' clause. @@ -8518,7 +8519,11 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'affinity' clause. - OMPClause *ActOnOpenMPAffinityClause(Expr *Affinity, SourceLocation StartLoc, + OMPClause *ActOnOpenMPAffinityClause(OpenMPAffinityClauseKind AffKind, + SourceLocation AffLoc, + SourceLocation ColonLoc, + ArrayRef<Expr *> VarList, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp index 3f87b900123f5f59199078f1b409ef8250be2728..111169896cd6e4043d3f0961cc0657c2c2eb1853 100644 --- a/lib/AST/OpenMPClause.cpp +++ b/lib/AST/OpenMPClause.cpp @@ -81,6 +81,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { case OMPC_thread_limit: case OMPC_priority: case OMPC_affinity: + case OMPC_oi: case OMPC_init: case OMPC_grainsize: case OMPC_nogroup: @@ -148,6 +149,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) case OMPC_thread_limit: case OMPC_priority: case OMPC_affinity: + case OMPC_oi: case OMPC_init: case OMPC_grainsize: case OMPC_nogroup: @@ -584,6 +586,29 @@ unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber( return TotalNum; } +OMPAffinityClause * +OMPAffinityClause::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + OpenMPAffinityClauseKind AffKind, + SourceLocation AffLoc, + SourceLocation ColonLoc, ArrayRef<Expr *> VL) { + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size())); + OMPAffinityClause *Clause = + new (Mem) OMPAffinityClause(StartLoc, LParenLoc, EndLoc, VL.size()); + Clause->setVarRefs(VL); + Clause->setAFfinityKind(AffKind); + Clause->setAffinityLoc(AffLoc); + Clause->setColonLoc(ColonLoc); + return Clause; +} + +OMPAffinityClause *OMPAffinityClause::CreateEmpty(const ASTContext &C, + unsigned N) { + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(0)); + return new (Mem) OMPAffinityClause(0); +} + + OMPMapClause * OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 3e5a83f7d300f5afd6406315eb017e5adac33388..764595bcaa378c3b1804d448c0fb508d74854133 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -760,6 +760,7 @@ void OMPClausePrinter::VisitOMPOperationalIntensityClause(OMPOperationalIntensit } void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) { + //TODO fix this OS << "affinity("; Node->getAffinity()->printPretty(OS, nullptr, Policy, 0); OS << ")"; diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp index be6c95e762649ebcd3f10cd1a63bd4b90988f7ce..62643ae9594bca0ad21676f72ead7111d9f4356a 100644 --- a/lib/Basic/OpenMPKinds.cpp +++ b/lib/Basic/OpenMPKinds.cpp @@ -130,6 +130,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, .Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_MODIFIER_##Name)) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_DEFAULTMAP_unknown); + case OMPC_affinity: + return llvm::StringSwitch<OpenMPAffinityClauseKind>(Str) +#define OPENMP_AFFINITY_KIND(Name) .Case(#Name, OMPC_AFFINITY_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_AFFINITY_unknown); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -163,7 +168,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_thread_limit: case OMPC_priority: case OMPC_oi: - case OMPC_affinity: case OMPC_grainsize: case OMPC_nogroup: case OMPC_num_tasks: diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp index 36a29e919193e2a0f6795c998d7ae4d080b3efa3..16f57357170f6fec7e9f7c3ca2ad7b5b4d9a66d3 100644 --- a/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/lib/CodeGen/CGOpenMPRuntime.cpp @@ -555,7 +555,8 @@ enum OpenMPRTLFunction { // Call to kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid, // int end_part); OMPRTL__kmpc_omp_taskyield, - // Call to void __kmpc_omp_set_task_affinity(ident_t *, kmp_int32 affinity); + // Call to void __kmpc_omp_set_task_affinity(int kind, kmp_int32 affinity, + // int strict); OMPRTL__kmpc_omp_set_task_affinity, // Call to void __kmpc_begin_push_init(int kind); OMPRTL__kmpc_begin_push_init, @@ -1234,8 +1235,9 @@ CGOpenMPRuntime::createRuntimeFunction(unsigned Function) { break; } case OMPRTL__kmpc_omp_set_task_affinity: { - // Build void __kmpc_omp_set_task_affinity(ident_t *loc, kmp_int32 affinity,) - llvm::Type *TypeParams[] = {CGM.Int32Ty}; + // Build void __kmpc_omp_set_task_affinity(int kind, kmp_int32 affinity, + // int strict) + llvm::Type *TypeParams[] = {CGM.Int32Ty, CGM.Int64Ty, CGM.Int32Ty}; llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_set_task_affinity"); @@ -2680,6 +2682,49 @@ void CGOpenMPRuntime::emitProcBindClause(CodeGenFunction &CGF, CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_proc_bind), Args); } +void CGOpenMPRuntime::emitTaskAffinityClause(CodeGenFunction &CGF, + OpenMPAffinityClauseKind AffKind, + const Expr *Aff, + llvm::Value *Strict) { + //Emit Affinity + CodeGenFunction::RunCleanupsScope AffinityScope(CGF); + + // Constants for affinity kind accepted by the runtime. + enum AffinityKindTy { + AffinityDepend = 0, + AffinityNuma, + AffinityCore + } RuntimeAffinity; + switch (AffKind) { + case OMPC_AFFINITY_numa: + RuntimeAffinity = AffinityNuma; + break; + case OMPC_AFFINITY_core: + RuntimeAffinity = AffinityCore; + break; + case OMPC_AFFINITY_depend: + RuntimeAffinity = AffinityDepend; + break; + case OMPC_AFFINITY_unknown: + llvm_unreachable("Unsupported affinity value."); + } + + llvm::Value *Affinity = CGF.EmitScalarExpr(Aff, /*IgnoreResultAssign*/ true); + const Type *ExprTy = Aff->getType().getTypePtr(); + if (AffKind == OMPC_AFFINITY_depend && ExprTy->isPointerType()) { + Affinity = CGF.Builder.CreatePtrToInt(Affinity, CGF.Int64Ty); + } + + // Build call __kmpc_omp_set_affinity(affinity) + llvm::Value *Args[] = { + llvm::ConstantInt::get(CGM.IntTy, RuntimeAffinity, /*isSigned=*/true), + CGF.Builder.CreateIntCast(Affinity, CGF.Int64Ty, /*isSigned*/ false), + CGF.Builder.CreateIntCast(Strict, CGF.Int32Ty, /*isSigned*/ false) + }; + CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_set_task_affinity), + Args); +} + void CGOpenMPRuntime::emitBeginInitClause(CodeGenFunction &CGF, OpenMPInitClauseKind Init) { if (!CGF.HaveInsertPoint()) diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h index 1f62bf1e9fef06ff8bed12ef3a5ba55c22f036a9..149920b5550399a841a0ec93ef3f2ea5d8504f31 100644 --- a/lib/CodeGen/CGOpenMPRuntime.h +++ b/lib/CodeGen/CGOpenMPRuntime.h @@ -749,6 +749,14 @@ public: OpenMPProcBindClauseKind ProcBind, SourceLocation Loc); + /// \brief Emit call to void __kmpc_omp_set_task_affinity(int kind, kmp_int32 + // affinity, int strict) + /// to generate code for begin 'init' clause. + virtual void emitTaskAffinityClause(CodeGenFunction &CGF, + OpenMPAffinityClauseKind AffKind, + const Expr *Aff, + llvm::Value *Strict); + /// \brief Emit call to void __kmpc_begin_push_init(int init) /// to generate code for begin 'init' clause. virtual void emitBeginInitClause(CodeGenFunction &CGF, diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index 07ee10c6e1816e38b68ba40048cff679d1369d92..2495cc7e5f0910a38dd265664d799672da422407 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -2609,13 +2609,6 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { // Emit outlined function for task construct. auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); auto CapturedStruct = GenerateCapturedStmtArgument(*CS); -#if 0 - //Check if there is an affinity clause - const Expr *Affinity = nullptr; - if (const auto *AffinityClause = S.getSingleClause<OMPAffinityClause>()) { - Affinity = AffinityClause->getAffinity(); - } -#endif auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl()); const Expr *IfCond = nullptr; for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { @@ -2639,6 +2632,20 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { SharedsTy, CapturedStruct, IfCond, Data); }; +#if 0 + //Check if there is an affinity clause + if (const auto *AffinityClause = S.getSingleClause<OMPAffinityClause>()) { + auto Strict = AffinityClause->getStrict(); + llvm::Value *StrictValue = Builder.getInt32(0); + if (Strict) + StrictValue = EvaluateExprAsBool(Strict); + + CGM.getOpenMPRuntime().emitTaskAffinityClause(*this, + AffinityClause->getAffinityKind(), + AffinityClause->getAffinity(), + StrictValue); + } +#endif EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data); } diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index 1eb25cc7210db4ed70dc050976cee894cfc4cb04..3577b6c70c45a1fde6ede47e6e1f28f2a5437d52 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -1086,7 +1086,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_thread_limit: case OMPC_priority: case OMPC_oi: - case OMPC_affinity: case OMPC_grainsize: case OMPC_num_tasks: case OMPC_hint: @@ -1197,6 +1196,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_copyprivate: case OMPC_flush: case OMPC_depend: + case OMPC_affinity: case OMPC_map: case OMPC_to: case OMPC_from: @@ -1597,6 +1597,24 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, : diag::warn_pragma_expected_colon) << "dependency type"; } + } else if (Kind == OMPC_affinity) { + // Handle affinity type for affinity clause. + ColonProtectionRAIIObject ColonRAII(*this); + Data.AffKind = static_cast<OpenMPAffinityClauseKind>(getOpenMPSimpleClauseType( + Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "")); + Data.DepLinMapLoc = Tok.getLocation(); + + if (Data.AffKind == OMPC_AFFINITY_unknown) { + //FIXME use correct error message + Diag(Tok, diag::err_omp_unknown_map_type); + } + ConsumeToken(); + if (Tok.is(tok::colon)) { + Data.ColonLoc = ConsumeToken(); + } else { + Diag(Tok, diag::warn_pragma_expected_colon) + << "affinity type"; + } } else if (Kind == OMPC_linear) { // Try to parse modifier if any. if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) { @@ -1676,12 +1694,13 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, } bool IsComma = - (Kind != OMPC_reduction && Kind != OMPC_depend && Kind != OMPC_map) || + (Kind != OMPC_reduction && Kind != OMPC_depend && Kind != OMPC_map && (Kind != OMPC_affinity)) || (Kind == OMPC_reduction && !InvalidReductionId) || (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown && (!MapTypeModifierSpecified || Data.MapTypeModifier == OMPC_MAP_always)) || - (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown); + (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown) || + (Kind == OMPC_affinity && Data.AffKind != OMPC_AFFINITY_unknown); const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned); while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) && Tok.isNot(tok::annot_pragma_openmp_end))) { @@ -1788,7 +1807,7 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, return Actions.ActOnOpenMPVarListClause( Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Tok.getLocation(), Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind, - Data.MapTypeModifier, Data.MapType, Data.IsMapTypeImplicit, + Data.MapTypeModifier, Data.AffKind, Data.MapType, Data.IsMapTypeImplicit, Data.DepLinMapLoc); } diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index ee1bfcab14c2a1f55cd19f6b335b37d2ff531234..a27dae97b49f0bbe8b48b47a8e38e0239b40dc44 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -7246,9 +7246,6 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_oi: Res = ActOnOpenMPOperationalIntensityClause(Expr, StartLoc, LParenLoc, EndLoc); break; - case OMPC_affinity: - Res = ActOnOpenMPAffinityClause(Expr, StartLoc, LParenLoc, EndLoc); - break; case OMPC_grainsize: Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); break; @@ -7283,6 +7280,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_capture: case OMPC_seq_cst: case OMPC_depend: + case OMPC_affinity: case OMPC_threads: case OMPC_simd: case OMPC_map: @@ -8023,6 +8021,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause( SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, + OpenMPAffinityClauseKind AffKind, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { OMPClause *Res = nullptr; @@ -8061,9 +8060,13 @@ OMPClause *Sema::ActOnOpenMPVarListClause( Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); break; case OMPC_depend: - Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, + Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); break; + case OMPC_affinity: + Res = ActOnOpenMPAffinityClause(AffKind, DepLinMapLoc, ColonLoc, VarList, + StartLoc, LParenLoc, EndLoc); + break; case OMPC_map: Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, DepLinMapLoc, ColonLoc, VarList, StartLoc, @@ -8108,7 +8111,6 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_thread_limit: case OMPC_priority: case OMPC_oi: - case OMPC_affinity: case OMPC_grainsize: case OMPC_nogroup: case OMPC_num_tasks: @@ -11354,19 +11356,25 @@ OMPClause *Sema::ActOnOpenMPOperationalIntensityClause(Expr *OperationalIntensit return new (Context) OMPOperationalIntensityClause(ValExpr, StartLoc, LParenLoc, EndLoc); } -OMPClause *Sema::ActOnOpenMPAffinityClause(Expr *Affinity, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - Expr *ValExpr = Affinity; - +OMPClause * +Sema::ActOnOpenMPAffinityClause(OpenMPAffinityClauseKind AffKind, + SourceLocation AffLoc, SourceLocation ColonLoc, + ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + + if (VarList.size() == 0 || VarList.size() > 2) + Diag(AffLoc, diag::err_omp_affinity_clause_wrong_number_var); + // FIXME do a proper check on this // The affinity is a non-negative numerical scalar expression. // It should also correspond to a NUMA node id - if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_affinity, - /*StrictlyPositive=*/false)) - return nullptr; + //if (!IsNonNegativeIntegerValue(VarList[0], *this, OMPC_affinity, + //StrictlyPositive=false)) + //return nullptr; - return new (Context) OMPAffinityClause(ValExpr, StartLoc, LParenLoc, EndLoc); + return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, EndLoc, + AffKind, AffLoc, ColonLoc, VarList); } OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 990c669ee3c941fb20018b9f92b0afebf7e0c837..f14c3d3643ed8fb04e0138c589a2bde1349757cc 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1743,10 +1743,15 @@ public: /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPAffinityClause(Expr *Affinity, SourceLocation StartLoc, + OMPClause *RebuildOMPAffinityClause(OpenMPAffinityClauseKind AffKind, + SourceLocation AffLoc, + SourceLocation ColonLoc, + ArrayRef<Expr *> VarList, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPAffinityClause(Affinity, StartLoc, LParenLoc, + return getSema().ActOnOpenMPAffinityClause(AffKind, AffLoc, ColonLoc, + VarList, StartLoc, LParenLoc, EndLoc); } @@ -8123,11 +8128,17 @@ TreeTransform<Derived>::TransformOMPOperationalIntensityClause(OMPOperationalInt template <typename Derived> OMPClause * TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) { - ExprResult E = getDerived().TransformExpr(C->getAffinity()); - if (E.isInvalid()) - return nullptr; + llvm::SmallVector<Expr *, 16> Vars; + Vars.reserve(C->varlist_size()); + for (auto *VE : C->varlists()) { + ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); + if (EVar.isInvalid()) + return nullptr; + Vars.push_back(EVar.get()); + } return getDerived().RebuildOMPAffinityClause( - E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd()); + C->getAffinityKind(), C->getAffinityLoc(), C->getColonLoc(), Vars, + C->getLocStart(), C->getLParenLoc(), C->getLocEnd()); } template <typename Derived> diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 65e01131ec0f586f39130240e51a900998d54244..63af2390f9727e3524ea0104f57f146e5d661af1 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -1906,7 +1906,7 @@ OMPClause *OMPClauseReader::readClause() { C = new (Context) OMPOperationalIntensityClause(); break; case OMPC_affinity: - C = new (Context) OMPAffinityClause(); + C = OMPAffinityClause::CreateEmpty(Context, Record[Idx++]); break; case OMPC_grainsize: C = new (Context) OMPGrainsizeClause(); diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 260842ef7d881c92f82f42885089842bddef4061..cab911cc5b417000ce346346d89fd69c79b2bc1f 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -2089,8 +2089,13 @@ void OMPClauseWriter::VisitOMPOperationalIntensityClause(OMPOperationalIntensity } void OMPClauseWriter::VisitOMPAffinityClause(OMPAffinityClause *C) { - Record.AddStmt(C->getAffinity()); + Record.push_back(C->varlist_size()); Record.AddSourceLocation(C->getLParenLoc()); + Record.push_back(C->getAffinityKind()); + Record.AddSourceLocation(C->getAffinityLoc()); + Record.AddSourceLocation(C->getColonLoc()); + for (auto *VE : C->varlists()) + Record.AddStmt(VE); } void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) { diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 00319bfd83678acd2948d289234c7c6ed09b73b2..86072b96a6a5438e033918e494d0b09fddc7ef88 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2144,7 +2144,7 @@ void OMPClauseEnqueue::VisitOMPOperationalIntensityClause(const OMPOperationalIn } void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause *C) { - Visitor->AddStmt(C->getAffinity()); + VisitOMPClauseList(C); } void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {