[flang-commits] [flang] [Flang][OpenMP] Stop emitting implicit mappers for allocatable derived types (and arrays of them) unconditionally (PR #216184)

via flang-commits flang-commits at lists.llvm.org
Wed Aug 19 22:15:19 PDT 2026


https://github.com/agozillon updated https://github.com/llvm/llvm-project/pull/216184

>From 9020762a990e10bf29f4c4647026f3dcab84949f Mon Sep 17 00:00:00 2001
From: agozillon <Andrew.Gozillon at amd.com>
Date: Thu, 13 Aug 2026 15:59:42 -0500
Subject: [PATCH 1/2] [Flang][OpenMP] Stop emitting implicit mappers for
 allocatable dervied types (and arrays of them) unconditionally

We should not be emitting these implicit mappers at the top level if the contents of the derived type do not
require mapping of allocatables. If we do this, we negatively impact performance with unneccessary maps, in
certain cases (array of structs) this can be quite significant.
---
 flang/lib/Lower/OpenMP/Utils.cpp              |  1 -
 ...xplicit-map-flat-allocatable-no-mapper.f90 | 47 +++++++++++++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)
 create mode 100644 flang/test/Lower/OpenMP/explicit-map-flat-allocatable-no-mapper.f90

diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index 515a626c8f209..0b4df19fd8974 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -1235,7 +1235,6 @@ resolveMapperId(Fortran::lower::AbstractConverter &converter,
           (mapTypeBits & mlir::omp::ClauseMapFlags::implicit) ==
           mlir::omp::ClauseMapFlags::implicit;
       bool needsDefaultMapper =
-          isAllocOrPointer ||
           requiresImplicitDefaultDeclareMapper(*objectTypeSpec);
       // For implicit captures, avoid synthesizing default mappers for
       // pointer entities (which can over-map pointer payloads) and for
diff --git a/flang/test/Lower/OpenMP/explicit-map-flat-allocatable-no-mapper.f90 b/flang/test/Lower/OpenMP/explicit-map-flat-allocatable-no-mapper.f90
new file mode 100644
index 0000000000000..e3031323a428e
--- /dev/null
+++ b/flang/test/Lower/OpenMP/explicit-map-flat-allocatable-no-mapper.f90
@@ -0,0 +1,47 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s --check-prefix=NO-FLAT
+
+! On an explicit map clause, an allocatable array of a derived type whose
+! components are all scalars/fixed-size arrays (a "flat" record needing no
+! deep copy) must NOT get an implicit default mapper synthesized. A derived
+! type that has an allocatable component still requires a mapper, and one
+! must still be generated after the fix.
+
+module types_mod
+  type flat_ty
+    integer :: i
+    real    :: r(3)
+  end type flat_ty
+
+  type deep_ty
+    integer              :: i
+    real, allocatable    :: a(:)
+  end type deep_ty
+end module types_mod
+
+subroutine map_flat()
+  use types_mod
+  type(flat_ty), allocatable :: arr(:)
+  allocate(arr(100))
+  !$omp target map(tofrom: arr)
+    arr(1)%i = arr(1)%i + 1
+  !$omp end target
+end subroutine map_flat
+
+subroutine map_deep()
+  use types_mod
+  type(deep_ty), allocatable :: arr(:)
+  allocate(arr(100))
+  !$omp target map(tofrom: arr)
+    arr(1)%i = arr(1)%i + 1
+  !$omp end target
+end subroutine map_deep
+
+! Verify no flat_ty mapper is generated anywhere in the program.
+! NO-FLAT-NOT: omp.declare_mapper @{{.*}}flat_ty{{.*}}
+! NO-FLAT-NOT: mapper(@{{.*}}flat_ty{{.*}})
+
+! Verify we do at least emit and attach the deep_ty mapper.
+! CHECK: omp.declare_mapper @{{.*}}deep_ty{{.*}}
+! CHECK-LABEL: func.func @_QPmap_deep
+! CHECK: omp.map.info {{.*}}mapper(@{{.*}}deep_ty{{.*}})

>From 0327328ae80d86c8fadf6df4be0d67ee5e48c7f4 Mon Sep 17 00:00:00 2001
From: agozillon <Andrew.Gozillon at amd.com>
Date: Wed, 19 Aug 2026 15:19:49 -0500
Subject: [PATCH 2/2] keep status quo for using mappers for iso c types

---
 flang/lib/Lower/OpenMP/Utils.cpp              | 11 +++--
 .../OpenMP/default-mapper-iso-c-nested.f90    | 47 +++++++++++++++++++
 2 files changed, 53 insertions(+), 5 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/default-mapper-iso-c-nested.f90

diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index 0b4df19fd8974..4e7cf5ca34cc3 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -76,15 +76,16 @@ namespace lower {
 namespace omp {
 bool requiresImplicitDefaultDeclareMapper(
     const semantics::DerivedTypeSpec &typeSpec) {
-  // ISO C interoperable types (e.g., c_ptr, c_funptr) must always have implicit
-  // default mappers available so that OpenMP offloading can correctly map them.
-  if (semantics::IsIsoCType(&typeSpec))
-    return true;
-
   llvm::SmallPtrSet<const semantics::DerivedTypeSpec *, 8> visited;
 
   std::function<bool(const semantics::DerivedTypeSpec &)> requiresMapper =
       [&](const semantics::DerivedTypeSpec &spec) -> bool {
+    // ISO C interoperable types (e.g., c_ptr, c_funptr) must always have
+    // implicit default mappers available so that OpenMP offloading can
+    // correctly map them.
+    if (semantics::IsIsoCType(&spec))
+      return true;
+
     if (!visited.insert(&spec).second)
       return false;
 
diff --git a/flang/test/Lower/OpenMP/default-mapper-iso-c-nested.f90 b/flang/test/Lower/OpenMP/default-mapper-iso-c-nested.f90
new file mode 100644
index 0000000000000..4a181daf42e4a
--- /dev/null
+++ b/flang/test/Lower/OpenMP/default-mapper-iso-c-nested.f90
@@ -0,0 +1,47 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %s -o - | FileCheck %s
+
+! Test that an implicit default declare mapper is synthesized for ISO C
+! interoperable types.
+
+program test_iso_c_nested_mapper
+  use iso_c_binding, only : c_ptr
+  implicit none
+
+  type :: dtype
+    integer     :: id
+    type(c_ptr) :: ptr
+  end type dtype
+
+  type(dtype), allocatable :: arr(:)
+
+  allocate(arr(10))
+
+  !$omp target map(tofrom: arr)
+    arr(1)%id = 1
+  !$omp end target
+end program test_iso_c_nested_mapper
+
+subroutine map_cptr_direct
+  use iso_c_binding, only : c_ptr
+  implicit none
+  type(c_ptr) :: p
+
+  !$omp target map(tofrom: p)
+  !$omp end target
+end subroutine map_cptr_direct
+
+
+! CHECK-LABEL: omp.declare_mapper @_QQM__fortran_builtinsc_ptr_omp_default_mapper
+! CHECK: omp.map.info var_ptr({{.*}}) map_clauses(implicit, tofrom){{.*}}name("")
+! CHECK: omp.map.info var_ptr({{.*}}) map_clauses(implicit){{.*}}members({{.*}}){{.*}}name("") partial_map(true)
+! CHECK: omp.declare_mapper.info map_entries(
+
+! CHECK-LABEL: func.func @_QQmain
+! CHECK: %[[ARR_DATA:.*]] = omp.map.info var_ptr(%{{.*}}){{.*}}map_clauses(tofrom){{.*}}var_ptr_ptr(%{{.*}}){{.*}}name("")
+! CHECK: %[[ARR_DESC:.*]] = omp.map.info var_ptr(%{{.*}}){{.*}}map_clauses(always, to){{.*}}members(%[[ARR_DATA]] : [0] :{{.*}}){{.*}}name("arr")
+! CHECK: %[[ARR_ATTACH:.*]] = omp.map.info var_ptr(%{{.*}}){{.*}}map_clauses(attach, ref_ptr, ref_ptee){{.*}}name("arr")
+! CHECK: omp.target {{.*}}map_entries(%[[ARR_DESC]] -> %{{[^,]*}}, %[[ARR_ATTACH]] -> %{{[^,]*}}, %[[ARR_DATA]] -> %{{[^,]*}} :
+
+! CHECK-LABEL: func.func @_QPmap_cptr_direct
+! CHECK: %[[P_MAP:.*]] = omp.map.info var_ptr(%{{.*}}){{.*}}map_clauses(tofrom){{.*}}mapper(@_QQM__fortran_builtinsc_ptr_omp_default_mapper){{.*}}name("p")
+! CHECK: omp.target {{.*}}map_entries(%[[P_MAP]] -> %{{[^,]*}} :



More information about the flang-commits mailing list