[OpenMP 5.0] Parsing/sema support for to clause with mapper modifier.
This patch implements the parsing and sema support for OpenMP to clause with potential user-defined mappers attached. User defined mapper is a new feature in OpenMP 5.0. A to/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 to(mapper(id): ss) // use the mapper with name 'id' to map ss to device Contributed-by: <lildmh@gmail.com> Differential Revision: https://reviews.llvm.org/D58523 llvm-svn: 354698
This commit is contained in:
parent
8fffa1dfa3
commit
01f670df8f
|
@ -158,8 +158,11 @@ public:
|
|||
|
||||
/// This structure contains most locations needed for by an OMPVarListClause.
|
||||
struct OMPVarListLocTy {
|
||||
/// Starting location of the clause (the clause keyword).
|
||||
SourceLocation StartLoc;
|
||||
/// Location of '('.
|
||||
SourceLocation LParenLoc;
|
||||
/// Ending location of the clause.
|
||||
SourceLocation EndLoc;
|
||||
OMPVarListLocTy() = default;
|
||||
OMPVarListLocTy(SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
|
@ -3609,9 +3612,13 @@ protected:
|
|||
/// This structure contains all sizes needed for by an
|
||||
/// OMPMappableExprListClause.
|
||||
struct OMPMappableExprListSizeTy {
|
||||
/// Number of expressions listed.
|
||||
unsigned NumVars;
|
||||
/// Number of unique base declarations.
|
||||
unsigned NumUniqueDeclarations;
|
||||
/// Number of component lists.
|
||||
unsigned NumComponentLists;
|
||||
/// Total number of expression components.
|
||||
unsigned NumComponents;
|
||||
OMPMappableExprListSizeTy() = default;
|
||||
OMPMappableExprListSizeTy(unsigned NumVars, unsigned NumUniqueDeclarations,
|
||||
|
@ -4969,6 +4976,10 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
|
|||
|
||||
/// Build clause with number of variables \a NumVars.
|
||||
///
|
||||
/// \param MapperQualifierLoc C++ nested name specifier for the associated
|
||||
/// user-defined mapper.
|
||||
/// \param MapperIdInfo The identifier of associated user-defined mapper.
|
||||
/// \param MapType Map type.
|
||||
/// \param Locs Locations needed to build a mappable clause. It includes 1)
|
||||
/// StartLoc: starting location of the clause (the clause keyword); 2)
|
||||
/// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
|
||||
|
@ -4977,9 +4988,12 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
|
|||
/// NumUniqueDeclarations: number of unique base declarations in this clause;
|
||||
/// 3) NumComponentLists: number of component lists in this clause; and 4)
|
||||
/// NumComponents: total number of expression components in the clause.
|
||||
explicit OMPToClause(const OMPVarListLocTy &Locs,
|
||||
explicit OMPToClause(NestedNameSpecifierLoc MapperQualifierLoc,
|
||||
DeclarationNameInfo MapperIdInfo,
|
||||
const OMPVarListLocTy &Locs,
|
||||
const OMPMappableExprListSizeTy &Sizes)
|
||||
: OMPMappableExprListClause(OMPC_to, Locs, Sizes) {}
|
||||
: OMPMappableExprListClause(OMPC_to, Locs, Sizes, &MapperQualifierLoc,
|
||||
&MapperIdInfo) {}
|
||||
|
||||
/// Build an empty clause.
|
||||
///
|
||||
|
@ -4994,7 +5008,9 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
|
|||
/// Define the sizes of each trailing object array except the last one. This
|
||||
/// is required for TrailingObjects to work properly.
|
||||
size_t numTrailingObjects(OverloadToken<Expr *>) const {
|
||||
return varlist_size();
|
||||
// There are varlist_size() of expressions, and varlist_size() of
|
||||
// user-defined mappers.
|
||||
return 2 * varlist_size();
|
||||
}
|
||||
size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
|
||||
return getUniqueDeclarationsNum();
|
||||
|
@ -5013,10 +5029,18 @@ public:
|
|||
/// \param Vars The original expression used in the clause.
|
||||
/// \param Declarations Declarations used in the clause.
|
||||
/// \param ComponentLists Component lists used in the clause.
|
||||
/// \param UDMapperRefs References to user-defined mappers associated with
|
||||
/// expressions used in the clause.
|
||||
/// \param UDMQualifierLoc C++ nested name specifier for the associated
|
||||
/// user-defined mapper.
|
||||
/// \param MapperId The identifier of associated user-defined mapper.
|
||||
static OMPToClause *Create(const ASTContext &C, const OMPVarListLocTy &Locs,
|
||||
ArrayRef<Expr *> Vars,
|
||||
ArrayRef<ValueDecl *> Declarations,
|
||||
MappableExprComponentListsRef ComponentLists);
|
||||
MappableExprComponentListsRef ComponentLists,
|
||||
ArrayRef<Expr *> UDMapperRefs,
|
||||
NestedNameSpecifierLoc UDMQualifierLoc,
|
||||
DeclarationNameInfo MapperId);
|
||||
|
||||
/// Creates an empty clause with the place for \a NumVars variables.
|
||||
///
|
||||
|
|
|
@ -1175,7 +1175,7 @@ def err_omp_declare_target_unexpected_clause: Error<
|
|||
def err_omp_expected_clause: Error<
|
||||
"expected at least one clause on '#pragma omp %0' directive">;
|
||||
def err_omp_mapper_illegal_identifier : Error<
|
||||
"illegal identifier on 'omp declare mapper' directive">;
|
||||
"illegal OpenMP user-defined mapper identifier">;
|
||||
def err_omp_mapper_expected_declarator : Error<
|
||||
"expected declarator on 'omp declare mapper' directive">;
|
||||
|
||||
|
|
|
@ -122,6 +122,9 @@
|
|||
#ifndef OPENMP_MAP_MODIFIER_KIND
|
||||
#define OPENMP_MAP_MODIFIER_KIND(Name)
|
||||
#endif
|
||||
#ifndef OPENMP_TO_MODIFIER_KIND
|
||||
#define OPENMP_TO_MODIFIER_KIND(Name)
|
||||
#endif
|
||||
#ifndef OPENMP_DIST_SCHEDULE_KIND
|
||||
#define OPENMP_DIST_SCHEDULE_KIND(Name)
|
||||
#endif
|
||||
|
@ -578,6 +581,9 @@ OPENMP_MAP_MODIFIER_KIND(always)
|
|||
OPENMP_MAP_MODIFIER_KIND(close)
|
||||
OPENMP_MAP_MODIFIER_KIND(mapper)
|
||||
|
||||
// Modifiers for 'to' clause.
|
||||
OPENMP_TO_MODIFIER_KIND(mapper)
|
||||
|
||||
// Clauses allowed for OpenMP directive 'taskloop'.
|
||||
OPENMP_TASKLOOP_CLAUSE(if)
|
||||
OPENMP_TASKLOOP_CLAUSE(shared)
|
||||
|
@ -934,6 +940,7 @@ OPENMP_DECLARE_MAPPER_CLAUSE(map)
|
|||
#undef OPENMP_FOR_SIMD_CLAUSE
|
||||
#undef OPENMP_MAP_KIND
|
||||
#undef OPENMP_MAP_MODIFIER_KIND
|
||||
#undef OPENMP_TO_MODIFIER_KIND
|
||||
#undef OPENMP_DISTRIBUTE_CLAUSE
|
||||
#undef OPENMP_DIST_SCHEDULE_KIND
|
||||
#undef OPENMP_DEFAULTMAP_KIND
|
||||
|
|
|
@ -105,6 +105,14 @@ enum OpenMPMapModifierKind {
|
|||
OMPC_MAP_MODIFIER_last
|
||||
};
|
||||
|
||||
/// OpenMP modifier kind for 'to' clause.
|
||||
enum OpenMPToModifierKind {
|
||||
#define OPENMP_TO_MODIFIER_KIND(Name) \
|
||||
OMPC_TO_MODIFIER_##Name,
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
OMPC_TO_MODIFIER_unknown
|
||||
};
|
||||
|
||||
/// OpenMP attributes for 'dist_schedule' clause.
|
||||
enum OpenMPDistScheduleClauseKind {
|
||||
#define OPENMP_DIST_SCHEDULE_KIND(Name) OMPC_DIST_SCHEDULE_##Name,
|
||||
|
|
|
@ -2925,6 +2925,8 @@ public:
|
|||
ParsedType ObjectType,
|
||||
SourceLocation *TemplateKWLoc,
|
||||
UnqualifiedId &Result);
|
||||
/// Parses the mapper modifier in map, to, and from clauses.
|
||||
bool parseMapperModifier(OpenMPVarListDataTy &Data);
|
||||
/// Parses map-type-modifiers in map clause.
|
||||
/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
|
||||
/// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
|
||||
|
|
|
@ -9471,8 +9471,11 @@ public:
|
|||
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
|
||||
SourceLocation KindLoc, SourceLocation EndLoc);
|
||||
/// Called on well-formed 'to' clause.
|
||||
OMPClause *ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
|
||||
const OMPVarListLocTy &Locs);
|
||||
OMPClause *
|
||||
ActOnOpenMPToClause(ArrayRef<Expr *> VarList, CXXScopeSpec &MapperIdScopeSpec,
|
||||
DeclarationNameInfo &MapperId,
|
||||
const OMPVarListLocTy &Locs,
|
||||
ArrayRef<Expr *> UnresolvedMappers = llvm::None);
|
||||
/// Called on well-formed 'from' clause.
|
||||
OMPClause *ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
|
||||
const OMPVarListLocTy &Locs);
|
||||
|
|
|
@ -845,11 +845,11 @@ OMPMapClause::CreateEmpty(const ASTContext &C,
|
|||
return new (Mem) OMPMapClause(Sizes);
|
||||
}
|
||||
|
||||
OMPToClause *OMPToClause::Create(const ASTContext &C,
|
||||
const OMPVarListLocTy &Locs,
|
||||
ArrayRef<Expr *> Vars,
|
||||
ArrayRef<ValueDecl *> Declarations,
|
||||
MappableExprComponentListsRef ComponentLists) {
|
||||
OMPToClause *OMPToClause::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);
|
||||
|
@ -857,8 +857,8 @@ OMPToClause *OMPToClause::Create(const ASTContext &C,
|
|||
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
|
||||
|
@ -869,13 +869,14 @@ OMPToClause *OMPToClause::Create(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));
|
||||
|
||||
OMPToClause *Clause = new (Mem) OMPToClause(Locs, Sizes);
|
||||
auto *Clause = new (Mem) OMPToClause(UDMQualifierLoc, MapperId, Locs, Sizes);
|
||||
|
||||
Clause->setVarRefs(Vars);
|
||||
Clause->setUDMapperRefs(UDMapperRefs);
|
||||
Clause->setClauseInfo(Declarations, ComponentLists);
|
||||
return Clause;
|
||||
}
|
||||
|
@ -885,7 +886,7 @@ OMPToClause *OMPToClause::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) OMPToClause(Sizes);
|
||||
|
@ -1444,7 +1445,19 @@ void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
|
|||
void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
|
||||
if (!Node->varlist_empty()) {
|
||||
OS << "to";
|
||||
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 << ")";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,12 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
|
|||
.Case(#Name, static_cast<unsigned>(OMPC_MAP_MODIFIER_##Name))
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
.Default(OMPC_MAP_unknown);
|
||||
case OMPC_to:
|
||||
return llvm::StringSwitch<unsigned>(Str)
|
||||
#define OPENMP_TO_MODIFIER_KIND(Name) \
|
||||
.Case(#Name, static_cast<unsigned>(OMPC_TO_MODIFIER_##Name))
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
.Default(OMPC_TO_MODIFIER_unknown);
|
||||
case OMPC_dist_schedule:
|
||||
return llvm::StringSwitch<OpenMPDistScheduleClauseKind>(Str)
|
||||
#define OPENMP_DIST_SCHEDULE_KIND(Name) .Case(#Name, OMPC_DIST_SCHEDULE_##Name)
|
||||
|
@ -174,7 +180,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
|
|||
case OMPC_num_tasks:
|
||||
case OMPC_hint:
|
||||
case OMPC_uniform:
|
||||
case OMPC_to:
|
||||
case OMPC_from:
|
||||
case OMPC_use_device_ptr:
|
||||
case OMPC_is_device_ptr:
|
||||
|
@ -260,6 +265,18 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
|||
break;
|
||||
}
|
||||
llvm_unreachable("Invalid OpenMP 'map' clause type");
|
||||
case OMPC_to:
|
||||
switch (Type) {
|
||||
case OMPC_TO_MODIFIER_unknown:
|
||||
return "unknown";
|
||||
#define OPENMP_TO_MODIFIER_KIND(Name) \
|
||||
case OMPC_TO_MODIFIER_##Name: \
|
||||
return #Name;
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("Invalid OpenMP 'to' clause type");
|
||||
case OMPC_dist_schedule:
|
||||
switch (Type) {
|
||||
case OMPC_DIST_SCHEDULE_unknown:
|
||||
|
@ -333,7 +350,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
|||
case OMPC_num_tasks:
|
||||
case OMPC_hint:
|
||||
case OMPC_uniform:
|
||||
case OMPC_to:
|
||||
case OMPC_from:
|
||||
case OMPC_use_device_ptr:
|
||||
case OMPC_is_device_ptr:
|
||||
|
|
|
@ -1959,6 +1959,34 @@ static OpenMPMapModifierKind isMapModifier(Parser &P) {
|
|||
return TypeModifier;
|
||||
}
|
||||
|
||||
/// Parse the mapper modifier in map, to, and from clauses.
|
||||
bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
|
||||
// Parse '('.
|
||||
BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
|
||||
if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
|
||||
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
|
||||
StopBeforeMatch);
|
||||
return true;
|
||||
}
|
||||
// Parse mapper-identifier
|
||||
if (getLangOpts().CPlusPlus)
|
||||
ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
|
||||
/*ObjectType=*/nullptr,
|
||||
/*EnteringContext=*/false);
|
||||
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
|
||||
Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
|
||||
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
|
||||
StopBeforeMatch);
|
||||
return true;
|
||||
}
|
||||
auto &DeclNames = Actions.getASTContext().DeclarationNames;
|
||||
Data.ReductionOrMapperId = DeclarationNameInfo(
|
||||
DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
|
||||
ConsumeToken();
|
||||
// Parse ')'.
|
||||
return T.consumeClose();
|
||||
}
|
||||
|
||||
/// Parse map-type-modifiers in map clause.
|
||||
/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
|
||||
/// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
|
||||
|
@ -1974,30 +2002,8 @@ bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
|
|||
Data.MapTypeModifiers.push_back(TypeModifier);
|
||||
Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
|
||||
ConsumeToken();
|
||||
// Parse '('.
|
||||
BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
|
||||
if (T.expectAndConsume(diag::err_expected_lparen_after,
|
||||
getOpenMPSimpleClauseTypeName(
|
||||
OMPC_map, OMPC_MAP_MODIFIER_mapper))) {
|
||||
SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
|
||||
if (parseMapperModifier(Data))
|
||||
return true;
|
||||
}
|
||||
// Parse mapper-identifier
|
||||
if (getLangOpts().CPlusPlus)
|
||||
ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
|
||||
/*ObjectType=*/nullptr,
|
||||
/*EnteringContext=*/false);
|
||||
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
|
||||
Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
|
||||
SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
|
||||
return true;
|
||||
}
|
||||
auto &DeclNames = Actions.getASTContext().DeclarationNames;
|
||||
Data.ReductionOrMapperId = DeclarationNameInfo(
|
||||
DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
|
||||
ConsumeToken();
|
||||
// Parse ')'.
|
||||
T.consumeClose();
|
||||
} else {
|
||||
// For the case of unknown map-type-modifier or a map-type.
|
||||
// Map-type is followed by a colon; the function returns when it
|
||||
|
@ -2053,7 +2059,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
|||
OpenMPVarListDataTy &Data) {
|
||||
UnqualifiedId UnqualifiedReductionId;
|
||||
bool InvalidReductionId = false;
|
||||
bool IsInvalidMapModifier = false;
|
||||
bool IsInvalidMapperModifier = false;
|
||||
|
||||
// Parse '('.
|
||||
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
|
||||
|
@ -2142,9 +2148,11 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
|||
// Only parse map-type-modifier[s] and map-type if a colon is present in
|
||||
// the map clause.
|
||||
if (ColonPresent) {
|
||||
IsInvalidMapModifier = parseMapTypeModifiers(Data);
|
||||
if (!IsInvalidMapModifier)
|
||||
IsInvalidMapperModifier = parseMapTypeModifiers(Data);
|
||||
if (!IsInvalidMapperModifier)
|
||||
parseMapType(*this, Data);
|
||||
else
|
||||
SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
|
||||
}
|
||||
if (Data.MapType == OMPC_MAP_unknown) {
|
||||
Data.MapType = OMPC_MAP_tofrom;
|
||||
|
@ -2153,6 +2161,28 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
|||
|
||||
if (Tok.is(tok::colon))
|
||||
Data.ColonLoc = ConsumeToken();
|
||||
} else if (Kind == OMPC_to) {
|
||||
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 (IsMapperModifier) {
|
||||
// Parse the mapper modifier.
|
||||
ConsumeToken();
|
||||
IsInvalidMapperModifier = parseMapperModifier(Data);
|
||||
if (Tok.isNot(tok::colon)) {
|
||||
if (!IsInvalidMapperModifier)
|
||||
Diag(Tok, diag::warn_pragma_expected_colon) << ")";
|
||||
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
|
||||
StopBeforeMatch);
|
||||
}
|
||||
// Consume ':'.
|
||||
if (Tok.is(tok::colon))
|
||||
ConsumeToken();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsComma =
|
||||
|
@ -2214,7 +2244,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
|||
Vars.empty()) ||
|
||||
(Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
|
||||
(MustHaveTail && !Data.TailExpr) || InvalidReductionId ||
|
||||
IsInvalidMapModifier;
|
||||
IsInvalidMapperModifier;
|
||||
}
|
||||
|
||||
/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
|
||||
|
@ -2247,10 +2277,10 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
|||
/// 'depend' '(' in | out | inout : list | source ')'
|
||||
/// map-clause:
|
||||
/// 'map' '(' [ [ always [,] ] [ close [,] ]
|
||||
/// [ mapper(mapper-identifier) [,] ]
|
||||
/// [ mapper '(' mapper-identifier ')' [,] ]
|
||||
/// to | from | tofrom | alloc | release | delete ':' ] list ')';
|
||||
/// to-clause:
|
||||
/// 'to' '(' list ')'
|
||||
/// 'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
|
||||
/// from-clause:
|
||||
/// 'from' '(' list ')'
|
||||
/// use_device_ptr-clause:
|
||||
|
|
|
@ -9802,7 +9802,8 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
|
|||
DepLinMapLoc, ColonLoc, VarList, Locs);
|
||||
break;
|
||||
case OMPC_to:
|
||||
Res = ActOnOpenMPToClause(VarList, Locs);
|
||||
Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
|
||||
ReductionOrMapperId, Locs);
|
||||
break;
|
||||
case OMPC_from:
|
||||
Res = ActOnOpenMPFromClause(VarList, Locs);
|
||||
|
@ -13140,17 +13141,23 @@ struct MappableVarListInfo {
|
|||
static void checkMappableExpressionList(
|
||||
Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
|
||||
MappableVarListInfo &MVLI, SourceLocation StartLoc,
|
||||
CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
|
||||
ArrayRef<Expr *> UnresolvedMappers,
|
||||
OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
|
||||
bool IsMapTypeImplicit = false, CXXScopeSpec *MapperIdScopeSpec = nullptr,
|
||||
const DeclarationNameInfo *MapperId = nullptr,
|
||||
ArrayRef<Expr *> UnresolvedMappers = llvm::None) {
|
||||
bool IsMapTypeImplicit = false) {
|
||||
// We only expect mappable expressions in 'to', 'from', and 'map' clauses.
|
||||
assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
|
||||
"Unexpected clause kind with mappable expressions!");
|
||||
assert(
|
||||
((CKind == OMPC_map && MapperIdScopeSpec && MapperId) ||
|
||||
(CKind != OMPC_map && !MapperIdScopeSpec && !MapperId)) &&
|
||||
"Map clauses and only map clauses have user-defined mapper identifiers.");
|
||||
|
||||
// If the identifier of user-defined mapper is not specified, it is "default".
|
||||
// We do not change the actual name in this clause to distinguish whether a
|
||||
// mapper is specified explicitly, i.e., it is not explicitly specified when
|
||||
// MapperId.getName() is empty.
|
||||
if (!MapperId.getName() || MapperId.getName().isEmpty()) {
|
||||
auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
|
||||
MapperId.setName(DeclNames.getIdentifier(
|
||||
&SemaRef.getASTContext().Idents.get("default")));
|
||||
}
|
||||
|
||||
// Iterators to find the current unresolved mapper expression.
|
||||
auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
|
||||
|
@ -13183,16 +13190,14 @@ static void checkMappableExpressionList(
|
|||
if (VE->isValueDependent() || VE->isTypeDependent() ||
|
||||
VE->isInstantiationDependent() ||
|
||||
VE->containsUnexpandedParameterPack()) {
|
||||
if (CKind == OMPC_map) {
|
||||
if (CKind != OMPC_from) {
|
||||
// Try to find the associated user-defined mapper.
|
||||
ExprResult ER = buildUserDefinedMapperRef(
|
||||
SemaRef, DSAS->getCurScope(), *MapperIdScopeSpec, *MapperId,
|
||||
SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
|
||||
VE->getType().getCanonicalType(), UnresolvedMapper);
|
||||
if (ER.isInvalid())
|
||||
continue;
|
||||
MVLI.UDMapperList.push_back(ER.get());
|
||||
} else {
|
||||
MVLI.UDMapperList.push_back(nullptr);
|
||||
}
|
||||
// We can only analyze this information once the missing information is
|
||||
// resolved.
|
||||
|
@ -13225,16 +13230,14 @@ 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_map) {
|
||||
if (CKind != OMPC_from) {
|
||||
// Try to find the associated user-defined mapper.
|
||||
ExprResult ER = buildUserDefinedMapperRef(
|
||||
SemaRef, DSAS->getCurScope(), *MapperIdScopeSpec, *MapperId,
|
||||
SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
|
||||
VE->getType().getCanonicalType(), UnresolvedMapper);
|
||||
if (ER.isInvalid())
|
||||
continue;
|
||||
MVLI.UDMapperList.push_back(ER.get());
|
||||
} else {
|
||||
MVLI.UDMapperList.push_back(nullptr);
|
||||
}
|
||||
// Skip restriction checking for variable or field declarations
|
||||
MVLI.ProcessedVarList.push_back(RE);
|
||||
|
@ -13352,16 +13355,16 @@ static void checkMappableExpressionList(
|
|||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to find the associated user-defined mapper.
|
||||
// Try to find the associated user-defined mapper.
|
||||
if (CKind != OMPC_from) {
|
||||
ExprResult ER = buildUserDefinedMapperRef(
|
||||
SemaRef, DSAS->getCurScope(), *MapperIdScopeSpec, *MapperId,
|
||||
SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
|
||||
Type.getCanonicalType(), UnresolvedMapper);
|
||||
if (ER.isInvalid())
|
||||
continue;
|
||||
MVLI.UDMapperList.push_back(ER.get());
|
||||
} else {
|
||||
MVLI.UDMapperList.push_back(nullptr);
|
||||
}
|
||||
|
||||
// Save the current expression.
|
||||
|
@ -13410,17 +13413,10 @@ OMPClause *Sema::ActOnOpenMPMapClause(
|
|||
++Count;
|
||||
}
|
||||
|
||||
// If the identifier of user-defined mapper is not specified, it is "default".
|
||||
if (!MapperId.getName() || MapperId.getName().isEmpty()) {
|
||||
auto &DeclNames = getASTContext().DeclarationNames;
|
||||
MapperId.setName(
|
||||
DeclNames.getIdentifier(&getASTContext().Idents.get("default")));
|
||||
}
|
||||
|
||||
MappableVarListInfo MVLI(VarList);
|
||||
checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
|
||||
MapType, IsMapTypeImplicit, &MapperIdScopeSpec,
|
||||
&MapperId, UnresolvedMappers);
|
||||
MapperIdScopeSpec, MapperId, UnresolvedMappers,
|
||||
MapType, IsMapTypeImplicit);
|
||||
|
||||
// We need to produce a map clause even if we don't have variables so that
|
||||
// other diagnostics related with non-existing map clauses are accurate.
|
||||
|
@ -14169,20 +14165,30 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
|
|||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
|
||||
const OMPVarListLocTy &Locs) {
|
||||
CXXScopeSpec &MapperIdScopeSpec,
|
||||
DeclarationNameInfo &MapperId,
|
||||
const OMPVarListLocTy &Locs,
|
||||
ArrayRef<Expr *> UnresolvedMappers) {
|
||||
MappableVarListInfo MVLI(VarList);
|
||||
checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc);
|
||||
checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
|
||||
MapperIdScopeSpec, MapperId, UnresolvedMappers);
|
||||
if (MVLI.ProcessedVarList.empty())
|
||||
return nullptr;
|
||||
|
||||
return OMPToClause::Create(Context, Locs, MVLI.ProcessedVarList,
|
||||
MVLI.VarBaseDeclarations, MVLI.VarComponents);
|
||||
return OMPToClause::Create(
|
||||
Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
|
||||
MVLI.VarComponents, MVLI.UDMapperList,
|
||||
MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
|
||||
const OMPVarListLocTy &Locs) {
|
||||
MappableVarListInfo MVLI(VarList);
|
||||
checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc);
|
||||
CXXScopeSpec MapperIdScopeSpec;
|
||||
DeclarationNameInfo MapperId;
|
||||
ArrayRef<Expr *> UnresolvedMappers;
|
||||
checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
|
||||
MapperIdScopeSpec, MapperId, UnresolvedMappers);
|
||||
if (MVLI.ProcessedVarList.empty())
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -1902,8 +1902,12 @@ public:
|
|||
/// By default, performs semantic analysis to build the new statement.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
OMPClause *RebuildOMPToClause(ArrayRef<Expr *> VarList,
|
||||
const OMPVarListLocTy &Locs) {
|
||||
return getSema().ActOnOpenMPToClause(VarList, Locs);
|
||||
CXXScopeSpec &MapperIdScopeSpec,
|
||||
DeclarationNameInfo &MapperId,
|
||||
const OMPVarListLocTy &Locs,
|
||||
ArrayRef<Expr *> UnresolvedMappers) {
|
||||
return getSema().ActOnOpenMPToClause(VarList, MapperIdScopeSpec, MapperId,
|
||||
Locs, UnresolvedMappers);
|
||||
}
|
||||
|
||||
/// Build a new OpenMP 'from' clause.
|
||||
|
@ -8811,34 +8815,37 @@ TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
|
|||
C->getLParenLoc(), C->getEndLoc());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
|
||||
llvm::SmallVector<Expr *, 16> Vars;
|
||||
template <typename Derived, class T>
|
||||
bool transformOMPMappableExprListClause(
|
||||
TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
|
||||
llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
|
||||
DeclarationNameInfo &MapperIdInfo,
|
||||
llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
|
||||
// Transform expressions in the list.
|
||||
Vars.reserve(C->varlist_size());
|
||||
for (auto *VE : C->varlists()) {
|
||||
ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
|
||||
ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
|
||||
if (EVar.isInvalid())
|
||||
return nullptr;
|
||||
return true;
|
||||
Vars.push_back(EVar.get());
|
||||
}
|
||||
// Transform mapper scope specifier and identifier.
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
if (C->getMapperQualifierLoc()) {
|
||||
QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
|
||||
QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
|
||||
C->getMapperQualifierLoc());
|
||||
if (!QualifierLoc)
|
||||
return nullptr;
|
||||
return true;
|
||||
}
|
||||
CXXScopeSpec MapperIdScopeSpec;
|
||||
MapperIdScopeSpec.Adopt(QualifierLoc);
|
||||
DeclarationNameInfo MapperIdInfo = C->getMapperIdInfo();
|
||||
MapperIdInfo = C->getMapperIdInfo();
|
||||
if (MapperIdInfo.getName()) {
|
||||
MapperIdInfo = getDerived().TransformDeclarationNameInfo(MapperIdInfo);
|
||||
MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
|
||||
if (!MapperIdInfo.getName())
|
||||
return nullptr;
|
||||
return true;
|
||||
}
|
||||
// Build a list of all candidate OMPDeclareMapperDecls, which is provided by
|
||||
// the previous user-defined mapper lookup in dependent environment.
|
||||
llvm::SmallVector<Expr *, 16> UnresolvedMappers;
|
||||
for (auto *E : C->mapperlists()) {
|
||||
// Transform all the decls.
|
||||
if (E) {
|
||||
|
@ -8846,18 +8853,31 @@ OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
|
|||
UnresolvedSet<8> Decls;
|
||||
for (auto *D : ULE->decls()) {
|
||||
NamedDecl *InstD =
|
||||
cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
|
||||
cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
|
||||
Decls.addDecl(InstD, InstD->getAccess());
|
||||
}
|
||||
UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
|
||||
SemaRef.Context, /*NamingClass=*/nullptr,
|
||||
MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperIdInfo,
|
||||
/*ADL=*/false, ULE->isOverloaded(), Decls.begin(), Decls.end()));
|
||||
TT.getSema().Context, /*NamingClass=*/nullptr,
|
||||
MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
|
||||
MapperIdInfo, /*ADL=*/true, ULE->isOverloaded(), Decls.begin(),
|
||||
Decls.end()));
|
||||
} else {
|
||||
UnresolvedMappers.push_back(nullptr);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
|
||||
OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
|
||||
llvm::SmallVector<Expr *, 16> Vars;
|
||||
CXXScopeSpec MapperIdScopeSpec;
|
||||
DeclarationNameInfo MapperIdInfo;
|
||||
llvm::SmallVector<Expr *, 16> UnresolvedMappers;
|
||||
if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
|
||||
*this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
|
||||
return nullptr;
|
||||
return getDerived().RebuildOMPMapClause(
|
||||
C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), MapperIdScopeSpec,
|
||||
MapperIdInfo, C->getMapType(), C->isImplicitMapType(), C->getMapLoc(),
|
||||
|
@ -8942,16 +8962,16 @@ TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
|
|||
|
||||
template <typename Derived>
|
||||
OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *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().RebuildOMPToClause(Vars, Locs);
|
||||
llvm::SmallVector<Expr *, 16> Vars;
|
||||
CXXScopeSpec MapperIdScopeSpec;
|
||||
DeclarationNameInfo MapperIdInfo;
|
||||
llvm::SmallVector<Expr *, 16> UnresolvedMappers;
|
||||
if (transformOMPMappableExprListClause<Derived, OMPToClause>(
|
||||
*this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
|
||||
return nullptr;
|
||||
return getDerived().RebuildOMPToClause(Vars, MapperIdScopeSpec, MapperIdInfo,
|
||||
Locs, UnresolvedMappers);
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
|
|
|
@ -12396,6 +12396,10 @@ void OMPClauseReader::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
|
|||
|
||||
void OMPClauseReader::VisitOMPToClause(OMPToClause *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();
|
||||
|
@ -12407,6 +12411,12 @@ void OMPClauseReader::VisitOMPToClause(OMPToClause *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)
|
||||
|
|
|
@ -6861,8 +6861,12 @@ void OMPClauseWriter::VisitOMPToClause(OMPToClause *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())
|
||||
|
|
|
@ -48,6 +48,8 @@ int main() {
|
|||
#pragma omp target map(mapper(default), from: dd[0:10])
|
||||
// CHECK: #pragma omp target map(mapper(default),from: dd[0:10])
|
||||
{ dd[0].i++; }
|
||||
#pragma omp target update to(mapper(id): vv)
|
||||
// CHECK: #pragma omp target update to(mapper(id): vv)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,8 @@ T foo(T a) {
|
|||
{ fd.a++; }
|
||||
#pragma omp target map(mapper(idd) alloc: fd.b)
|
||||
{ fd.b.k++; }
|
||||
#pragma omp target update to(mapper(id): fd)
|
||||
#pragma omp target update to(mapper(idd): fd.b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -93,6 +95,8 @@ T foo(T a) {
|
|||
// CHECK: }
|
||||
// CHECK: #pragma omp target map(mapper(id),alloc: fd)
|
||||
// CHECK: #pragma omp target map(mapper(idd),alloc: fd.b)
|
||||
// CHECK: #pragma omp target update to(mapper(id): fd)
|
||||
// CHECK: #pragma omp target update to(mapper(idd): fd.b)
|
||||
// CHECK: }
|
||||
// CHECK: template<> int foo<int>(int a) {
|
||||
// CHECK: #pragma omp declare mapper (id : struct foodat v) map(tofrom: v.a)
|
||||
|
@ -103,6 +107,8 @@ T foo(T a) {
|
|||
// CHECK: }
|
||||
// CHECK: #pragma omp target map(mapper(id),alloc: fd)
|
||||
// CHECK: #pragma omp target map(mapper(idd),alloc: fd.b)
|
||||
// CHECK: #pragma omp target update to(mapper(id): fd)
|
||||
// CHECK: #pragma omp target update to(mapper(idd): fd.b)
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: int main() {
|
||||
|
@ -119,6 +125,12 @@ int main() {
|
|||
#pragma omp target map(mapper(default) tofrom: dd)
|
||||
// CHECK: #pragma omp target map(mapper(default),tofrom: dd)
|
||||
{ dd.d++; }
|
||||
|
||||
#pragma omp target update to(mapper(N1::id) : vc)
|
||||
// CHECK: #pragma omp target update to(mapper(N1::id): vc)
|
||||
#pragma omp target update to(mapper(dat<double>::id): vvv)
|
||||
// CHECK: #pragma omp target update to(mapper(dat<double>::id): vvv)
|
||||
|
||||
#pragma omp declare mapper(id: N1::vec v) map(v.len)
|
||||
// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
|
||||
{
|
||||
|
|
|
@ -26,10 +26,12 @@ public:
|
|||
|
||||
#pragma omp declare mapper(id: C s) map(s.a)
|
||||
|
||||
// CHECK-LABEL: @.__omp_offloading_{{.*}}foo{{.*}}_l49.region_id = weak constant i8 0
|
||||
// CHECK-LABEL: @.__omp_offloading_{{.*}}foo{{.*}}_l52.region_id = weak constant i8 0
|
||||
|
||||
// CHECK-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i{{64|32}}] [i{{64|32}} 4]
|
||||
// CHECK-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 35]
|
||||
// CHECK: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
|
||||
// CHECK: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 35]
|
||||
// CHECK: [[TSIZES:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4]
|
||||
// CHECK: [[TTYPES:@.+]] = {{.+}}constant [1 x i64] [i64 33]
|
||||
|
||||
// CHECK-LABEL: foo{{.*}}(
|
||||
void foo(int a){
|
||||
|
@ -46,11 +48,22 @@ void foo(int a){
|
|||
// CHECK-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to %class.C**
|
||||
// CHECK-DAG: store %class.C* [[VAL:%[^,]+]], %class.C** [[CBP1]]
|
||||
// CHECK-DAG: store %class.C* [[VAL]], %class.C** [[CP1]]
|
||||
// CHECK: call void [[KERNEL:@.+]](%class.C* [[VAL]])
|
||||
#pragma omp target map(mapper(id),tofrom: c)
|
||||
{
|
||||
++c.a;
|
||||
}
|
||||
// CHECK: call void [[KERNEL:@.+]](%class.C* [[VAL]])
|
||||
|
||||
// CHECK-DAG: call void @__tgt_target_data_update(i64 -1, i32 1, i8** [[TGEPBP:%.+]], i8** [[TGEPP:%.+]], i[[sz]]* getelementptr {{.+}}[1 x i[[sz]]]* [[TSIZES]], i32 0, i32 0), {{.+}}getelementptr {{.+}}[1 x i64]* [[TTYPES]]{{.+}})
|
||||
// CHECK-DAG: [[TGEPBP]] = getelementptr inbounds {{.+}}[[TBP:%[^,]+]], i{{.+}} 0, i{{.+}} 0
|
||||
// CHECK-DAG: [[TGEPP]] = getelementptr inbounds {{.+}}[[TP:%[^,]+]], i{{.+}} 0, i{{.+}} 0
|
||||
// CHECK-DAG: [[TBP0:%.+]] = getelementptr inbounds {{.+}}[[TBP]], i{{.+}} 0, i{{.+}} 0
|
||||
// CHECK-DAG: [[TP0:%.+]] = getelementptr inbounds {{.+}}[[TP]], i{{.+}} 0, i{{.+}} 0
|
||||
// CHECK-DAG: [[TCBP0:%.+]] = bitcast i8** [[TBP0]] to %class.C**
|
||||
// CHECK-DAG: [[TCP0:%.+]] = bitcast i8** [[TP0]] to %class.C**
|
||||
// CHECK-DAG: store %class.C* [[VAL]], %class.C** [[TCBP0]]
|
||||
// CHECK-DAG: store %class.C* [[VAL]], %class.C** [[TCP0]]
|
||||
#pragma omp target update to(mapper(id): c)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ struct vec { // expec
|
|||
#pragma omp declare mapper(bb:struct vec v) private(v) // expected-error {{expected at least one clause on '#pragma omp declare mapper' directive}} // expected-error {{unexpected OpenMP clause 'private' in directive '#pragma omp declare mapper'}}
|
||||
#pragma omp declare mapper(cc:struct vec v) map(v) ( // expected-warning {{extra tokens at the end of '#pragma omp declare mapper' are ignored}}
|
||||
|
||||
#pragma omp declare mapper(++: struct vec v) map(v.len) // expected-error {{illegal identifier on 'omp declare mapper' directive}}
|
||||
#pragma omp declare mapper(++: struct vec v) map(v.len) // expected-error {{illegal OpenMP user-defined mapper identifier}}
|
||||
#pragma omp declare mapper(id1: struct vec v) map(v.len, temp) // expected-error {{only variable v is allowed in map clauses of this 'omp declare mapper' directive}}
|
||||
#pragma omp declare mapper(default : struct vec kk) map(kk.data[0:2]) // expected-note {{previous definition is here}}
|
||||
#pragma omp declare mapper(struct vec v) map(v.len) // expected-error {{redefinition of user-defined mapper for type 'struct vec' with name 'default'}}
|
||||
|
@ -50,6 +50,14 @@ int fun(int arg) {
|
|||
{}
|
||||
#pragma omp target map(mapper(aa) to:vv) map(close mapper(aa) from:v1)
|
||||
{}
|
||||
|
||||
#pragma omp target update to(mapper) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper() // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper:vv) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper(:vv) // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper(aa :vv) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper(ab):vv) // expected-error {{cannot find a valid user-defined mapper for type 'struct vec' with name 'ab'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper(aa):vv)
|
||||
}
|
||||
}
|
||||
return arg;
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
#pragma omp declare mapper(bb: vec v) private(v) // expected-error {{expected at least one clause on '#pragma omp declare mapper' directive}} // expected-error {{unexpected OpenMP clause 'private' in directive '#pragma omp declare mapper'}}
|
||||
#pragma omp declare mapper(cc: vec v) map(v) ( // expected-warning {{extra tokens at the end of '#pragma omp declare mapper' are ignored}}
|
||||
|
||||
#pragma omp declare mapper(++: vec v) map(v.len) // expected-error {{illegal identifier on 'omp declare mapper' directive}}
|
||||
#pragma omp declare mapper(++: vec v) map(v.len) // expected-error {{illegal OpenMP user-defined mapper identifier}}
|
||||
#pragma omp declare mapper(id1: vec v) map(v.len, temp) // expected-error {{only variable v is allowed in map clauses of this 'omp declare mapper' directive}}
|
||||
#pragma omp declare mapper(default : vec kk) map(kk.data[0:2]) // expected-note {{previous definition is here}}
|
||||
#pragma omp declare mapper(vec v) map(v.len) // expected-error {{redefinition of user-defined mapper for type 'vec' with name 'default'}}
|
||||
|
@ -74,9 +74,9 @@ int fun(int arg) {
|
|||
{}
|
||||
#pragma omp target map(mapper(ab) :vv) // expected-error {{missing map type}} expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'ab'}}
|
||||
{}
|
||||
#pragma omp target map(mapper(N2::) :vv) // expected-error {{use of undeclared identifier 'N2'}} expected-error {{illegal identifier on 'omp declare mapper' directive}}
|
||||
#pragma omp target map(mapper(N2::) :vv) // expected-error {{use of undeclared identifier 'N2'}} expected-error {{illegal OpenMP user-defined mapper identifier}}
|
||||
{}
|
||||
#pragma omp target map(mapper(N1::) :vv) // expected-error {{illegal identifier on 'omp declare mapper' directive}}
|
||||
#pragma omp target map(mapper(N1::) :vv) // expected-error {{illegal OpenMP user-defined mapper identifier}}
|
||||
{}
|
||||
#pragma omp target map(mapper(aa) :vv) // expected-error {{missing map type}}
|
||||
{}
|
||||
|
@ -86,6 +86,19 @@ int fun(int arg) {
|
|||
{}
|
||||
#pragma omp target map(mapper(N1::stack<int>::id) to:vv)
|
||||
{}
|
||||
|
||||
#pragma omp target update to(mapper) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper() // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper:vv) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper(:vv) // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper(aa :vv) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper(N2:: :vv) // expected-error {{use of undeclared identifier 'N2'}} expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper(N1:: :vv) // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper(N1::aa) :vv) // expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'aa'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper(ab):vv) // expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'ab'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(mapper(aa) a:vv) // expected-warning {{missing ':' after ) - ignoring}}
|
||||
#pragma omp target update to(mapper(aa):vv)
|
||||
#pragma omp target update to(mapper(N1::stack<int>::id) :vv)
|
||||
}
|
||||
#pragma omp declare mapper(id: vec v) map(v.len) // expected-error {{redefinition of user-defined mapper for type 'vec' with name 'id'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue