diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTTypeTraits.cpp | 1 | ||||
-rw-r--r-- | clang/lib/AST/OpenMPClause.cpp | 38 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Basic/OpenMPKinds.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 31 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 57 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 36 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 15 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 9 |
10 files changed, 189 insertions, 11 deletions
diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp index dae9ab3a289..ba1581bd3f6 100644 --- a/clang/lib/AST/ASTTypeTraits.cpp +++ b/clang/lib/AST/ASTTypeTraits.cpp @@ -113,7 +113,6 @@ ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) { #define OPENMP_CLAUSE(Name, Class) \ case OMPC_##Name: return ASTNodeKind(NKI_##Class); #include "clang/Basic/OpenMPKinds.def" - case OMPC_allocate: case OMPC_threadprivate: case OMPC_uniform: case OMPC_unknown: diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 5ee10fb2a11..5bd4ad81bf8 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -74,6 +74,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { case OMPC_safelen: case OMPC_simdlen: case OMPC_allocator: + case OMPC_allocate: case OMPC_collapse: case OMPC_private: case OMPC_shared: @@ -85,7 +86,6 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { case OMPC_untied: case OMPC_mergeable: case OMPC_threadprivate: - case OMPC_allocate: case OMPC_flush: case OMPC_read: case OMPC_write: @@ -147,6 +147,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) case OMPC_safelen: case OMPC_simdlen: case OMPC_allocator: + case OMPC_allocate: case OMPC_collapse: case OMPC_private: case OMPC_shared: @@ -158,7 +159,6 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) case OMPC_untied: case OMPC_mergeable: case OMPC_threadprivate: - case OMPC_allocate: case OMPC_flush: case OMPC_read: case OMPC_write: @@ -701,6 +701,25 @@ OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C, return new (Mem) OMPInReductionClause(N); } +OMPAllocateClause * +OMPAllocateClause::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, Expr *Allocator, + SourceLocation ColonLoc, SourceLocation EndLoc, + ArrayRef<Expr *> VL) { + // Allocate space for private variables and initializer expressions. + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size())); + auto *Clause = new (Mem) OMPAllocateClause(StartLoc, LParenLoc, Allocator, + ColonLoc, EndLoc, VL.size()); + Clause->setVarRefs(VL); + return Clause; +} + +OMPAllocateClause *OMPAllocateClause::CreateEmpty(const ASTContext &C, + unsigned N) { + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N)); + return new (Mem) OMPAllocateClause(N); +} + OMPFlushClause *OMPFlushClause::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -1264,6 +1283,21 @@ void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) { } } +void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) { + if (Node->varlist_empty()) + return; + OS << "allocate"; + if (Expr *Allocator = Node->getAllocator()) { + OS << "("; + Allocator->printPretty(OS, nullptr, Policy, 0); + OS << ":"; + VisitOMPClauseList(Node, ' '); + } else { + VisitOMPClauseList(Node, '('); + } + OS << ")"; +} + void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) { if (!Node->varlist_empty()) { OS << "private"; diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 53655a18f91..da80322a707 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -716,6 +716,11 @@ void OMPClauseProfiler::VisitOMPDeviceClause(const OMPDeviceClause *C) { void OMPClauseProfiler::VisitOMPMapClause(const OMPMapClause *C) { VisitOMPClauseList(C); } +void OMPClauseProfiler::VisitOMPAllocateClause(const OMPAllocateClause *C) { + if (Expr *Allocator = C->getAllocator()) + Profiler->VisitStmt(Allocator); + VisitOMPClauseList(C); +} void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) { VistOMPClauseWithPreInit(C); if (C->getNumTeams()) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index e4e8adda93b..82e193efef3 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -71,8 +71,6 @@ const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) { return "uniform"; case OMPC_threadprivate: return "threadprivate or thread local"; - case OMPC_allocate: - return "allocate"; } llvm_unreachable("Invalid OpenMP clause kind"); } @@ -149,13 +147,13 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, .Default(OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown); case OMPC_unknown: case OMPC_threadprivate: - case OMPC_allocate: case OMPC_if: case OMPC_final: case OMPC_num_threads: case OMPC_safelen: case OMPC_simdlen: case OMPC_allocator: + case OMPC_allocate: case OMPC_collapse: case OMPC_private: case OMPC_firstprivate: @@ -332,13 +330,13 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, llvm_unreachable("Invalid OpenMP 'atomic_default_mem_order' clause type"); case OMPC_unknown: case OMPC_threadprivate: - case OMPC_allocate: case OMPC_if: case OMPC_final: case OMPC_num_threads: case OMPC_safelen: case OMPC_simdlen: case OMPC_allocator: + case OMPC_allocate: case OMPC_collapse: case OMPC_private: case OMPC_firstprivate: diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 107825bd936..e739a117bd8 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -3950,6 +3950,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_safelen: case OMPC_simdlen: case OMPC_allocator: + case OMPC_allocate: case OMPC_collapse: case OMPC_default: case OMPC_seq_cst: @@ -3965,7 +3966,6 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_nowait: case OMPC_untied: case OMPC_threadprivate: - case OMPC_allocate: case OMPC_depend: case OMPC_mergeable: case OMPC_device: diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 572863c164f..34798ea39c7 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1562,7 +1562,7 @@ bool Parser::ParseOpenMPSimpleVarList( /// thread_limit-clause | priority-clause | grainsize-clause | /// nogroup-clause | num_tasks-clause | hint-clause | to-clause | /// from-clause | is_device_ptr-clause | task_reduction-clause | -/// in_reduction-clause | allocator-clause +/// in_reduction-clause | allocator-clause | allocate-clause /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { @@ -1708,6 +1708,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_from: case OMPC_use_device_ptr: case OMPC_is_device_ptr: + case OMPC_allocate: Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective); break; case OMPC_unknown: @@ -1716,7 +1717,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); break; case OMPC_threadprivate: - case OMPC_allocate: case OMPC_uniform: if (!WrongDirective) Diag(Tok, diag::err_omp_unexpected_clause) @@ -2306,6 +2306,31 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, ConsumeToken(); } } + } else if (Kind == OMPC_allocate) { + // Handle optional allocator expression followed by colon delimiter. + ColonProtectionRAIIObject ColonRAII(*this); + TentativeParsingAction TPA(*this); + ExprResult Tail = + Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); + Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(), + /*DiscardedValue=*/false); + if (Tail.isUsable()) { + if (Tok.is(tok::colon)) { + Data.TailExpr = Tail.get(); + Data.ColonLoc = ConsumeToken(); + TPA.Commit(); + } else { + // colon not found, no allocator specified, parse only list of + // variables. + TPA.Revert(); + } + } else { + // Parsing was unsuccessfull, revert and skip to the end of clause or + // directive. + TPA.Revert(); + SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, + StopBeforeMatch); + } } bool IsComma = @@ -2410,6 +2435,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, /// 'use_device_ptr' '(' list ')' /// is_device_ptr-clause: /// 'is_device_ptr' '(' list ')' +/// allocate-clause: +/// 'allocate' '(' [ allocator ':' ] list ')' /// /// For 'linear' clause linear-list may have the following forms: /// list diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index dbccb69aad7..150b21a8c92 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -10152,6 +10152,10 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_is_device_ptr: Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); break; + case OMPC_allocate: + Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, + ColonLoc, EndLoc); + break; case OMPC_if: case OMPC_final: case OMPC_num_threads: @@ -10167,7 +10171,6 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_untied: case OMPC_mergeable: case OMPC_threadprivate: - case OMPC_allocate: case OMPC_read: case OMPC_write: case OMPC_update: @@ -14700,3 +14703,55 @@ OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, MVLI.VarBaseDeclarations, MVLI.VarComponents); } + +OMPClause *Sema::ActOnOpenMPAllocateClause( + Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, + SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { + if (Allocator) { + // OpenMP [2.11.4 allocate Clause, Description] + // allocator is an expression of omp_allocator_handle_t type. + if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) + return nullptr; + + ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); + if (AllocatorRes.isInvalid()) + return nullptr; + AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), + DSAStack->getOMPAllocatorHandleT(), + Sema::AA_Initializing, + /*AllowExplicit=*/true); + if (AllocatorRes.isInvalid()) + return nullptr; + Allocator = AllocatorRes.get(); + } + // Analyze and build list of variables. + SmallVector<Expr *, 8> Vars; + for (Expr *RefExpr : VarList) { + assert(RefExpr && "NULL expr in OpenMP private clause."); + SourceLocation ELoc; + SourceRange ERange; + Expr *SimpleRefExpr = RefExpr; + auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); + if (Res.second) { + // It will be analyzed later. + Vars.push_back(RefExpr); + } + ValueDecl *D = Res.first; + if (!D) + continue; + + auto *VD = dyn_cast<VarDecl>(D); + DeclRefExpr *Ref = nullptr; + if (!VD && !CurContext->isDependentContext()) + Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); + Vars.push_back((VD || CurContext->isDependentContext()) + ? RefExpr->IgnoreParens() + : Ref); + } + + if (Vars.empty()) + return nullptr; + + return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, + ColonLoc, EndLoc, Vars); +} diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 93c5bdfed4c..a8ea6b01d1c 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1827,6 +1827,19 @@ public: VarList, Locs, UnresolvedMappers); } + /// Build a new OpenMP 'allocate' clause. + /// + /// By default, performs semantic analysis to build the new OpenMP clause. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation ColonLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPAllocateClause(Allocate, VarList, StartLoc, + LParenLoc, ColonLoc, EndLoc); + } + /// Build a new OpenMP 'num_teams' clause. /// /// By default, performs semantic analysis to build the new statement. @@ -8908,6 +8921,29 @@ OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) { template <typename Derived> OMPClause * +TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) { + Expr *Allocator = C->getAllocator(); + if (Allocator) { + ExprResult AllocatorRes = getDerived().TransformExpr(Allocator); + if (AllocatorRes.isInvalid()) + return nullptr; + Allocator = AllocatorRes.get(); + } + 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().RebuildOMPAllocateClause( + Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), + C->getEndLoc()); +} + +template <typename Derived> +OMPClause * TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) { ExprResult E = getDerived().TransformExpr(C->getNumTeams()); if (E.isInvalid()) diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 5ca5e8de556..d381f9e9bd3 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11884,6 +11884,9 @@ OMPClause *OMPClauseReader::readClause() { C = OMPIsDevicePtrClause::CreateEmpty(Context, Sizes); break; } + case OMPC_allocate: + C = OMPAllocateClause::CreateEmpty(Context, Record.readInt()); + break; } Visit(C); C->setLocStart(Record.readSourceLocation()); @@ -12379,6 +12382,18 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { C->setComponents(Components, ListSizes); } +void OMPClauseReader::VisitOMPAllocateClause(OMPAllocateClause *C) { + C->setLParenLoc(Record.readSourceLocation()); + C->setColonLoc(Record.readSourceLocation()); + C->setAllocator(Record.readSubExpr()); + unsigned NumVars = C->varlist_size(); + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Record.readSubExpr()); + C->setVarRefs(Vars); +} + void OMPClauseReader::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) { VisitOMPClauseWithPreInit(C); C->setNumTeams(Record.readSubExpr()); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index c593dd98dba..3609e589193 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6831,6 +6831,15 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { } } +void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) { + Record.push_back(C->varlist_size()); + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getColonLoc()); + Record.AddStmt(C->getAllocator()); + for (auto *VE : C->varlists()) + Record.AddStmt(VE); +} + void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) { VisitOMPClauseWithPreInit(C); Record.AddStmt(C->getNumTeams()); |