@@ -7080,6 +7080,110 @@ class MappableExprsHandler {
7080
7080
return ConstLength.getSExtValue() != 1;
7081
7081
}
7082
7082
7083
+ /// A helper class to copy structures with overlapped elements, i.e. those
7084
+ /// which have mappings of both "s" and "s.mem". Consecutive elements that
7085
+ /// are not explicitly copied have mapping nodes synthesized for them,
7086
+ /// taking care to avoid generating zero-sized copies.
7087
+ class CopyOverlappedEntryGaps {
7088
+ CodeGenFunction &CGF;
7089
+ MapCombinedInfoTy &CombinedInfo;
7090
+ OpenMPOffloadMappingFlags Flags = OpenMPOffloadMappingFlags::OMP_MAP_NONE;
7091
+ const ValueDecl *MapDecl = nullptr;
7092
+ const Expr *MapExpr = nullptr;
7093
+ Address BP = Address::invalid();
7094
+ bool IsNonContiguous = false;
7095
+ uint64_t DimSize = 0;
7096
+ // These elements track the position as the struct is iterated over
7097
+ // (in order of increasing element address).
7098
+ const RecordDecl *LastParent = nullptr;
7099
+ uint64_t Cursor = 0;
7100
+ unsigned LastIndex = -1u;
7101
+ Address LB = Address::invalid();
7102
+
7103
+ public:
7104
+ CopyOverlappedEntryGaps(CodeGenFunction &CGF,
7105
+ MapCombinedInfoTy &CombinedInfo,
7106
+ OpenMPOffloadMappingFlags Flags,
7107
+ const ValueDecl *MapDecl, const Expr *MapExpr,
7108
+ Address BP, Address LB, bool IsNonContiguous,
7109
+ uint64_t DimSize)
7110
+ : CGF(CGF), CombinedInfo(CombinedInfo), Flags(Flags), MapDecl(MapDecl),
7111
+ MapExpr(MapExpr), BP(BP), LB(LB), IsNonContiguous(IsNonContiguous),
7112
+ DimSize(DimSize) {}
7113
+
7114
+ void processField(
7115
+ const OMPClauseMappableExprCommon::MappableComponent &MC,
7116
+ const FieldDecl *FD,
7117
+ llvm::function_ref<LValue(CodeGenFunction &, const MemberExpr *)>
7118
+ EmitMemberExprBase) {
7119
+ const RecordDecl *RD = FD->getParent();
7120
+ const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
7121
+ uint64_t FieldOffset = RL.getFieldOffset(FD->getFieldIndex());
7122
+ uint64_t FieldSize =
7123
+ CGF.getContext().getTypeSize(FD->getType().getCanonicalType());
7124
+ Address ComponentLB = Address::invalid();
7125
+
7126
+ if (FD->getType()->isLValueReferenceType()) {
7127
+ const auto *ME = cast<MemberExpr>(MC.getAssociatedExpression());
7128
+ LValue BaseLVal = EmitMemberExprBase(CGF, ME);
7129
+ ComponentLB =
7130
+ CGF.EmitLValueForFieldInitialization(BaseLVal, FD).getAddress();
7131
+ } else {
7132
+ ComponentLB =
7133
+ CGF.EmitOMPSharedLValue(MC.getAssociatedExpression()).getAddress();
7134
+ }
7135
+
7136
+ if (!LastParent)
7137
+ LastParent = RD;
7138
+ if (FD->getParent() == LastParent) {
7139
+ if (FD->getFieldIndex() != LastIndex + 1)
7140
+ copyUntilField(FD, ComponentLB);
7141
+ } else {
7142
+ LastParent = FD->getParent();
7143
+ if (((int64_t)FieldOffset - (int64_t)Cursor) > 0)
7144
+ copyUntilField(FD, ComponentLB);
7145
+ }
7146
+ Cursor = FieldOffset + FieldSize;
7147
+ LastIndex = FD->getFieldIndex();
7148
+ LB = CGF.Builder.CreateConstGEP(ComponentLB, 1);
7149
+ }
7150
+
7151
+ void copyUntilField(const FieldDecl *FD, Address ComponentLB) {
7152
+ llvm::Value *ComponentLBPtr = ComponentLB.emitRawPointer(CGF);
7153
+ llvm::Value *LBPtr = LB.emitRawPointer(CGF);
7154
+ llvm::Value *Size =
7155
+ CGF.Builder.CreatePtrDiff(CGF.Int8Ty, ComponentLBPtr, LBPtr);
7156
+ copySizedChunk(LBPtr, Size);
7157
+ }
7158
+
7159
+ void copyUntilEnd(Address HB) {
7160
+ if (LastParent) {
7161
+ const ASTRecordLayout &RL =
7162
+ CGF.getContext().getASTRecordLayout(LastParent);
7163
+ if ((uint64_t)CGF.getContext().toBits(RL.getSize()) <= Cursor)
7164
+ return;
7165
+ }
7166
+ llvm::Value *LBPtr = LB.emitRawPointer(CGF);
7167
+ llvm::Value *Size = CGF.Builder.CreatePtrDiff(
7168
+ CGF.Int8Ty, CGF.Builder.CreateConstGEP(HB, 1).emitRawPointer(CGF),
7169
+ LBPtr);
7170
+ copySizedChunk(LBPtr, Size);
7171
+ }
7172
+
7173
+ void copySizedChunk(llvm::Value *Base, llvm::Value *Size) {
7174
+ CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
7175
+ CombinedInfo.BasePointers.push_back(BP.emitRawPointer(CGF));
7176
+ CombinedInfo.DevicePtrDecls.push_back(nullptr);
7177
+ CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None);
7178
+ CombinedInfo.Pointers.push_back(Base);
7179
+ CombinedInfo.Sizes.push_back(
7180
+ CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true));
7181
+ CombinedInfo.Types.push_back(Flags);
7182
+ CombinedInfo.Mappers.push_back(nullptr);
7183
+ CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize : 1);
7184
+ }
7185
+ };
7186
+
7083
7187
/// Generate the base pointers, section pointers, sizes, map type bits, and
7084
7188
/// user-defined mappers (all included in \a CombinedInfo) for the provided
7085
7189
/// map type, map or motion modifiers, and expression components.
@@ -7570,63 +7674,22 @@ class MappableExprsHandler {
7570
7674
getMapTypeBits(MapType, MapModifiers, MotionModifiers, IsImplicit,
7571
7675
/*AddPtrFlag=*/false,
7572
7676
/*AddIsTargetParamFlag=*/false, IsNonContiguous);
7573
- llvm::Value *Size = nullptr;
7677
+ CopyOverlappedEntryGaps CopyGaps(CGF, CombinedInfo, Flags, MapDecl,
7678
+ MapExpr, BP, LB, IsNonContiguous,
7679
+ DimSize);
7574
7680
// Do bitcopy of all non-overlapped structure elements.
7575
7681
for (OMPClauseMappableExprCommon::MappableExprComponentListRef
7576
7682
Component : OverlappedElements) {
7577
- Address ComponentLB = Address::invalid();
7578
7683
for (const OMPClauseMappableExprCommon::MappableComponent &MC :
7579
7684
Component) {
7580
7685
if (const ValueDecl *VD = MC.getAssociatedDeclaration()) {
7581
- const auto *FD = dyn_cast<FieldDecl>(VD);
7582
- if (FD && FD->getType()->isLValueReferenceType()) {
7583
- const auto *ME =
7584
- cast<MemberExpr>(MC.getAssociatedExpression());
7585
- LValue BaseLVal = EmitMemberExprBase(CGF, ME);
7586
- ComponentLB =
7587
- CGF.EmitLValueForFieldInitialization(BaseLVal, FD)
7588
- .getAddress();
7589
- } else {
7590
- ComponentLB =
7591
- CGF.EmitOMPSharedLValue(MC.getAssociatedExpression())
7592
- .getAddress();
7686
+ if (const auto *FD = dyn_cast<FieldDecl>(VD)) {
7687
+ CopyGaps.processField(MC, FD, EmitMemberExprBase);
7593
7688
}
7594
- llvm::Value *ComponentLBPtr = ComponentLB.emitRawPointer(CGF);
7595
- llvm::Value *LBPtr = LB.emitRawPointer(CGF);
7596
- Size = CGF.Builder.CreatePtrDiff(CGF.Int8Ty, ComponentLBPtr,
7597
- LBPtr);
7598
- break;
7599
7689
}
7600
7690
}
7601
- assert(Size && "Failed to determine structure size");
7602
- CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
7603
- CombinedInfo.BasePointers.push_back(BP.emitRawPointer(CGF));
7604
- CombinedInfo.DevicePtrDecls.push_back(nullptr);
7605
- CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None);
7606
- CombinedInfo.Pointers.push_back(LB.emitRawPointer(CGF));
7607
- CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
7608
- Size, CGF.Int64Ty, /*isSigned=*/true));
7609
- CombinedInfo.Types.push_back(Flags);
7610
- CombinedInfo.Mappers.push_back(nullptr);
7611
- CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize
7612
- : 1);
7613
- LB = CGF.Builder.CreateConstGEP(ComponentLB, 1);
7614
7691
}
7615
- CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
7616
- CombinedInfo.BasePointers.push_back(BP.emitRawPointer(CGF));
7617
- CombinedInfo.DevicePtrDecls.push_back(nullptr);
7618
- CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None);
7619
- CombinedInfo.Pointers.push_back(LB.emitRawPointer(CGF));
7620
- llvm::Value *LBPtr = LB.emitRawPointer(CGF);
7621
- Size = CGF.Builder.CreatePtrDiff(
7622
- CGF.Int8Ty, CGF.Builder.CreateConstGEP(HB, 1).emitRawPointer(CGF),
7623
- LBPtr);
7624
- CombinedInfo.Sizes.push_back(
7625
- CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true));
7626
- CombinedInfo.Types.push_back(Flags);
7627
- CombinedInfo.Mappers.push_back(nullptr);
7628
- CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize
7629
- : 1);
7692
+ CopyGaps.copyUntilEnd(HB);
7630
7693
break;
7631
7694
}
7632
7695
llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
0 commit comments