@@ -7080,6 +7080,111 @@ 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;
7091
+ const ValueDecl *MapDecl;
7092
+ const Expr *MapExpr;
7093
+ Address BP;
7094
+ bool IsNonContiguous;
7095
+ uint64_t DimSize;
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;
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),
7111
+ MapDecl(_MapDecl), MapExpr(_MapExpr), BP(_BP), LB(_LB),
7112
+ IsNonContiguous(_IsNonContiguous), 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 == nullptr) {
7137
+ LastParent = RD;
7138
+ }
7139
+ if (FD->getParent() == LastParent) {
7140
+ if (FD->getFieldIndex() != LastIndex + 1)
7141
+ CopyUntilField(FD, ComponentLB);
7142
+ } else {
7143
+ LastParent = FD->getParent();
7144
+ if (((int64_t)FieldOffset - (int64_t)Cursor) > 0)
7145
+ CopyUntilField(FD, ComponentLB);
7146
+ }
7147
+ Cursor = FieldOffset + FieldSize;
7148
+ LastIndex = FD->getFieldIndex();
7149
+ LB = CGF.Builder.CreateConstGEP(ComponentLB, 1);
7150
+ }
7151
+
7152
+ void CopyUntilField(const FieldDecl *FD, Address ComponentLB) {
7153
+ llvm::Value *ComponentLBPtr = ComponentLB.emitRawPointer(CGF);
7154
+ llvm::Value *LBPtr = LB.emitRawPointer(CGF);
7155
+ llvm::Value *Size =
7156
+ CGF.Builder.CreatePtrDiff(CGF.Int8Ty, ComponentLBPtr, LBPtr);
7157
+ CopySizedChunk(LBPtr, Size);
7158
+ }
7159
+
7160
+ void CopyUntilEnd(Address HB) {
7161
+ if (LastParent) {
7162
+ const ASTRecordLayout &RL =
7163
+ CGF.getContext().getASTRecordLayout(LastParent);
7164
+ if ((uint64_t)CGF.getContext().toBits(RL.getSize()) <= Cursor)
7165
+ return;
7166
+ }
7167
+ llvm::Value *LBPtr = LB.emitRawPointer(CGF);
7168
+ llvm::Value *Size = CGF.Builder.CreatePtrDiff(
7169
+ CGF.Int8Ty, CGF.Builder.CreateConstGEP(HB, 1).emitRawPointer(CGF),
7170
+ LBPtr);
7171
+ CopySizedChunk(LBPtr, Size);
7172
+ }
7173
+
7174
+ void CopySizedChunk(llvm::Value *Base, llvm::Value *Size) {
7175
+ CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
7176
+ CombinedInfo.BasePointers.push_back(BP.emitRawPointer(CGF));
7177
+ CombinedInfo.DevicePtrDecls.push_back(nullptr);
7178
+ CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None);
7179
+ CombinedInfo.Pointers.push_back(Base);
7180
+ CombinedInfo.Sizes.push_back(
7181
+ CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true));
7182
+ CombinedInfo.Types.push_back(Flags);
7183
+ CombinedInfo.Mappers.push_back(nullptr);
7184
+ CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize : 1);
7185
+ }
7186
+ };
7187
+
7083
7188
/// Generate the base pointers, section pointers, sizes, map type bits, and
7084
7189
/// user-defined mappers (all included in \a CombinedInfo) for the provided
7085
7190
/// map type, map or motion modifiers, and expression components.
@@ -7570,63 +7675,22 @@ class MappableExprsHandler {
7570
7675
getMapTypeBits(MapType, MapModifiers, MotionModifiers, IsImplicit,
7571
7676
/*AddPtrFlag=*/false,
7572
7677
/*AddIsTargetParamFlag=*/false, IsNonContiguous);
7573
- llvm::Value *Size = nullptr;
7678
+ CopyOverlappedEntryGaps CopyGaps(CGF, CombinedInfo, Flags, MapDecl,
7679
+ MapExpr, BP, LB, IsNonContiguous,
7680
+ DimSize);
7574
7681
// Do bitcopy of all non-overlapped structure elements.
7575
7682
for (OMPClauseMappableExprCommon::MappableExprComponentListRef
7576
7683
Component : OverlappedElements) {
7577
- Address ComponentLB = Address::invalid();
7578
7684
for (const OMPClauseMappableExprCommon::MappableComponent &MC :
7579
7685
Component) {
7580
7686
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();
7687
+ if (const auto *FD = dyn_cast<FieldDecl>(VD)) {
7688
+ CopyGaps.ProcessField(MC, FD, EmitMemberExprBase);
7593
7689
}
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
7690
}
7600
7691
}
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
7692
}
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);
7693
+ CopyGaps.CopyUntilEnd(HB);
7630
7694
break;
7631
7695
}
7632
7696
llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
0 commit comments