diff options
author | Michael Kruse <llvm@meinersbur.de> | 2019-02-25 20:34:15 +0000 |
---|---|---|
committer | Michael Kruse <llvm@meinersbur.de> | 2019-02-25 20:34:15 +0000 |
commit | 01e162c2965d114aa4e21c91b6341454210ad8fb (patch) | |
tree | 8914dcbd768bc12f699a64b4fa85f8d7282106dd /lib | |
parent | 3e24c20c7799f2f51b34589b9e8d2dbe49537bb7 (diff) | |
download | clang-01e162c2965d114aa4e21c91b6341454210ad8fb.tar.gz |
[OpenMP 5.0] Parsing/sema support for from clause with mapper modifier.
This patch implements the parsing and sema support for the OpenMP
'from'-clause with potential user-defined mappers attached.
User-defined mappers are a new feature in OpenMP 5.0. A 'from'-clause
can have an explicit or implicit associated mapper, which instructs the
compiler to generate and use customized mapping functions. An example is
shown below:
struct S { int len; int *d; };
#pragma omp declare mapper(id: struct S s) map(s, s.d[0:s.len])
struct S ss;
#pragma omp target update from(mapper(id): ss) // use the mapper with name 'id' to map ss from device
Contributed-by: Lingda Li <lildmh@gmail.com>
Differential Revision: https://reviews.llvm.org/D58638
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354817 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/OpenMPClause.cpp | 35 | ||||
-rw-r--r-- | lib/Basic/OpenMPKinds.cpp | 20 | ||||
-rw-r--r-- | lib/Parse/ParseOpenMP.cpp | 19 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 63 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 26 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 10 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 4 |
7 files changed, 115 insertions, 62 deletions
diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp index 0f1cb0258a..b02a888a8c 100644 --- a/lib/AST/OpenMPClause.cpp +++ b/lib/AST/OpenMPClause.cpp @@ -892,10 +892,11 @@ OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C, return new (Mem) OMPToClause(Sizes); } -OMPFromClause * -OMPFromClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs, - ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, - MappableExprComponentListsRef ComponentLists) { +OMPFromClause *OMPFromClause::Create( + const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars, + ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs, + NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Vars.size(); Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations); @@ -903,8 +904,8 @@ OMPFromClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs, Sizes.NumComponents = getComponentsTotalNumber(ComponentLists); // We need to allocate: - // NumVars x Expr* - we have an original list expression for each clause list - // entry. + // 2 x NumVars x Expr* - we have an original list expression and an associated + // user-defined mapper for each clause list entry. // NumUniqueDeclarations x ValueDecl* - unique base declarations associated // with each component list. // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the @@ -915,13 +916,15 @@ OMPFromClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs, void *Mem = C.Allocate( totalSizeToAlloc<Expr *, ValueDecl *, unsigned, OMPClauseMappableExprCommon::MappableComponent>( - Sizes.NumVars, Sizes.NumUniqueDeclarations, + 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations, Sizes.NumUniqueDeclarations + Sizes.NumComponentLists, Sizes.NumComponents)); - OMPFromClause *Clause = new (Mem) OMPFromClause(Locs, Sizes); + auto *Clause = + new (Mem) OMPFromClause(UDMQualifierLoc, MapperId, Locs, Sizes); Clause->setVarRefs(Vars); + Clause->setUDMapperRefs(UDMapperRefs); Clause->setClauseInfo(Declarations, ComponentLists); return Clause; } @@ -932,7 +935,7 @@ OMPFromClause::CreateEmpty(const ASTContext &C, void *Mem = C.Allocate( totalSizeToAlloc<Expr *, ValueDecl *, unsigned, OMPClauseMappableExprCommon::MappableComponent>( - Sizes.NumVars, Sizes.NumUniqueDeclarations, + 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations, Sizes.NumUniqueDeclarations + Sizes.NumComponentLists, Sizes.NumComponents)); return new (Mem) OMPFromClause(Sizes); @@ -1465,7 +1468,19 @@ void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) { void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) { if (!Node->varlist_empty()) { OS << "from"; - VisitOMPClauseList(Node, '('); + DeclarationNameInfo MapperId = Node->getMapperIdInfo(); + if (MapperId.getName() && !MapperId.getName().isEmpty()) { + OS << '('; + OS << "mapper("; + NestedNameSpecifier *MapperNNS = + Node->getMapperQualifierLoc().getNestedNameSpecifier(); + if (MapperNNS) + MapperNNS->print(OS, Policy); + OS << MapperId << "):"; + VisitOMPClauseList(Node, ' '); + } else { + VisitOMPClauseList(Node, '('); + } OS << ")"; } } diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp index 47830c324d..b10c6d2498 100644 --- a/lib/Basic/OpenMPKinds.cpp +++ b/lib/Basic/OpenMPKinds.cpp @@ -122,6 +122,12 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, .Case(#Name, static_cast<unsigned>(OMPC_TO_MODIFIER_##Name)) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_TO_MODIFIER_unknown); + case OMPC_from: + return llvm::StringSwitch<unsigned>(Str) +#define OPENMP_FROM_MODIFIER_KIND(Name) \ + .Case(#Name, static_cast<unsigned>(OMPC_FROM_MODIFIER_##Name)) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_FROM_MODIFIER_unknown); case OMPC_dist_schedule: return llvm::StringSwitch<OpenMPDistScheduleClauseKind>(Str) #define OPENMP_DIST_SCHEDULE_KIND(Name) .Case(#Name, OMPC_DIST_SCHEDULE_##Name) @@ -180,7 +186,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_num_tasks: case OMPC_hint: case OMPC_uniform: - case OMPC_from: case OMPC_use_device_ptr: case OMPC_is_device_ptr: case OMPC_unified_address: @@ -277,6 +282,18 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, break; } llvm_unreachable("Invalid OpenMP 'to' clause type"); + case OMPC_from: + switch (Type) { + case OMPC_FROM_MODIFIER_unknown: + return "unknown"; +#define OPENMP_FROM_MODIFIER_KIND(Name) \ + case OMPC_FROM_MODIFIER_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + llvm_unreachable("Invalid OpenMP 'from' clause type"); case OMPC_dist_schedule: switch (Type) { case OMPC_DIST_SCHEDULE_unknown: @@ -350,7 +367,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_num_tasks: case OMPC_hint: case OMPC_uniform: - case OMPC_from: case OMPC_use_device_ptr: case OMPC_is_device_ptr: case OMPC_unified_address: diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index 68843f0c65..782ad12aac 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -2161,13 +2161,20 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, if (Tok.is(tok::colon)) Data.ColonLoc = ConsumeToken(); - } else if (Kind == OMPC_to) { + } else if (Kind == OMPC_to || Kind == OMPC_from) { if (Tok.is(tok::identifier)) { bool IsMapperModifier = false; - auto Modifier = static_cast<OpenMPToModifierKind>( - getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))); - if (Modifier == OMPC_TO_MODIFIER_mapper) - IsMapperModifier = true; + if (Kind == OMPC_to) { + auto Modifier = static_cast<OpenMPToModifierKind>( + getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))); + if (Modifier == OMPC_TO_MODIFIER_mapper) + IsMapperModifier = true; + } else { + auto Modifier = static_cast<OpenMPFromModifierKind>( + getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))); + if (Modifier == OMPC_FROM_MODIFIER_mapper) + IsMapperModifier = true; + } if (IsMapperModifier) { // Parse the mapper modifier. ConsumeToken(); @@ -2282,7 +2289,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, /// to-clause: /// 'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')' /// from-clause: -/// 'from' '(' list ')' +/// 'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')' /// use_device_ptr-clause: /// 'use_device_ptr' '(' list ')' /// is_device_ptr-clause: diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 5a6891d01a..76141afd59 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -9806,7 +9806,8 @@ OMPClause *Sema::ActOnOpenMPVarListClause( ReductionOrMapperId, Locs); break; case OMPC_from: - Res = ActOnOpenMPFromClause(VarList, Locs); + Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, + ReductionOrMapperId, Locs); break; case OMPC_use_device_ptr: Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); @@ -13190,15 +13191,13 @@ static void checkMappableExpressionList( if (VE->isValueDependent() || VE->isTypeDependent() || VE->isInstantiationDependent() || VE->containsUnexpandedParameterPack()) { - if (CKind != OMPC_from) { - // Try to find the associated user-defined mapper. - ExprResult ER = buildUserDefinedMapperRef( - SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, - VE->getType().getCanonicalType(), UnresolvedMapper); - if (ER.isInvalid()) - continue; - MVLI.UDMapperList.push_back(ER.get()); - } + // Try to find the associated user-defined mapper. + ExprResult ER = buildUserDefinedMapperRef( + SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, + VE->getType().getCanonicalType(), UnresolvedMapper); + if (ER.isInvalid()) + continue; + MVLI.UDMapperList.push_back(ER.get()); // We can only analyze this information once the missing information is // resolved. MVLI.ProcessedVarList.push_back(RE); @@ -13230,15 +13229,13 @@ static void checkMappableExpressionList( if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { // Add store "this" pointer to class in DSAStackTy for future checking DSAS->addMappedClassesQualTypes(TE->getType()); - if (CKind != OMPC_from) { - // Try to find the associated user-defined mapper. - ExprResult ER = buildUserDefinedMapperRef( - SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, - VE->getType().getCanonicalType(), UnresolvedMapper); - if (ER.isInvalid()) - continue; - MVLI.UDMapperList.push_back(ER.get()); - } + // Try to find the associated user-defined mapper. + ExprResult ER = buildUserDefinedMapperRef( + SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, + VE->getType().getCanonicalType(), UnresolvedMapper); + if (ER.isInvalid()) + continue; + MVLI.UDMapperList.push_back(ER.get()); // Skip restriction checking for variable or field declarations MVLI.ProcessedVarList.push_back(RE); MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); @@ -13358,14 +13355,12 @@ static void checkMappableExpressionList( } // Try to find the associated user-defined mapper. - if (CKind != OMPC_from) { - ExprResult ER = buildUserDefinedMapperRef( - SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, - Type.getCanonicalType(), UnresolvedMapper); - if (ER.isInvalid()) - continue; - MVLI.UDMapperList.push_back(ER.get()); - } + ExprResult ER = buildUserDefinedMapperRef( + SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, + Type.getCanonicalType(), UnresolvedMapper); + if (ER.isInvalid()) + continue; + MVLI.UDMapperList.push_back(ER.get()); // Save the current expression. MVLI.ProcessedVarList.push_back(RE); @@ -14182,18 +14177,20 @@ OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, } OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, - const OMPVarListLocTy &Locs) { + CXXScopeSpec &MapperIdScopeSpec, + DeclarationNameInfo &MapperId, + const OMPVarListLocTy &Locs, + ArrayRef<Expr *> UnresolvedMappers) { MappableVarListInfo MVLI(VarList); - CXXScopeSpec MapperIdScopeSpec; - DeclarationNameInfo MapperId; - ArrayRef<Expr *> UnresolvedMappers; checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, MapperIdScopeSpec, MapperId, UnresolvedMappers); if (MVLI.ProcessedVarList.empty()) return nullptr; - return OMPFromClause::Create(Context, Locs, MVLI.ProcessedVarList, - MVLI.VarBaseDeclarations, MVLI.VarComponents); + return OMPFromClause::Create( + Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, + MVLI.VarComponents, MVLI.UDMapperList, + MapperIdScopeSpec.getWithLocInContext(Context), MapperId); } OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index b8f922a76e..386b23db3a 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1915,8 +1915,12 @@ public: /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. OMPClause *RebuildOMPFromClause(ArrayRef<Expr *> VarList, - const OMPVarListLocTy &Locs) { - return getSema().ActOnOpenMPFromClause(VarList, Locs); + CXXScopeSpec &MapperIdScopeSpec, + DeclarationNameInfo &MapperId, + const OMPVarListLocTy &Locs, + ArrayRef<Expr *> UnresolvedMappers) { + return getSema().ActOnOpenMPFromClause(VarList, MapperIdScopeSpec, MapperId, + Locs, UnresolvedMappers); } /// Build a new OpenMP 'use_device_ptr' clause. @@ -8976,16 +8980,16 @@ OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) { template <typename Derived> OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) { - 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 0; - Vars.push_back(EVar.get()); - } OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); - return getDerived().RebuildOMPFromClause(Vars, Locs); + llvm::SmallVector<Expr *, 16> Vars; + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo MapperIdInfo; + llvm::SmallVector<Expr *, 16> UnresolvedMappers; + if (transformOMPMappableExprListClause<Derived, OMPFromClause>( + *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers)) + return nullptr; + return getDerived().RebuildOMPFromClause( + Vars, MapperIdScopeSpec, MapperIdInfo, Locs, UnresolvedMappers); } template <typename Derived> diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index bed58d0e10..9626418f68 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -12448,6 +12448,10 @@ void OMPClauseReader::VisitOMPToClause(OMPToClause *C) { void OMPClauseReader::VisitOMPFromClause(OMPFromClause *C) { C->setLParenLoc(Record.readSourceLocation()); + C->setMapperQualifierLoc(Record.readNestedNameSpecifierLoc()); + DeclarationNameInfo DNI; + Record.readDeclarationNameInfo(DNI); + C->setMapperIdInfo(DNI); auto NumVars = C->varlist_size(); auto UniqueDecls = C->getUniqueDeclarationsNum(); auto TotalLists = C->getTotalComponentListNum(); @@ -12459,6 +12463,12 @@ void OMPClauseReader::VisitOMPFromClause(OMPFromClause *C) { Vars.push_back(Record.readSubExpr()); C->setVarRefs(Vars); + SmallVector<Expr *, 16> UDMappers; + UDMappers.reserve(NumVars); + for (unsigned I = 0; I < NumVars; ++I) + UDMappers.push_back(Record.readSubExpr()); + C->setUDMapperRefs(UDMappers); + SmallVector<ValueDecl *, 16> Decls; Decls.reserve(UniqueDecls); for (unsigned i = 0; i < UniqueDecls; ++i) diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 1575a400ba..3d19c9d823 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -6885,8 +6885,12 @@ void OMPClauseWriter::VisitOMPFromClause(OMPFromClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); + Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc()); + Record.AddDeclarationNameInfo(C->getMapperIdInfo()); for (auto *E : C->varlists()) Record.AddStmt(E); + for (auto *E : C->mapperlists()) + Record.AddStmt(E); for (auto *D : C->all_decls()) Record.AddDeclRef(D); for (auto N : C->all_num_lists()) |