@@ -7080,6 +7080,110 @@ class MappableExprsHandler {
70807080 return ConstLength.getSExtValue() != 1;
70817081 }
70827082
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+
70837187 /// Generate the base pointers, section pointers, sizes, map type bits, and
70847188 /// user-defined mappers (all included in \a CombinedInfo) for the provided
70857189 /// map type, map or motion modifiers, and expression components.
@@ -7570,63 +7674,22 @@ class MappableExprsHandler {
75707674 getMapTypeBits(MapType, MapModifiers, MotionModifiers, IsImplicit,
75717675 /*AddPtrFlag=*/false,
75727676 /*AddIsTargetParamFlag=*/false, IsNonContiguous);
7573- llvm::Value *Size = nullptr;
7677+ CopyOverlappedEntryGaps CopyGaps(CGF, CombinedInfo, Flags, MapDecl,
7678+ MapExpr, BP, LB, IsNonContiguous,
7679+ DimSize);
75747680 // Do bitcopy of all non-overlapped structure elements.
75757681 for (OMPClauseMappableExprCommon::MappableExprComponentListRef
75767682 Component : OverlappedElements) {
7577- Address ComponentLB = Address::invalid();
75787683 for (const OMPClauseMappableExprCommon::MappableComponent &MC :
75797684 Component) {
75807685 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);
75937688 }
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;
75997689 }
76007690 }
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);
76147691 }
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);
76307693 break;
76317694 }
76327695 llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
0 commit comments