@@ -7031,7 +7031,7 @@ class MappableExprsHandler {
7031
7031
OMP_MAP_TARGET_PARAM = 0x20,
7032
7032
/// Signal that the runtime library has to return the device pointer
7033
7033
/// in the current position for the data being mapped. Used when we have the
7034
- // / use_device_ptr clause.
7034
+ /// use_device_ptr or use_device_addr clause.
7035
7035
OMP_MAP_RETURN_PARAM = 0x40,
7036
7036
/// This flag signals that the reference being passed is a pointer to
7037
7037
/// private data.
@@ -7099,26 +7099,30 @@ class MappableExprsHandler {
7099
7099
ArrayRef<OpenMPMapModifierKind> MapModifiers;
7100
7100
bool ReturnDevicePointer = false;
7101
7101
bool IsImplicit = false;
7102
+ bool ForDeviceAddr = false;
7102
7103
7103
7104
MapInfo() = default;
7104
7105
MapInfo(
7105
7106
OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
7106
7107
OpenMPMapClauseKind MapType,
7107
- ArrayRef<OpenMPMapModifierKind> MapModifiers,
7108
- bool ReturnDevicePointer , bool IsImplicit )
7108
+ ArrayRef<OpenMPMapModifierKind> MapModifiers, bool ReturnDevicePointer,
7109
+ bool IsImplicit , bool ForDeviceAddr = false )
7109
7110
: Components(Components), MapType(MapType), MapModifiers(MapModifiers),
7110
- ReturnDevicePointer (ReturnDevicePointer), IsImplicit(IsImplicit) {}
7111
+ ReturnDevicePointer(ReturnDevicePointer), IsImplicit(IsImplicit),
7112
+ ForDeviceAddr(ForDeviceAddr) {}
7111
7113
};
7112
7114
7113
- // / If use_device_ptr is used on a pointer which is a struct member and there
7114
- // / is no map information about it, then emission of that entry is deferred
7115
- // / until the whole struct has been processed.
7115
+ /// If use_device_ptr or use_device_addr is used on a decl which is a struct
7116
+ /// member and there is no map information about it, then emission of that
7117
+ /// entry is deferred until the whole struct has been processed.
7116
7118
struct DeferredDevicePtrEntryTy {
7117
7119
const Expr *IE = nullptr;
7118
7120
const ValueDecl *VD = nullptr;
7121
+ bool ForDeviceAddr = false;
7119
7122
7120
- DeferredDevicePtrEntryTy (const Expr *IE, const ValueDecl *VD)
7121
- : IE(IE), VD(VD) {}
7123
+ DeferredDevicePtrEntryTy(const Expr *IE, const ValueDecl *VD,
7124
+ bool ForDeviceAddr)
7125
+ : IE(IE), VD(VD), ForDeviceAddr(ForDeviceAddr) {}
7122
7126
};
7123
7127
7124
7128
/// The target directive from where the mappable clauses were extracted. It
@@ -7306,13 +7310,12 @@ class MappableExprsHandler {
7306
7310
/// \a IsFirstComponent should be set to true if the provided set of
7307
7311
/// components is the first associated with a capture.
7308
7312
void generateInfoForComponentList(
7309
- OpenMPMapClauseKind MapType,
7310
- ArrayRef<OpenMPMapModifierKind> MapModifiers,
7313
+ OpenMPMapClauseKind MapType, ArrayRef<OpenMPMapModifierKind> MapModifiers,
7311
7314
OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
7312
7315
MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
7313
7316
MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
7314
7317
StructRangeInfoTy &PartialStruct, bool IsFirstComponentList,
7315
- bool IsImplicit,
7318
+ bool IsImplicit, bool ForDeviceAddr = false,
7316
7319
ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
7317
7320
OverlappedElements = llvm::None) const {
7318
7321
// The following summarizes what has to be generated for each map and the
@@ -7623,8 +7626,8 @@ class MappableExprsHandler {
7623
7626
// If this component is a pointer inside the base struct then we don't
7624
7627
// need to create any entry for it - it will be combined with the object
7625
7628
// it is pointing to into a single PTR_AND_OBJ entry.
7626
- bool IsMemberPointer =
7627
- IsPointer && EncounteredME &&
7629
+ bool IsMemberPointerOrAddr =
7630
+ ( IsPointer || ForDeviceAddr) && EncounteredME &&
7628
7631
(dyn_cast<MemberExpr>(I->getAssociatedExpression()) ==
7629
7632
EncounteredME);
7630
7633
if (!OverlappedElements.empty()) {
@@ -7691,7 +7694,7 @@ class MappableExprsHandler {
7691
7694
break;
7692
7695
}
7693
7696
llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
7694
- if (!IsMemberPointer ) {
7697
+ if (!IsMemberPointerOrAddr ) {
7695
7698
BasePointers.push_back(BP.getPointer());
7696
7699
Pointers.push_back(LB.getPointer());
7697
7700
Sizes.push_back(
@@ -7952,17 +7955,18 @@ class MappableExprsHandler {
7952
7955
7953
7956
// Helper function to fill the information map for the different supported
7954
7957
// clauses.
7955
- auto &&InfoGen = [&Info](
7956
- const ValueDecl *D,
7957
- OMPClauseMappableExprCommon::MappableExprComponentListRef L,
7958
- OpenMPMapClauseKind MapType,
7959
- ArrayRef<OpenMPMapModifierKind> MapModifiers,
7960
- bool ReturnDevicePointer, bool IsImplicit) {
7961
- const ValueDecl *VD =
7962
- D ? cast<ValueDecl>(D->getCanonicalDecl ()) : nullptr ;
7963
- Info[VD].emplace_back (L, MapType, MapModifiers, ReturnDevicePointer,
7964
- IsImplicit);
7965
- };
7958
+ auto &&InfoGen =
7959
+ [&Info](const ValueDecl *D,
7960
+ OMPClauseMappableExprCommon::MappableExprComponentListRef L,
7961
+ OpenMPMapClauseKind MapType,
7962
+ ArrayRef<OpenMPMapModifierKind> MapModifiers,
7963
+ bool ReturnDevicePointer, bool IsImplicit,
7964
+ bool ForDeviceAddr = false) {
7965
+ const ValueDecl *VD =
7966
+ D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
7967
+ Info[VD].emplace_back(L, MapType, MapModifiers, ReturnDevicePointer,
7968
+ IsImplicit, ForDeviceAddr);
7969
+ };
7966
7970
7967
7971
assert(CurDir.is<const OMPExecutableDirective *>() &&
7968
7972
"Expect a executable directive");
@@ -8032,7 +8036,7 @@ class MappableExprsHandler {
8032
8036
// partial struct.
8033
8037
InfoGen(nullptr, L.second, OMPC_MAP_unknown, llvm::None,
8034
8038
/*ReturnDevicePointer=*/false, C->isImplicit());
8035
- DeferredInfo[nullptr ].emplace_back (IE, VD);
8039
+ DeferredInfo[nullptr].emplace_back(IE, VD, /*ForDeviceAddr=*/false );
8036
8040
} else {
8037
8041
llvm::Value *Ptr =
8038
8042
CGF.EmitLoadOfScalar(CGF.EmitLValue(IE), IE->getExprLoc());
@@ -8044,6 +8048,70 @@ class MappableExprsHandler {
8044
8048
}
8045
8049
}
8046
8050
8051
+ // Look at the use_device_addr clause information and mark the existing map
8052
+ // entries as such. If there is no map information for an entry in the
8053
+ // use_device_addr list, we create one with map type 'alloc' and zero size
8054
+ // section. It is the user fault if that was not mapped before. If there is
8055
+ // no map information and the pointer is a struct member, then we defer the
8056
+ // emission of that entry until the whole struct has been processed.
8057
+ llvm::SmallDenseSet<CanonicalDeclPtr<const Decl>, 4> Processed;
8058
+ for (const auto *C :
8059
+ CurExecDir->getClausesOfKind<OMPUseDeviceAddrClause>()) {
8060
+ for (const auto L : C->component_lists()) {
8061
+ assert(!L.second.empty() && "Not expecting empty list of components!");
8062
+ const ValueDecl *VD = L.second.back().getAssociatedDeclaration();
8063
+ if (!Processed.insert(VD).second)
8064
+ continue;
8065
+ VD = cast<ValueDecl>(VD->getCanonicalDecl());
8066
+ const Expr *IE = L.second.back().getAssociatedExpression();
8067
+ // If the first component is a member expression, we have to look into
8068
+ // 'this', which maps to null in the map of map information. Otherwise
8069
+ // look directly for the information.
8070
+ auto It = Info.find(isa<MemberExpr>(IE) ? nullptr : VD);
8071
+
8072
+ // We potentially have map information for this declaration already.
8073
+ // Look for the first set of components that refer to it.
8074
+ if (It != Info.end()) {
8075
+ auto *CI = llvm::find_if(It->second, [VD](const MapInfo &MI) {
8076
+ return MI.Components.back().getAssociatedDeclaration() == VD;
8077
+ });
8078
+ // If we found a map entry, signal that the pointer has to be returned
8079
+ // and move on to the next declaration.
8080
+ if (CI != It->second.end()) {
8081
+ CI->ReturnDevicePointer = true;
8082
+ continue;
8083
+ }
8084
+ }
8085
+
8086
+ // We didn't find any match in our map information - generate a zero
8087
+ // size array section - if the pointer is a struct member we defer this
8088
+ // action until the whole struct has been processed.
8089
+ if (isa<MemberExpr>(IE)) {
8090
+ // Insert the pointer into Info to be processed by
8091
+ // generateInfoForComponentList. Because it is a member pointer
8092
+ // without a pointee, no entry will be generated for it, therefore
8093
+ // we need to generate one after the whole struct has been processed.
8094
+ // Nonetheless, generateInfoForComponentList must be called to take
8095
+ // the pointer into account for the calculation of the range of the
8096
+ // partial struct.
8097
+ InfoGen(nullptr, L.second, OMPC_MAP_unknown, llvm::None,
8098
+ /*ReturnDevicePointer=*/false, C->isImplicit(),
8099
+ /*ForDeviceAddr=*/true);
8100
+ DeferredInfo[nullptr].emplace_back(IE, VD, /*ForDeviceAddr=*/true);
8101
+ } else {
8102
+ llvm::Value *Ptr;
8103
+ if (IE->isGLValue())
8104
+ Ptr = CGF.EmitLValue(IE).getPointer(CGF);
8105
+ else
8106
+ Ptr = CGF.EmitScalarExpr(IE);
8107
+ BasePointers.emplace_back(Ptr, VD);
8108
+ Pointers.push_back(Ptr);
8109
+ Sizes.push_back(llvm::Constant::getNullValue(CGF.Int64Ty));
8110
+ Types.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_TARGET_PARAM);
8111
+ }
8112
+ }
8113
+ }
8114
+
8047
8115
for (const auto &M : Info) {
8048
8116
// We need to know when we generate information for the first component
8049
8117
// associated with a capture, because the mapping flags depend on it.
@@ -8062,10 +8130,10 @@ class MappableExprsHandler {
8062
8130
8063
8131
// Remember the current base pointer index.
8064
8132
unsigned CurrentBasePointersIdx = CurBasePointers.size();
8065
- generateInfoForComponentList (L. MapType , L. MapModifiers , L. Components ,
8066
- CurBasePointers, CurPointers, CurSizes ,
8067
- CurTypes, PartialStruct,
8068
- IsFirstComponentList, L.IsImplicit );
8133
+ generateInfoForComponentList(
8134
+ L.MapType, L.MapModifiers, L.Components, CurBasePointers ,
8135
+ CurPointers, CurSizes, CurTypes, PartialStruct,
8136
+ IsFirstComponentList, L.IsImplicit, L.ForDeviceAddr );
8069
8137
8070
8138
// If this entry relates with a device pointer, set the relevant
8071
8139
// declaration and add the 'return pointer' flag.
@@ -8085,21 +8153,35 @@ class MappableExprsHandler {
8085
8153
}
8086
8154
8087
8155
// Append any pending zero-length pointers which are struct members and
8088
- // used with use_device_ptr.
8156
+ // used with use_device_ptr or use_device_addr .
8089
8157
auto CI = DeferredInfo.find(M.first);
8090
8158
if (CI != DeferredInfo.end()) {
8091
8159
for (const DeferredDevicePtrEntryTy &L : CI->second) {
8092
- llvm::Value *BasePtr = this ->CGF .EmitLValue (L.IE ).getPointer (CGF);
8093
- llvm::Value *Ptr = this ->CGF .EmitLoadOfScalar (
8094
- this ->CGF .EmitLValue (L.IE ), L.IE ->getExprLoc ());
8160
+ llvm::Value *BasePtr;
8161
+ llvm::Value *Ptr;
8162
+ if (L.ForDeviceAddr) {
8163
+ if (L.IE->isGLValue())
8164
+ Ptr = this->CGF.EmitLValue(L.IE).getPointer(CGF);
8165
+ else
8166
+ Ptr = this->CGF.EmitScalarExpr(L.IE);
8167
+ BasePtr = Ptr;
8168
+ // Entry is RETURN_PARAM. Also, set the placeholder value
8169
+ // MEMBER_OF=FFFF so that the entry is later updated with the
8170
+ // correct value of MEMBER_OF.
8171
+ CurTypes.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_MEMBER_OF);
8172
+ } else {
8173
+ BasePtr = this->CGF.EmitLValue(L.IE).getPointer(CGF);
8174
+ Ptr = this->CGF.EmitLoadOfScalar(this->CGF.EmitLValue(L.IE),
8175
+ L.IE->getExprLoc());
8176
+ // Entry is PTR_AND_OBJ and RETURN_PARAM. Also, set the placeholder
8177
+ // value MEMBER_OF=FFFF so that the entry is later updated with the
8178
+ // correct value of MEMBER_OF.
8179
+ CurTypes.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_RETURN_PARAM |
8180
+ OMP_MAP_MEMBER_OF);
8181
+ }
8095
8182
CurBasePointers.emplace_back(BasePtr, L.VD);
8096
8183
CurPointers.push_back(Ptr);
8097
8184
CurSizes.push_back(llvm::Constant::getNullValue(this->CGF.Int64Ty));
8098
- // Entry is PTR_AND_OBJ and RETURN_PARAM. Also, set the placeholder
8099
- // value MEMBER_OF=FFFF so that the entry is later updated with the
8100
- // correct value of MEMBER_OF.
8101
- CurTypes.push_back (OMP_MAP_PTR_AND_OBJ | OMP_MAP_RETURN_PARAM |
8102
- OMP_MAP_MEMBER_OF);
8103
8185
}
8104
8186
}
8105
8187
@@ -8168,10 +8250,10 @@ class MappableExprsHandler {
8168
8250
for (const MapInfo &L : M.second) {
8169
8251
assert(!L.Components.empty() &&
8170
8252
"Not expecting declaration with no component lists.");
8171
- generateInfoForComponentList (L. MapType , L. MapModifiers , L. Components ,
8172
- CurBasePointers, CurPointers, CurSizes ,
8173
- CurTypes, PartialStruct,
8174
- IsFirstComponentList, L.IsImplicit );
8253
+ generateInfoForComponentList(
8254
+ L.MapType, L.MapModifiers, L.Components, CurBasePointers ,
8255
+ CurPointers, CurSizes, CurTypes, PartialStruct,
8256
+ IsFirstComponentList, L.IsImplicit, L.ForDeviceAddr );
8175
8257
IsFirstComponentList = false;
8176
8258
}
8177
8259
@@ -8437,10 +8519,10 @@ class MappableExprsHandler {
8437
8519
ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
8438
8520
OverlappedComponents = Pair.getSecond();
8439
8521
bool IsFirstComponentList = true;
8440
- generateInfoForComponentList (MapType, MapModifiers, Components,
8441
- BasePointers, Pointers, Sizes, Types ,
8442
- PartialStruct, IsFirstComponentList,
8443
- IsImplicit , OverlappedComponents);
8522
+ generateInfoForComponentList(
8523
+ MapType, MapModifiers, Components, BasePointers, Pointers, Sizes,
8524
+ Types, PartialStruct, IsFirstComponentList, IsImplicit ,
8525
+ /*ForDeviceAddr=*/false , OverlappedComponents);
8444
8526
}
8445
8527
// Go through other elements without overlapped elements.
8446
8528
bool IsFirstComponentList = OverlappedData.empty();
0 commit comments