Skip to content

Commit 0caf736

Browse files
committed
[OPENMP50]Mapping of the subcomponents with the 'default' mappers.
If the mapped structure has data members, which have 'default' mappers, need to map these members individually using their 'default' mappers. Differential Revision: https://reviews.llvm.org/D92195
1 parent 888c5c2 commit 0caf736

File tree

8 files changed

+590
-81
lines changed

8 files changed

+590
-81
lines changed

clang/include/clang/AST/OpenMPClause.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5355,14 +5355,14 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
53555355
if (!(--RemainingLists)) {
53565356
++DeclCur;
53575357
++NumListsCur;
5358-
if (SupportsMapper)
5359-
++MapperCur;
53605358
RemainingLists = *NumListsCur;
53615359
assert(RemainingLists && "No lists in the following declaration??");
53625360
}
53635361
}
53645362

53655363
++ListSizeCur;
5364+
if (SupportsMapper)
5365+
++MapperCur;
53665366
return *this;
53675367
}
53685368
};

clang/lib/CodeGen/CGOpenMPRuntime.cpp

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7151,11 +7151,13 @@ class MappableExprsHandler {
71517151
/// [ValueDecl *] --> {LE(FieldIndex, Pointer),
71527152
/// HE(FieldIndex, Pointer)}
71537153
struct StructRangeInfoTy {
7154+
MapCombinedInfoTy PreliminaryMapData;
71547155
std::pair<unsigned /*FieldIndex*/, Address /*Pointer*/> LowestElem = {
71557156
0, Address::invalid()};
71567157
std::pair<unsigned /*FieldIndex*/, Address /*Pointer*/> HighestElem = {
71577158
0, Address::invalid()};
71587159
Address Base = Address::invalid();
7160+
Address LB = Address::invalid();
71597161
bool IsArraySection = false;
71607162
bool HasCompleteRecord = false;
71617163
};
@@ -7754,11 +7756,9 @@ class MappableExprsHandler {
77547756
(IsPointer || ForDeviceAddr) && EncounteredME &&
77557757
(dyn_cast<MemberExpr>(I->getAssociatedExpression()) ==
77567758
EncounteredME);
7757-
if (!OverlappedElements.empty()) {
7759+
if (!OverlappedElements.empty() && Next == CE) {
77587760
// Handle base element with the info for overlapped elements.
77597761
assert(!PartialStruct.Base.isValid() && "The base element is set.");
7760-
assert(Next == CE &&
7761-
"Expected last element for the overlapped elements.");
77627762
assert(!IsPointer &&
77637763
"Unexpected base element with the pointer type.");
77647764
// Mark the whole struct as the struct that requires allocation on the
@@ -7775,13 +7775,17 @@ class MappableExprsHandler {
77757775
PartialStruct.HighestElem.first)>::max(),
77767776
HB};
77777777
PartialStruct.Base = BP;
7778+
PartialStruct.LB = LB;
7779+
assert(
7780+
PartialStruct.PreliminaryMapData.BasePointers.empty() &&
7781+
"Overlapped elements must be used only once for the variable.");
7782+
std::swap(PartialStruct.PreliminaryMapData, CombinedInfo);
77787783
// Emit data for non-overlapped data.
77797784
OpenMPOffloadMappingFlags Flags =
77807785
OMP_MAP_MEMBER_OF |
77817786
getMapTypeBits(MapType, MapModifiers, MotionModifiers, IsImplicit,
77827787
/*AddPtrFlag=*/false,
77837788
/*AddIsTargetParamFlag=*/false, IsNonContiguous);
7784-
LB = BP;
77857789
llvm::Value *Size = nullptr;
77867790
// Do bitcopy of all non-overlapped structure elements.
77877791
for (OMPClauseMappableExprCommon::MappableExprComponentListRef
@@ -7890,6 +7894,7 @@ class MappableExprsHandler {
78907894
PartialStruct.HighestElem = {FieldIndex, LB};
78917895
}
78927896
PartialStruct.Base = BP;
7897+
PartialStruct.LB = BP;
78937898
} else if (FieldIndex < PartialStruct.LowestElem.first) {
78947899
PartialStruct.LowestElem = {FieldIndex, LB};
78957900
} else if (FieldIndex > PartialStruct.HighestElem.first) {
@@ -8609,8 +8614,8 @@ class MappableExprsHandler {
86098614
Address LBAddr = PartialStruct.LowestElem.second;
86108615
Address HBAddr = PartialStruct.HighestElem.second;
86118616
if (PartialStruct.HasCompleteRecord) {
8612-
LBAddr = PartialStruct.Base;
8613-
HBAddr = PartialStruct.Base;
8617+
LBAddr = PartialStruct.LB;
8618+
HBAddr = PartialStruct.LB;
86148619
}
86158620
CombinedInfo.Exprs.push_back(VD);
86168621
// Base is the base of the struct
@@ -8909,11 +8914,17 @@ class MappableExprsHandler {
89098914
// Sort the overlapped elements for each item.
89108915
llvm::SmallVector<const FieldDecl *, 4> Layout;
89118916
if (!OverlappedData.empty()) {
8912-
if (const auto *CRD =
8913-
VD->getType().getCanonicalType()->getAsCXXRecordDecl())
8917+
const Type *BaseType = VD->getType().getCanonicalType().getTypePtr();
8918+
const Type *OrigType = BaseType->getPointeeOrArrayElementType();
8919+
while (BaseType != OrigType) {
8920+
BaseType = OrigType->getCanonicalTypeInternal().getTypePtr();
8921+
OrigType = BaseType->getPointeeOrArrayElementType();
8922+
}
8923+
8924+
if (const auto *CRD = BaseType->getAsCXXRecordDecl())
89148925
getPlainLayout(CRD, Layout, /*AsBase=*/false);
89158926
else {
8916-
const auto *RD = VD->getType().getCanonicalType()->getAsRecordDecl();
8927+
const auto *RD = BaseType->getAsRecordDecl();
89178928
Layout.append(RD->field_begin(), RD->field_end());
89188929
}
89198930
}
@@ -9567,10 +9578,12 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
95679578
/// void *base, void *begin,
95689579
/// int64_t size, int64_t type,
95699580
/// void *name = nullptr) {
9570-
/// // Allocate space for an array section first.
9571-
/// if ((size > 1 || base != begin) && !maptype.IsDelete)
9581+
/// // Allocate space for an array section first or add a base/begin for
9582+
/// // pointer dereference.
9583+
/// if ((size > 1 || (base != begin && maptype.IsPtrAndObj)) &&
9584+
/// !maptype.IsDelete)
95729585
/// __tgt_push_mapper_component(rt_mapper_handle, base, begin,
9573-
/// size*sizeof(Ty), clearToFrom(type));
9586+
/// size*sizeof(Ty), clearToFromMember(type));
95749587
/// // Map members.
95759588
/// for (unsigned i = 0; i < size; i++) {
95769589
/// // For each component specified by this mapper:
@@ -9585,9 +9598,9 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
95859598
/// }
95869599
/// }
95879600
/// // Delete the array section.
9588-
/// if ((size > 1 || base != begin) && maptype.IsDelete)
9601+
/// if (size > 1 && maptype.IsDelete)
95899602
/// __tgt_push_mapper_component(rt_mapper_handle, base, begin,
9590-
/// size*sizeof(Ty), clearToFrom(type));
9603+
/// size*sizeof(Ty), clearToFromMember(type));
95919604
/// }
95929605
/// \endcode
95939606
void CGOpenMPRuntime::emitUserDefinedMapper(const OMPDeclareMapperDecl *D,
@@ -9851,18 +9864,26 @@ void CGOpenMPRuntime::emitUDMapperArrayInitOrDel(
98519864
MapperCGF.createBasicBlock(getName({"omp.array", Prefix}));
98529865
llvm::Value *IsArray = MapperCGF.Builder.CreateICmpSGT(
98539866
Size, MapperCGF.Builder.getInt64(1), "omp.arrayinit.isarray");
9854-
// base != begin?
9855-
llvm::Value *BaseIsBegin = MapperCGF.Builder.CreateIsNotNull(
9856-
MapperCGF.Builder.CreatePtrDiff(Base, Begin));
9857-
llvm::Value *Cond = MapperCGF.Builder.CreateOr(IsArray, BaseIsBegin);
98589867
llvm::Value *DeleteBit = MapperCGF.Builder.CreateAnd(
98599868
MapType,
98609869
MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_DELETE));
98619870
llvm::Value *DeleteCond;
9871+
llvm::Value *Cond;
98629872
if (IsInit) {
9873+
// base != begin?
9874+
llvm::Value *BaseIsBegin = MapperCGF.Builder.CreateIsNotNull(
9875+
MapperCGF.Builder.CreatePtrDiff(Base, Begin));
9876+
// IsPtrAndObj?
9877+
llvm::Value *PtrAndObjBit = MapperCGF.Builder.CreateAnd(
9878+
MapType,
9879+
MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_PTR_AND_OBJ));
9880+
PtrAndObjBit = MapperCGF.Builder.CreateIsNotNull(PtrAndObjBit);
9881+
BaseIsBegin = MapperCGF.Builder.CreateAnd(BaseIsBegin, PtrAndObjBit);
9882+
Cond = MapperCGF.Builder.CreateOr(IsArray, BaseIsBegin);
98639883
DeleteCond = MapperCGF.Builder.CreateIsNull(
98649884
DeleteBit, getName({"omp.array", Prefix, ".delete"}));
98659885
} else {
9886+
Cond = IsArray;
98669887
DeleteCond = MapperCGF.Builder.CreateIsNotNull(
98679888
DeleteBit, getName({"omp.array", Prefix, ".delete"}));
98689889
}
@@ -9879,7 +9900,8 @@ void CGOpenMPRuntime::emitUDMapperArrayInitOrDel(
98799900
llvm::Value *MapTypeArg = MapperCGF.Builder.CreateAnd(
98809901
MapType,
98819902
MapperCGF.Builder.getInt64(~(MappableExprsHandler::OMP_MAP_TO |
9882-
MappableExprsHandler::OMP_MAP_FROM)));
9903+
MappableExprsHandler::OMP_MAP_FROM |
9904+
MappableExprsHandler::OMP_MAP_MEMBER_OF)));
98839905
llvm::Value *MapNameArg = llvm::ConstantPointerNull::get(CGM.VoidPtrTy);
98849906

98859907
// Call the runtime API __tgt_push_mapper_component to fill up the runtime
@@ -10171,9 +10193,12 @@ void CGOpenMPRuntime::emitTargetCall(
1017110193

1017210194
// If there is an entry in PartialStruct it means we have a struct with
1017310195
// individual members mapped. Emit an extra combined entry.
10174-
if (PartialStruct.Base.isValid())
10175-
MEHandler.emitCombinedEntry(CombinedInfo, CurInfo.Types, PartialStruct,
10176-
nullptr, /*NoTargetParam=*/false);
10196+
if (PartialStruct.Base.isValid()) {
10197+
CombinedInfo.append(PartialStruct.PreliminaryMapData);
10198+
MEHandler.emitCombinedEntry(
10199+
CombinedInfo, CurInfo.Types, PartialStruct, nullptr,
10200+
!PartialStruct.PreliminaryMapData.BasePointers.empty());
10201+
}
1017710202

1017810203
// We need to append the results of this capture to what we already have.
1017910204
CombinedInfo.append(CurInfo);

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 162 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5151,6 +5151,146 @@ static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
51515151
}
51525152
}
51535153

5154+
static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5155+
CXXScopeSpec &MapperIdScopeSpec,
5156+
const DeclarationNameInfo &MapperId,
5157+
QualType Type,
5158+
Expr *UnresolvedMapper);
5159+
5160+
/// Perform DFS through the structure/class data members trying to find
5161+
/// member(s) with user-defined 'default' mapper and generate implicit map
5162+
/// clauses for such members with the found 'default' mapper.
5163+
static void
5164+
processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5165+
SmallVectorImpl<OMPClause *> &Clauses) {
5166+
// Check for the deault mapper for data members.
5167+
if (S.getLangOpts().OpenMP < 50)
5168+
return;
5169+
SmallVector<OMPClause *, 4> ImplicitMaps;
5170+
DeclarationNameInfo DefaultMapperId;
5171+
DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5172+
&S.Context.Idents.get("default")));
5173+
for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5174+
auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5175+
if (!C)
5176+
continue;
5177+
SmallVector<Expr *, 4> SubExprs;
5178+
auto *MI = C->mapperlist_begin();
5179+
for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5180+
++I, ++MI) {
5181+
// Expression is mapped using mapper - skip it.
5182+
if (*MI)
5183+
continue;
5184+
Expr *E = *I;
5185+
// Expression is dependent - skip it, build the mapper when it gets
5186+
// instantiated.
5187+
if (E->isTypeDependent() || E->isValueDependent() ||
5188+
E->containsUnexpandedParameterPack())
5189+
continue;
5190+
// Array section - need to check for the mapping of the array section
5191+
// element.
5192+
QualType CanonType = E->getType().getCanonicalType();
5193+
if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5194+
const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5195+
QualType BaseType =
5196+
OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5197+
QualType ElemType;
5198+
if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5199+
ElemType = ATy->getElementType();
5200+
else
5201+
ElemType = BaseType->getPointeeType();
5202+
CanonType = ElemType;
5203+
}
5204+
5205+
// DFS over data members in structures/classes.
5206+
SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5207+
1, {CanonType, nullptr});
5208+
llvm::DenseMap<const Type *, Expr *> Visited;
5209+
SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5210+
1, {nullptr, 1});
5211+
while (!Types.empty()) {
5212+
QualType BaseType;
5213+
FieldDecl *CurFD;
5214+
std::tie(BaseType, CurFD) = Types.pop_back_val();
5215+
while (ParentChain.back().second == 0)
5216+
ParentChain.pop_back();
5217+
--ParentChain.back().second;
5218+
if (BaseType.isNull())
5219+
continue;
5220+
// Only structs/classes are allowed to have mappers.
5221+
const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5222+
if (!RD)
5223+
continue;
5224+
auto It = Visited.find(BaseType.getTypePtr());
5225+
if (It == Visited.end()) {
5226+
// Try to find the associated user-defined mapper.
5227+
CXXScopeSpec MapperIdScopeSpec;
5228+
ExprResult ER = buildUserDefinedMapperRef(
5229+
S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5230+
BaseType, /*UnresolvedMapper=*/nullptr);
5231+
if (ER.isInvalid())
5232+
continue;
5233+
It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5234+
}
5235+
// Found default mapper.
5236+
if (It->second) {
5237+
auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5238+
VK_LValue, OK_Ordinary, E);
5239+
OE->setIsUnique(/*V=*/true);
5240+
Expr *BaseExpr = OE;
5241+
for (const auto &P : ParentChain) {
5242+
if (P.first) {
5243+
BaseExpr = S.BuildMemberExpr(
5244+
BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5245+
NestedNameSpecifierLoc(), SourceLocation(), P.first,
5246+
DeclAccessPair::make(P.first, P.first->getAccess()),
5247+
/*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5248+
P.first->getType(), VK_LValue, OK_Ordinary);
5249+
BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5250+
}
5251+
}
5252+
if (CurFD)
5253+
BaseExpr = S.BuildMemberExpr(
5254+
BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5255+
NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5256+
DeclAccessPair::make(CurFD, CurFD->getAccess()),
5257+
/*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5258+
CurFD->getType(), VK_LValue, OK_Ordinary);
5259+
SubExprs.push_back(BaseExpr);
5260+
continue;
5261+
}
5262+
// Check for the "default" mapper for data memebers.
5263+
bool FirstIter = true;
5264+
for (FieldDecl *FD : RD->fields()) {
5265+
if (!FD)
5266+
continue;
5267+
QualType FieldTy = FD->getType();
5268+
if (FieldTy.isNull() ||
5269+
!(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5270+
continue;
5271+
if (FirstIter) {
5272+
FirstIter = false;
5273+
ParentChain.emplace_back(CurFD, 1);
5274+
} else {
5275+
++ParentChain.back().second;
5276+
}
5277+
Types.emplace_back(FieldTy, FD);
5278+
}
5279+
}
5280+
}
5281+
if (SubExprs.empty())
5282+
continue;
5283+
CXXScopeSpec MapperIdScopeSpec;
5284+
DeclarationNameInfo MapperId;
5285+
if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5286+
C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5287+
MapperIdScopeSpec, MapperId, C->getMapType(),
5288+
/*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5289+
SubExprs, OMPVarListLocTy()))
5290+
Clauses.push_back(NewClause);
5291+
}
5292+
}
5293+
51545294
StmtResult Sema::ActOnOpenMPExecutableDirective(
51555295
OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
51565296
OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
@@ -5271,6 +5411,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
52715411
}
52725412
}
52735413
}
5414+
// Build expressions for implicit maps of data members with 'default'
5415+
// mappers.
5416+
if (LangOpts.OpenMP >= 50)
5417+
processImplicitMapsWithDefaultMappers(*this, DSAStack,
5418+
ClausesWithImplicit);
52745419
}
52755420

52765421
llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
@@ -17502,6 +17647,14 @@ class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
1750217647
Components.emplace_back(COCE, nullptr, IsNonContiguous);
1750317648
return true;
1750417649
}
17650+
bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
17651+
Expr *Source = E->getSourceExpr();
17652+
if (!Source) {
17653+
emitErrorMsg();
17654+
return false;
17655+
}
17656+
return Visit(Source);
17657+
}
1750517658
bool VisitStmt(Stmt *) {
1750617659
emitErrorMsg();
1750717660
return false;
@@ -18622,8 +18775,15 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
1862218775
Diag(I->second, diag::note_previous_definition);
1862318776
Invalid = true;
1862418777
}
18625-
auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
18626-
MapperType, VN, Clauses, PrevDMD);
18778+
// Build expressions for implicit maps of data members with 'default'
18779+
// mappers.
18780+
SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
18781+
Clauses.end());
18782+
if (LangOpts.OpenMP >= 50)
18783+
processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
18784+
auto *DMD =
18785+
OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
18786+
ClausesWithImplicit, PrevDMD);
1862718787
if (S)
1862818788
PushOnScopeChains(DMD, S);
1862918789
else

0 commit comments

Comments
 (0)