@@ -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;
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), MapDecl(_MapDecl),
7111
+ MapExpr(_MapExpr), BP(_BP), LB(_LB),
7112
+ IsNonContiguous(_IsNonContiguous), DimSize(_DimSize) { }
7113
+
7114
+ void ProcessField(const OMPClauseMappableExprCommon::MappableComponent &MC,
7115
+ const FieldDecl *FD,
7116
+ llvm::function_ref<LValue(CodeGenFunction &, const MemberExpr *)> EmitMemberExprBase) {
7117
+ const RecordDecl *RD = FD->getParent();
7118
+ const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
7119
+ uint64_t FieldOffset = RL.getFieldOffset(FD->getFieldIndex());
7120
+ uint64_t FieldSize = CGF.getContext().getTypeSize(FD->getType().getCanonicalType());
7121
+ Address ComponentLB = Address::invalid();
7122
+
7123
+ if (FD->getType()->isLValueReferenceType()) {
7124
+ const auto *ME =
7125
+ cast<MemberExpr>(MC.getAssociatedExpression());
7126
+ LValue BaseLVal = EmitMemberExprBase(CGF, ME);
7127
+ ComponentLB =
7128
+ CGF.EmitLValueForFieldInitialization(BaseLVal, FD)
7129
+ .getAddress();
7130
+ } else {
7131
+ ComponentLB =
7132
+ CGF.EmitOMPSharedLValue(MC.getAssociatedExpression())
7133
+ .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 = CGF.Builder.CreatePtrDiff(CGF.Int8Ty, ComponentLBPtr,
7156
+ LBPtr);
7157
+ CopySizedChunk(LBPtr, Size);
7158
+ }
7159
+
7160
+ void CopyUntilEnd(Address HB) {
7161
+ if (LastParent) {
7162
+ const ASTRecordLayout &RL = 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(CGF.Builder.CreateIntCast(
7180
+ 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