[flang-commits] [flang] cb0fb6c - [Flang][OpenMP] Stop emitting implicit mappers for allocatable derived types (and arrays of them) unconditionally (#216184)
via flang-commits
flang-commits at lists.llvm.org
Thu Aug 20 11:07:39 PDT 2026
Author: agozillon
Date: 2026-08-20T20:07:34+02:00
New Revision: cb0fb6c8fc2333cd336d3e39f1727f6ffc40c1e3
URL: https://github.com/llvm/llvm-project/commit/cb0fb6c8fc2333cd336d3e39f1727f6ffc40c1e3
DIFF: https://github.com/llvm/llvm-project/commit/cb0fb6c8fc2333cd336d3e39f1727f6ffc40c1e3.diff
LOG: [Flang][OpenMP] Stop emitting implicit mappers for allocatable derived types (and arrays of them) unconditionally (#216184)
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.
Added:
flang/test/Lower/OpenMP/default-mapper-iso-c-nested.f90
flang/test/Lower/OpenMP/explicit-map-flat-allocatable-no-mapper.f90
Modified:
flang/lib/Lower/OpenMP/Utils.cpp
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index 515a626c8f209..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;
@@ -1235,7 +1236,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/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]] -> %{{[^,]*}} :
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{{.*}})
More information about the flang-commits
mailing list