[flang-commits] [flang] [Flang][OpenMP] Enable implicit mapping of allocatables inside derived types for enter/exit/update (PR #224145)

via flang-commits flang-commits at lists.llvm.org
Wed Sep 16 14:48:10 PDT 2026


https://github.com/agozillon created https://github.com/llvm/llvm-project/pull/224145

Currently we only allow mapper emission for implicit maps and explicit target region maps, this PR extends it to support enter/exit/update by removing the inhibitor we had on it, now that we can handle this type of mapping.

>From c977411ec80aba502adcc9d18f4b86d02dcf06bd Mon Sep 17 00:00:00 2001
From: agozillon <Andrew.Gozillon at amd.com>
Date: Wed, 16 Sep 2026 16:36:51 -0500
Subject: [PATCH] [Flang][OpenMP] Enable implicit mapping of allocatables
 inside derived types for enter/exit/update

Currently we only allow mapper emission for implicit maps and explicit target region maps, this PR extends it
to support enter/exit/update by removing the inhibitor we had on it, now that we can handle this type of mapping.
---
 flang/lib/Lower/OpenMP/ClauseProcessor.cpp    |  6 ++--
 flang/lib/Lower/OpenMP/ClauseProcessor.h      |  4 +--
 flang/lib/Lower/OpenMP/Utils.cpp              | 18 +++--------
 flang/lib/Lower/OpenMP/Utils.h                |  7 ++--
 ...icit-default-mapper-target-data-motion.f90 | 32 +++++++++++++++++++
 5 files changed, 44 insertions(+), 23 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/implicit-default-mapper-target-data-motion.f90

diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index b871f630d3dae..0efa11e271aa3 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1882,7 +1882,7 @@ void ClauseProcessor::processMapObjects(
     std::map<Object, OmpMapParentAndMemberData> &parentMemberIndices,
     llvm::SmallVectorImpl<mlir::Value> &mapVars,
     llvm::SmallVectorImpl<Object> &mapObjects, llvm::StringRef mapperIdNameRef,
-    bool isMotionModifier, llvm::omp::Directive directive) const {
+    bool isMotionModifier) const {
   fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
 
   for (const omp::Object &object : objects) {
@@ -1918,7 +1918,7 @@ void ClauseProcessor::processMapObjects(
 
     mlir::FlatSymbolRefAttr mapperId =
         resolveMapperId(converter, clauseLocation, object, mapperIdNameRef,
-                        mapTypeBits, directive, parentObj.has_value());
+                        mapTypeBits, parentObj.has_value());
 
     // Explicit map captures are captured ByRef by default,
     // optimisation passes may alter this to ByCopy or other capture
@@ -2070,7 +2070,7 @@ bool ClauseProcessor::processMap(
     processMapObjects(stmtCtx, clauseLocation,
                       std::get<omp::ObjectList>(clause.t), mapTypeBits,
                       parentMemberIndices, result.mapVars, *ptrMapObjects,
-                      mapperIdName, /*isMotionModifier=*/false, directive);
+                      mapperIdName, /*isMotionModifier=*/false);
   };
 
   bool clauseFound = findRepeatableClause<omp::clause::Map>(process);
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index 6b0e0cf606f48..1d4d93315748d 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -223,8 +223,8 @@ class ClauseProcessor {
       std::map<Object, OmpMapParentAndMemberData> &parentMemberIndices,
       llvm::SmallVectorImpl<mlir::Value> &mapVars,
       llvm::SmallVectorImpl<Object> &mapObjects,
-      llvm::StringRef mapperIdNameRef = "", bool isMotionModifier = false,
-      llvm::omp::Directive directive = llvm::omp::OMPD_unknown) const;
+      llvm::StringRef mapperIdNameRef = "",
+      bool isMotionModifier = false) const;
 
   lower::AbstractConverter &converter;
   semantics::SemanticsContext &semaCtx;
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index b52c03ff63fed..8a01608b865d6 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -1228,8 +1228,7 @@ mlir::FlatSymbolRefAttr
 resolveMapperId(Fortran::lower::AbstractConverter &converter,
                 mlir::Location loc, const omp::Object &object,
                 llvm::StringRef mapperIdNameRef,
-                mlir::omp::ClauseMapFlags mapTypeBits,
-                llvm::omp::Directive directive, bool hasParentObj) {
+                mlir::omp::ClauseMapFlags mapTypeBits, bool hasParentObj) {
   const semantics::DerivedTypeSpec *objectTypeSpec =
       getSymbolDerivedType(*object.sym());
   if (!objectTypeSpec)
@@ -1250,19 +1249,12 @@ resolveMapperId(Fortran::lower::AbstractConverter &converter,
 
   if (mapperIdName == "__implicit_mapper") {
     mapperIdName = getDefaultMapperID(converter, firOpBuilder, objectTypeSpec);
-    // Currently we do not apply implicit compiler generated delcare mappers
-    // to enter, exit or update directives. However, we will syntheize one
-    // below if we're not a target enter/exit/update and no user defined
-    // implicit declare mapper has been defined and we meet the other
-    // conditions
-    // TODO/FIXME: Loosen this restriction to comply with the OpenMP
-    // specification.
+    // Synthesize an implicit compiler generated declare mapper if no user
+    // defined implicit declare mapper has been defined and the mapped object
+    // meets the other conditions below.
     auto *userDefinedDefault =
         converter.getModuleOp().lookupSymbol(mapperIdName);
-    if (!userDefinedDefault && !hasParentObj &&
-        (directive != llvm::omp::Directive::OMPD_target_enter_data &&
-         directive != llvm::omp::Directive::OMPD_target_exit_data &&
-         directive != llvm::omp::Directive::OMPD_target_update)) {
+    if (!userDefinedDefault && !hasParentObj) {
       bool isAllocOrPointer =
           semantics::IsAllocatableOrObjectPointer(object.sym());
       bool isPointer = semantics::IsPointer(*object.sym());
diff --git a/flang/lib/Lower/OpenMP/Utils.h b/flang/lib/Lower/OpenMP/Utils.h
index 7fde1825b006a..e5bbff35200fd 100644
--- a/flang/lib/Lower/OpenMP/Utils.h
+++ b/flang/lib/Lower/OpenMP/Utils.h
@@ -237,8 +237,7 @@ mlir::Value genIteratorCoordinate(Fortran::lower::AbstractConverter &converter,
 ///
 /// The default mapper path first looks for a user-defined mapper. If none
 /// exists, it may synthesize a compiler-generated mapper, except for mapped
-/// members whose parent object is also mapped and for target enter data,
-/// target exit data, and target update directives.
+/// members whose parent object is also mapped.
 ///
 /// \param converter The converter used to query and generate mapper symbols.
 /// \param loc The location to use when generating an implicit mapper.
@@ -247,7 +246,6 @@ mlir::Value genIteratorCoordinate(Fortran::lower::AbstractConverter &converter,
 ///        empty name.
 /// \param mapTypeBits The map flags used when deciding whether an implicit
 ///        mapper should be generated.
-/// \param directive The enclosing OpenMP directive.
 /// \param hasParentObj True if a mapped parent object already owns this object.
 /// \return A symbol reference to the resolved mapper, or a null attribute when
 ///         no mapper applies.
@@ -255,8 +253,7 @@ mlir::FlatSymbolRefAttr
 resolveMapperId(Fortran::lower::AbstractConverter &converter,
                 mlir::Location loc, const omp::Object &object,
                 llvm::StringRef mapperIdName,
-                mlir::omp::ClauseMapFlags mapTypeBits,
-                llvm::omp::Directive directive, bool hasParentObj);
+                mlir::omp::ClauseMapFlags mapTypeBits, bool hasParentObj);
 
 std::optional<llvm::SmallVector<mlir::Value>> getIteratorElementIndices(
     Fortran::lower::AbstractConverter &converter, const omp::Object &object,
diff --git a/flang/test/Lower/OpenMP/implicit-default-mapper-target-data-motion.f90 b/flang/test/Lower/OpenMP/implicit-default-mapper-target-data-motion.f90
new file mode 100644
index 0000000000000..d7bb6118371aa
--- /dev/null
+++ b/flang/test/Lower/OpenMP/implicit-default-mapper-target-data-motion.f90
@@ -0,0 +1,32 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %s -o - | FileCheck %s
+
+module implicit_default_mapper_target_data_motion
+  type :: t
+    integer, allocatable :: a(:)
+  end type
+contains
+  subroutine s(x)
+    type(t) :: x
+
+    !$omp target enter data map(to: x)
+    !$omp target update to(x)
+    !$omp target update from(x)
+    !$omp target exit data map(from: x)
+  end subroutine
+end module
+
+! CHECK: omp.declare_mapper @[[MAPPER:.*_omp_default_mapper]] :
+! CHECK: omp.map.info {{.*}} map_clauses(implicit, tofrom, ref_ptee) {{.*}}name("")
+! CHECK: omp.map.info {{.*}} map_clauses(attach, ref_ptee) {{.*}}name("")
+! CHECK: omp.map.info {{.*}} map_clauses(implicit, tofrom) capture(ByRef) members(%{{.*}} : [0]
+! CHECK: omp.declare_mapper.info map_entries(
+
+! CHECK-LABEL: func.func @_QMimplicit_default_mapper_target_data_motionPs(
+! CHECK: %[[ENTER_MAP:.*]] = omp.map.info {{.*}} map_clauses(to) capture(ByRef) mapper(@[[MAPPER]]) name("x")
+! CHECK-NEXT: omp.target_enter_data map_entries(%[[ENTER_MAP]]
+! CHECK: %[[UPDATE_TO_MAP:.*]] = omp.map.info {{.*}} map_clauses(to) capture(ByRef) mapper(@[[MAPPER]]) name("x")
+! CHECK-NEXT: omp.target_update map_entries(%[[UPDATE_TO_MAP]]
+! CHECK: %[[UPDATE_FROM_MAP:.*]] = omp.map.info {{.*}} map_clauses(from) capture(ByRef) mapper(@[[MAPPER]]) name("x")
+! CHECK-NEXT: omp.target_update map_entries(%[[UPDATE_FROM_MAP]]
+! CHECK: %[[EXIT_MAP:.*]] = omp.map.info {{.*}} map_clauses(from) capture(ByRef) mapper(@[[MAPPER]]) name("x")
+! CHECK-NEXT: omp.target_exit_data map_entries(%[[EXIT_MAP]]



More information about the flang-commits mailing list