summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2019-02-25 20:34:15 +0000
committerMichael Kruse <llvm@meinersbur.de>2019-02-25 20:34:15 +0000
commit01e162c2965d114aa4e21c91b6341454210ad8fb (patch)
tree8914dcbd768bc12f699a64b4fa85f8d7282106dd /lib
parent3e24c20c7799f2f51b34589b9e8d2dbe49537bb7 (diff)
downloadclang-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.cpp35
-rw-r--r--lib/Basic/OpenMPKinds.cpp20
-rw-r--r--lib/Parse/ParseOpenMP.cpp19
-rw-r--r--lib/Sema/SemaOpenMP.cpp63
-rw-r--r--lib/Sema/TreeTransform.h26
-rw-r--r--lib/Serialization/ASTReader.cpp10
-rw-r--r--lib/Serialization/ASTWriter.cpp4
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())