@@ -6811,8 +6811,10 @@ class MappableExprsHandler {
6811
6811
OpenMPMapClauseKind MapType, ArrayRef<OpenMPMapModifierKind> MapModifiers,
6812
6812
ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
6813
6813
OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
6814
- MapCombinedInfoTy &CombinedInfo, StructRangeInfoTy &PartialStruct,
6815
- bool IsFirstComponentList, bool IsImplicit,
6814
+ MapCombinedInfoTy &CombinedInfo,
6815
+ MapCombinedInfoTy &StructBaseCombinedInfo,
6816
+ StructRangeInfoTy &PartialStruct, bool IsFirstComponentList,
6817
+ bool IsImplicit, bool GenerateAllInfoForClauses,
6816
6818
const ValueDecl *Mapper = nullptr, bool ForDeviceAddr = false,
6817
6819
const ValueDecl *BaseDecl = nullptr, const Expr *MapExpr = nullptr,
6818
6820
ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
@@ -7098,6 +7100,25 @@ class MappableExprsHandler {
7098
7100
bool IsNonContiguous = CombinedInfo.NonContigInfo.IsNonContiguous;
7099
7101
bool IsPrevMemberReference = false;
7100
7102
7103
+ // We need to check if we will be encountering any MEs. If we do not
7104
+ // encounter any ME expression it means we will be mapping the whole struct.
7105
+ // In that case we need to skip adding an entry for the struct to the
7106
+ // CombinedInfo list and instead add an entry to the StructBaseCombinedInfo
7107
+ // list only when generating all info for clauses.
7108
+ bool IsMappingWholeStruct = true;
7109
+ if (!GenerateAllInfoForClauses) {
7110
+ IsMappingWholeStruct = false;
7111
+ } else {
7112
+ for (auto TempI = I; TempI != CE; ++TempI) {
7113
+ const MemberExpr *PossibleME =
7114
+ dyn_cast<MemberExpr>(TempI->getAssociatedExpression());
7115
+ if (PossibleME) {
7116
+ IsMappingWholeStruct = false;
7117
+ break;
7118
+ }
7119
+ }
7120
+ }
7121
+
7101
7122
for (; I != CE; ++I) {
7102
7123
// If the current component is member of a struct (parent struct) mark it.
7103
7124
if (!EncounteredME) {
@@ -7317,21 +7338,41 @@ class MappableExprsHandler {
7317
7338
break;
7318
7339
}
7319
7340
llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
7341
+ // Skip adding an entry in the CurInfo of this combined entry if the
7342
+ // whole struct is currently being mapped. The struct needs to be added
7343
+ // in the first position before any data internal to the struct is being
7344
+ // mapped.
7320
7345
if (!IsMemberPointerOrAddr ||
7321
7346
(Next == CE && MapType != OMPC_MAP_unknown)) {
7322
- CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
7323
- CombinedInfo.BasePointers.push_back(BP.getPointer());
7324
- CombinedInfo.DevicePtrDecls.push_back(nullptr);
7325
- CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None);
7326
- CombinedInfo.Pointers.push_back(LB.getPointer());
7327
- CombinedInfo.Sizes.push_back(
7328
- CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true));
7329
- CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize
7330
- : 1);
7347
+ if (!IsMappingWholeStruct) {
7348
+ CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
7349
+ CombinedInfo.BasePointers.push_back(BP.getPointer());
7350
+ CombinedInfo.DevicePtrDecls.push_back(nullptr);
7351
+ CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None);
7352
+ CombinedInfo.Pointers.push_back(LB.getPointer());
7353
+ CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
7354
+ Size, CGF.Int64Ty, /*isSigned=*/true));
7355
+ CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize
7356
+ : 1);
7357
+ } else {
7358
+ StructBaseCombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
7359
+ StructBaseCombinedInfo.BasePointers.push_back(BP.getPointer());
7360
+ StructBaseCombinedInfo.DevicePtrDecls.push_back(nullptr);
7361
+ StructBaseCombinedInfo.DevicePointers.push_back(DeviceInfoTy::None);
7362
+ StructBaseCombinedInfo.Pointers.push_back(LB.getPointer());
7363
+ StructBaseCombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
7364
+ Size, CGF.Int64Ty, /*isSigned=*/true));
7365
+ StructBaseCombinedInfo.NonContigInfo.Dims.push_back(
7366
+ IsNonContiguous ? DimSize : 1);
7367
+ }
7331
7368
7332
7369
// If Mapper is valid, the last component inherits the mapper.
7333
7370
bool HasMapper = Mapper && Next == CE;
7334
- CombinedInfo.Mappers.push_back(HasMapper ? Mapper : nullptr);
7371
+ if (!IsMappingWholeStruct)
7372
+ CombinedInfo.Mappers.push_back(HasMapper ? Mapper : nullptr);
7373
+ else
7374
+ StructBaseCombinedInfo.Mappers.push_back(HasMapper ? Mapper
7375
+ : nullptr);
7335
7376
7336
7377
// We need to add a pointer flag for each map that comes from the
7337
7378
// same expression except for the first one. We also need to signal
@@ -7363,7 +7404,10 @@ class MappableExprsHandler {
7363
7404
}
7364
7405
}
7365
7406
7366
- CombinedInfo.Types.push_back(Flags);
7407
+ if (!IsMappingWholeStruct)
7408
+ CombinedInfo.Types.push_back(Flags);
7409
+ else
7410
+ StructBaseCombinedInfo.Types.push_back(Flags);
7367
7411
}
7368
7412
7369
7413
// If we have encountered a member expression so far, keep track of the
@@ -7954,8 +7998,10 @@ class MappableExprsHandler {
7954
7998
7955
7999
for (const auto &Data : Info) {
7956
8000
StructRangeInfoTy PartialStruct;
7957
- // Temporary generated information.
8001
+ // Current struct information:
7958
8002
MapCombinedInfoTy CurInfo;
8003
+ // Current struct base information:
8004
+ MapCombinedInfoTy StructBaseCurInfo;
7959
8005
const Decl *D = Data.first;
7960
8006
const ValueDecl *VD = cast_or_null<ValueDecl>(D);
7961
8007
for (const auto &M : Data.second) {
@@ -7965,29 +8011,55 @@ class MappableExprsHandler {
7965
8011
7966
8012
// Remember the current base pointer index.
7967
8013
unsigned CurrentBasePointersIdx = CurInfo.BasePointers.size();
8014
+ unsigned StructBasePointersIdx =
8015
+ StructBaseCurInfo.BasePointers.size();
7968
8016
CurInfo.NonContigInfo.IsNonContiguous =
7969
8017
L.Components.back().isNonContiguous();
7970
8018
generateInfoForComponentList(
7971
8019
L.MapType, L.MapModifiers, L.MotionModifiers, L.Components,
7972
- CurInfo, PartialStruct, /*IsFirstComponentList=*/false,
7973
- L.IsImplicit, L.Mapper, L.ForDeviceAddr, VD, L.VarRef);
8020
+ CurInfo, StructBaseCurInfo, PartialStruct,
8021
+ /*IsFirstComponentList=*/false, L.IsImplicit,
8022
+ /*GenerateAllInfoForClauses*/ true, L.Mapper, L.ForDeviceAddr, VD,
8023
+ L.VarRef);
7974
8024
7975
- // If this entry relates with a device pointer, set the relevant
8025
+ // If this entry relates to a device pointer, set the relevant
7976
8026
// declaration and add the 'return pointer' flag.
7977
8027
if (L.ReturnDevicePointer) {
7978
- assert(CurInfo.BasePointers.size() > CurrentBasePointersIdx &&
8028
+ // Check whether a value was added to either CurInfo or
8029
+ // StructBaseCurInfo and error if no value was added to either of
8030
+ // them:
8031
+ assert((CurrentBasePointersIdx < CurInfo.BasePointers.size() ||
8032
+ StructBasePointersIdx <
8033
+ StructBaseCurInfo.BasePointers.size()) &&
7979
8034
"Unexpected number of mapped base pointers.");
7980
8035
8036
+ // Choose a base pointer index which is always valid:
7981
8037
const ValueDecl *RelevantVD =
7982
8038
L.Components.back().getAssociatedDeclaration();
7983
8039
assert(RelevantVD &&
7984
8040
"No relevant declaration related with device pointer??");
7985
8041
7986
- CurInfo.DevicePtrDecls[CurrentBasePointersIdx] = RelevantVD;
7987
- CurInfo.DevicePointers[CurrentBasePointersIdx] =
7988
- L.ForDeviceAddr ? DeviceInfoTy::Address : DeviceInfoTy::Pointer;
7989
- CurInfo.Types[CurrentBasePointersIdx] |=
7990
- OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM;
8042
+ // If StructBaseCurInfo has been updated this iteration then work on
8043
+ // the first new entry added to it i.e. make sure that when multiple
8044
+ // values are added to any of the lists, the first value added is
8045
+ // being modified by the assignments below (not the last value
8046
+ // added).
8047
+ if (StructBasePointersIdx < StructBaseCurInfo.BasePointers.size()) {
8048
+ StructBaseCurInfo.DevicePtrDecls[StructBasePointersIdx] =
8049
+ RelevantVD;
8050
+ StructBaseCurInfo.DevicePointers[StructBasePointersIdx] =
8051
+ L.ForDeviceAddr ? DeviceInfoTy::Address
8052
+ : DeviceInfoTy::Pointer;
8053
+ StructBaseCurInfo.Types[StructBasePointersIdx] |=
8054
+ OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM;
8055
+ } else {
8056
+ CurInfo.DevicePtrDecls[CurrentBasePointersIdx] = RelevantVD;
8057
+ CurInfo.DevicePointers[CurrentBasePointersIdx] =
8058
+ L.ForDeviceAddr ? DeviceInfoTy::Address
8059
+ : DeviceInfoTy::Pointer;
8060
+ CurInfo.Types[CurrentBasePointersIdx] |=
8061
+ OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM;
8062
+ }
7991
8063
}
7992
8064
}
7993
8065
}
@@ -8034,17 +8106,24 @@ class MappableExprsHandler {
8034
8106
CurInfo.Mappers.push_back(nullptr);
8035
8107
}
8036
8108
}
8109
+
8110
+ // Unify entries in one list making sure the struct mapping precedes the
8111
+ // individual fields:
8112
+ MapCombinedInfoTy UnionCurInfo;
8113
+ UnionCurInfo.append(StructBaseCurInfo);
8114
+ UnionCurInfo.append(CurInfo);
8115
+
8037
8116
// If there is an entry in PartialStruct it means we have a struct with
8038
8117
// individual members mapped. Emit an extra combined entry.
8039
8118
if (PartialStruct.Base.isValid()) {
8040
- CurInfo.NonContigInfo.Dims.push_back(0);
8041
- emitCombinedEntry(CombinedInfo, CurInfo.Types, PartialStruct,
8119
+ UnionCurInfo.NonContigInfo.Dims.push_back(0);
8120
+ // Emit a combined entry:
8121
+ emitCombinedEntry(CombinedInfo, UnionCurInfo.Types, PartialStruct,
8042
8122
/*IsMapThis*/ !VD, OMPBuilder, VD);
8043
8123
}
8044
8124
8045
- // We need to append the results of this capture to what we already
8046
- // have.
8047
- CombinedInfo.append(CurInfo);
8125
+ // We need to append the results of this capture to what we already have.
8126
+ CombinedInfo.append(UnionCurInfo);
8048
8127
}
8049
8128
// Append data for use_device_ptr clauses.
8050
8129
CombinedInfo.append(UseDeviceDataCombinedInfo);
@@ -8554,6 +8633,7 @@ class MappableExprsHandler {
8554
8633
// Associated with a capture, because the mapping flags depend on it.
8555
8634
// Go through all of the elements with the overlapped elements.
8556
8635
bool IsFirstComponentList = true;
8636
+ MapCombinedInfoTy StructBaseCombinedInfo;
8557
8637
for (const auto &Pair : OverlappedData) {
8558
8638
const MapData &L = *Pair.getFirst();
8559
8639
OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
@@ -8568,7 +8648,8 @@ class MappableExprsHandler {
8568
8648
OverlappedComponents = Pair.getSecond();
8569
8649
generateInfoForComponentList(
8570
8650
MapType, MapModifiers, std::nullopt, Components, CombinedInfo,
8571
- PartialStruct, IsFirstComponentList, IsImplicit, Mapper,
8651
+ StructBaseCombinedInfo, PartialStruct, IsFirstComponentList,
8652
+ IsImplicit, /*GenerateAllInfoForClauses*/ false, Mapper,
8572
8653
/*ForDeviceAddr=*/false, VD, VarRef, OverlappedComponents);
8573
8654
IsFirstComponentList = false;
8574
8655
}
@@ -8584,10 +8665,11 @@ class MappableExprsHandler {
8584
8665
L;
8585
8666
auto It = OverlappedData.find(&L);
8586
8667
if (It == OverlappedData.end())
8587
- generateInfoForComponentList(MapType, MapModifiers, std::nullopt,
8588
- Components, CombinedInfo, PartialStruct,
8589
- IsFirstComponentList, IsImplicit, Mapper,
8590
- /*ForDeviceAddr=*/false, VD, VarRef);
8668
+ generateInfoForComponentList(
8669
+ MapType, MapModifiers, std::nullopt, Components, CombinedInfo,
8670
+ StructBaseCombinedInfo, PartialStruct, IsFirstComponentList,
8671
+ IsImplicit, /*GenerateAllInfoForClauses*/ false, Mapper,
8672
+ /*ForDeviceAddr=*/false, VD, VarRef);
8591
8673
IsFirstComponentList = false;
8592
8674
}
8593
8675
}
0 commit comments