[clang] [OpenMP] Don't emit redundant zero-sized mapping nodes for overlapped structs (PR #148947)

Julian Brown via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 16 04:55:58 PDT 2025


================
@@ -7080,6 +7080,111 @@ class MappableExprsHandler {
     return ConstLength.getSExtValue() != 1;
   }
 
+  /// A helper class to copy structures with overlapped elements, i.e. those
+  /// which have mappings of both "s" and "s.mem".  Consecutive elements that
+  /// are not explicitly copied have mapping nodes synthesized for them,
+  /// taking care to avoid generating zero-sized copies.
+  class CopyOverlappedEntryGaps {
+    CodeGenFunction &CGF;
+    MapCombinedInfoTy &CombinedInfo;
+    OpenMPOffloadMappingFlags Flags;
+    const ValueDecl *MapDecl;
+    const Expr *MapExpr;
+    Address BP;
+    bool IsNonContiguous;
+    uint64_t DimSize;
+    // These elements track the position as the struct is iterated over
+    // (in order of increasing element address).
+    const RecordDecl *LastParent = nullptr;
+    uint64_t Cursor = 0;
+    unsigned LastIndex = -1u;
+    Address LB;
+
+  public:
+    CopyOverlappedEntryGaps(CodeGenFunction &_CGF,
+                            MapCombinedInfoTy &_CombinedInfo,
+                            OpenMPOffloadMappingFlags _Flags,
+                            const ValueDecl *_MapDecl, const Expr *_MapExpr,
+                            Address _BP, Address _LB, bool _IsNonContiguous,
+                            uint64_t _DimSize)
+        : CGF(_CGF), CombinedInfo(_CombinedInfo), Flags(_Flags),
+          MapDecl(_MapDecl), MapExpr(_MapExpr), BP(_BP), LB(_LB),
+          IsNonContiguous(_IsNonContiguous), DimSize(_DimSize) {}
+
+    void ProcessField(
+        const OMPClauseMappableExprCommon::MappableComponent &MC,
+        const FieldDecl *FD,
+        llvm::function_ref<LValue(CodeGenFunction &, const MemberExpr *)>
+            EmitMemberExprBase) {
+      const RecordDecl *RD = FD->getParent();
+      const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
+      uint64_t FieldOffset = RL.getFieldOffset(FD->getFieldIndex());
+      uint64_t FieldSize =
+          CGF.getContext().getTypeSize(FD->getType().getCanonicalType());
+      Address ComponentLB = Address::invalid();
+
+      if (FD->getType()->isLValueReferenceType()) {
+        const auto *ME = cast<MemberExpr>(MC.getAssociatedExpression());
+        LValue BaseLVal = EmitMemberExprBase(CGF, ME);
+        ComponentLB =
+            CGF.EmitLValueForFieldInitialization(BaseLVal, FD).getAddress();
+      } else {
+        ComponentLB =
+            CGF.EmitOMPSharedLValue(MC.getAssociatedExpression()).getAddress();
+      }
+
+      if (LastParent == nullptr) {
+        LastParent = RD;
+      }
----------------
jtb20 wrote:

Changed, thanks.

https://github.com/llvm/llvm-project/pull/148947


More information about the cfe-commits mailing list