[llvm-branch-commits] [flang] [MLIR][OpenMP] Add Lowering support for OpenMP Declare Mapper directive (PR #117046)

Akash Banerjee via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Dec 23 10:45:47 PST 2024


https://github.com/TIFitis updated https://github.com/llvm/llvm-project/pull/117046

>From 472e8c19bce954a67fe9653618c59999f9b7695e Mon Sep 17 00:00:00 2001
From: Akash Banerjee <Akash.Banerjee at amd.com>
Date: Wed, 20 Nov 2024 20:51:02 +0000
Subject: [PATCH 1/5] [MLIR][OpenMP] Add Lowering support for OpenMP Declare
 Mapper directive

This patch adds HLFIR/FIR lowering support for OpenMP Declare Mapper directive.
---
 flang/lib/Lower/OpenMP/OpenMP.cpp             | 35 ++++++++++++++++++-
 .../Optimizer/OpenMP/MapInfoFinalization.cpp  |  3 +-
 .../Lower/OpenMP/Todo/omp-declare-mapper.f90  |  8 ++---
 flang/test/Lower/OpenMP/declare-mapper.f90    | 31 ++++++++++++++++
 4 files changed, 71 insertions(+), 6 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/declare-mapper.f90

diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 4de5ecf187a4cb..16ba5037a919a2 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -40,6 +40,7 @@
 #include "mlir/Transforms/RegionUtils.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Frontend/OpenMP/OMPConstants.h"
+#include <string>
 
 using namespace Fortran::lower::omp;
 using namespace Fortran::common::openmp;
@@ -2612,7 +2613,39 @@ static void
 genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
        semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
        const parser::OpenMPDeclareMapperConstruct &declareMapperConstruct) {
-  TODO(converter.getCurrentLocation(), "OpenMPDeclareMapperConstruct");
+  fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+  lower::StatementContext stmtCtx;
+  const auto &spec =
+      std::get<parser::OmpDeclareMapperSpecifier>(declareMapperConstruct.t);
+  const auto &mapperName{std::get<std::optional<parser::Name>>(spec.t)};
+  const auto &varType{std::get<parser::TypeSpec>(spec.t)};
+  const auto &varName{std::get<parser::Name>(spec.t)};
+  std::stringstream mapperNameStr;
+  if (mapperName.has_value()) {
+    mapperNameStr << mapperName->ToString();
+  } else {
+    mapperNameStr << "default_"
+                  << varType.declTypeSpec->derivedTypeSpec().name().ToString();
+  }
+
+  mlir::OpBuilder::InsertPoint insPt = firOpBuilder.saveInsertionPoint();
+  firOpBuilder.setInsertionPointToStart(converter.getModuleOp().getBody());
+  auto mlirType = converter.genType(varType.declTypeSpec->derivedTypeSpec());
+  auto varVal = firOpBuilder.createTemporaryAlloc(
+      converter.getCurrentLocation(), mlirType, varName.ToString());
+  symTable.addSymbol(*varName.symbol, varVal);
+
+  mlir::omp::DeclareMapperOperands clauseOps;
+  const auto *clauseList{
+      parser::Unwrap<parser::OmpClauseList>(declareMapperConstruct.t)};
+  List<Clause> clauses = makeClauses(*clauseList, semaCtx);
+  ClauseProcessor cp(converter, semaCtx, clauses);
+  cp.processMap(converter.getCurrentLocation(), stmtCtx, clauseOps);
+  auto declMapperOp = firOpBuilder.create<mlir::omp::DeclareMapperOp>(
+      converter.getCurrentLocation(), mapperNameStr.str(), varVal, mlirType,
+      clauseOps.mapVars);
+  converter.getMLIRSymbolTable()->insert(declMapperOp.getOperation());
+  firOpBuilder.restoreInsertionPoint(insPt);
 }
 
 static void
diff --git a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
index ad7b806ae262ae..2991bcd6f242c6 100644
--- a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
@@ -451,7 +451,8 @@ class MapInfoFinalizationPass
     for (auto *user : mapOp->getUsers()) {
       if (llvm::isa<mlir::omp::TargetOp, mlir::omp::TargetDataOp,
                     mlir::omp::TargetUpdateOp, mlir::omp::TargetExitDataOp,
-                    mlir::omp::TargetEnterDataOp>(user))
+                    mlir::omp::TargetEnterDataOp, mlir::omp::DeclareMapperOp>(
+              user))
         return user;
 
       if (auto mapUser = llvm::dyn_cast<mlir::omp::MapInfoOp>(user))
diff --git a/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90 b/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
index 5ae48ff7360482..13a4da5849f8c0 100644
--- a/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
+++ b/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
@@ -10,7 +10,7 @@ subroutine declare_mapper_1
  type my_type
    integer              :: num_vals
    integer, allocatable :: values(:)
- end type 
+ end type
 
  type my_type2
    type (my_type)        :: my_type_var
@@ -21,7 +21,7 @@ subroutine declare_mapper_1
   type (my_type2)        :: t
   real                   :: x, y(nvals)
   !$omp declare mapper (my_type :: var) map (var, var%values (1:var%num_vals))
-!CHECK: not yet implemented: OpenMPDeclareMapperConstruct
+!CHECK: not yet implemented: lowering symbol to HLFIR
 end subroutine declare_mapper_1
 
 
@@ -31,7 +31,7 @@ subroutine declare_mapper_2
  type my_type
    integer              :: num_vals
    integer, allocatable :: values(:)
- end type 
+ end type
 
  type my_type2
    type (my_type)        :: my_type_var
@@ -43,5 +43,5 @@ subroutine declare_mapper_2
   real                   :: x, y(nvals)
   !$omp declare mapper (my_mapper : my_type2 :: v) map (v%arr, x, y(:)) &
   !$omp&                map (alloc : v%temp)
-!CHECK: not yet implemented: OpenMPDeclareMapperConstruct
+!CHECK: not yet implemented: lowering symbol to HLFIR
 end subroutine declare_mapper_2
diff --git a/flang/test/Lower/OpenMP/declare-mapper.f90 b/flang/test/Lower/OpenMP/declare-mapper.f90
new file mode 100644
index 00000000000000..fd018b4fbb0e0f
--- /dev/null
+++ b/flang/test/Lower/OpenMP/declare-mapper.f90
@@ -0,0 +1,31 @@
+! This test checks lowering of OpenMP declare mapper Directive.
+
+! RUN: split-file %s %t
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/declare-mapper-1.f90 -o - | FileCheck %t/declare-mapper-1.f90
+! RUN  %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/declare-mapper-2.f90 -o - | FileCheck %t/declare-mapper-2.f90
+
+!--- declare-mapper-1.f90
+subroutine mapper
+   implicit none
+   type my_type
+      integer, pointer :: my_buffer
+      integer :: my_buffer_size
+   end type
+   !CHECK: %[[MY_VAR:.*]] = fir.alloca ![[VAR_TYPE:.*]] {bindc_name = "my_var"}
+   !CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%[[MY_VAR]] : !fir.ref<![[VAR_TYPE]]>, ![[VAR_TYPE]]) map_clauses(tofrom) capture(ByRef) -> !fir.ref<![[VAR_TYPE]]> {name = "my_var"}
+   !CHECK: omp.declare_mapper @my_mapper : %[[MY_VAR]] : !fir.ref<![[VAR_TYPE]]> : ![[VAR_TYPE]] map_entries(%[[MAP_INFO]] : !fir.ref<![[VAR_TYPE]]>)
+   !$omp DECLARE MAPPER(my_mapper : my_type :: my_var) map(tofrom : my_var)
+end subroutine
+
+!--- declare-mapper-2.f90
+subroutine mapper_default
+   implicit none
+   type my_type
+      integer, pointer :: my_buffer
+      integer :: my_buffer_size
+   end type
+   !CHECK: %[[MY_VAR:.*]] = fir.alloca ![[VAR_TYPE:.*]] {bindc_name = "my_var"}
+   !CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%[[MY_VAR]] : !fir.ref<![[VAR_TYPE]]>, ![[VAR_TYPE]]) map_clauses(tofrom) capture(ByRef) -> !fir.ref<![[VAR_TYPE]]> {name = "my_var"}
+   !CHECK: omp.declare_mapper @default_my_type : %[[MY_VAR]] : !fir.ref<![[VAR_TYPE]]> : ![[VAR_TYPE]] map_entries(%[[MAP_INFO]] : !fir.ref<![[VAR_TYPE]]>)
+   !$omp DECLARE MAPPER(my_type :: my_var) map(tofrom : my_var)
+end subroutine
\ No newline at end of file

>From c0a814c5bc138383dfa2de1dec1451a1a378fa09 Mon Sep 17 00:00:00 2001
From: Akash Banerjee <Akash.Banerjee at amd.com>
Date: Wed, 20 Nov 2024 20:55:45 +0000
Subject: [PATCH 2/5] Add emptyline to test.

---
 flang/test/Lower/OpenMP/declare-mapper.f90 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/test/Lower/OpenMP/declare-mapper.f90 b/flang/test/Lower/OpenMP/declare-mapper.f90
index fd018b4fbb0e0f..eed40d2e4cdce5 100644
--- a/flang/test/Lower/OpenMP/declare-mapper.f90
+++ b/flang/test/Lower/OpenMP/declare-mapper.f90
@@ -28,4 +28,4 @@ subroutine mapper_default
    !CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%[[MY_VAR]] : !fir.ref<![[VAR_TYPE]]>, ![[VAR_TYPE]]) map_clauses(tofrom) capture(ByRef) -> !fir.ref<![[VAR_TYPE]]> {name = "my_var"}
    !CHECK: omp.declare_mapper @default_my_type : %[[MY_VAR]] : !fir.ref<![[VAR_TYPE]]> : ![[VAR_TYPE]] map_entries(%[[MAP_INFO]] : !fir.ref<![[VAR_TYPE]]>)
    !$omp DECLARE MAPPER(my_type :: my_var) map(tofrom : my_var)
-end subroutine
\ No newline at end of file
+end subroutine

>From aca529d84f71166557e00a121c8edc4b3f7d1a90 Mon Sep 17 00:00:00 2001
From: Akash Banerjee <Akash.Banerjee at amd.com>
Date: Fri, 22 Nov 2024 12:50:32 +0000
Subject: [PATCH 3/5] Addressed reviewer comments. Added assert to check for
 derived type.

---
 flang/lib/Lower/OpenMP/OpenMP.cpp | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 16ba5037a919a2..52c56b9575703e 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -40,7 +40,6 @@
 #include "mlir/Transforms/RegionUtils.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Frontend/OpenMP/OMPConstants.h"
-#include <string>
 
 using namespace Fortran::lower::omp;
 using namespace Fortran::common::openmp;
@@ -2620,13 +2619,16 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
   const auto &mapperName{std::get<std::optional<parser::Name>>(spec.t)};
   const auto &varType{std::get<parser::TypeSpec>(spec.t)};
   const auto &varName{std::get<parser::Name>(spec.t)};
-  std::stringstream mapperNameStr;
-  if (mapperName.has_value()) {
-    mapperNameStr << mapperName->ToString();
-  } else {
-    mapperNameStr << "default_"
-                  << varType.declTypeSpec->derivedTypeSpec().name().ToString();
-  }
+  assert(varType.declTypeSpec->category() ==
+             semantics::DeclTypeSpec::Category::TypeDerived &&
+         "Expected derived type");
+
+  std::string mapperNameStr;
+  if (mapperName.has_value())
+    mapperNameStr = mapperName->ToString();
+  else
+    mapperNameStr =
+        "default_" + varType.declTypeSpec->derivedTypeSpec().name().ToString();
 
   mlir::OpBuilder::InsertPoint insPt = firOpBuilder.saveInsertionPoint();
   firOpBuilder.setInsertionPointToStart(converter.getModuleOp().getBody());
@@ -2642,7 +2644,7 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
   ClauseProcessor cp(converter, semaCtx, clauses);
   cp.processMap(converter.getCurrentLocation(), stmtCtx, clauseOps);
   auto declMapperOp = firOpBuilder.create<mlir::omp::DeclareMapperOp>(
-      converter.getCurrentLocation(), mapperNameStr.str(), varVal, mlirType,
+      converter.getCurrentLocation(), mapperNameStr, varVal, mlirType,
       clauseOps.mapVars);
   converter.getMLIRSymbolTable()->insert(declMapperOp.getOperation());
   firOpBuilder.restoreInsertionPoint(insPt);

>From b1c1a89cbe6ebce6512ffc4173287cabc03b27a3 Mon Sep 17 00:00:00 2001
From: Akash Banerjee <Akash.Banerjee at amd.com>
Date: Thu, 28 Nov 2024 21:17:40 +0000
Subject: [PATCH 4/5] Add lowering changes for declMapperOp's region.

---
 flang/lib/Lower/OpenMP/OpenMP.cpp             |  49 ++++++--
 .../Optimizer/OpenMP/MapInfoFinalization.cpp  |   4 +-
 .../Lower/OpenMP/Todo/omp-declare-mapper.f90  |  47 --------
 flang/test/Lower/OpenMP/declare-mapper.f90    | 105 ++++++++++++++----
 4 files changed, 123 insertions(+), 82 deletions(-)
 delete mode 100644 flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90

diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 52c56b9575703e..259c1c810f9179 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2612,6 +2612,7 @@ static void
 genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
        semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
        const parser::OpenMPDeclareMapperConstruct &declareMapperConstruct) {
+  mlir::Location loc = converter.genLocation(declareMapperConstruct.source);
   fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
   lower::StatementContext stmtCtx;
   const auto &spec =
@@ -2629,24 +2630,50 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
   else
     mapperNameStr =
         "default_" + varType.declTypeSpec->derivedTypeSpec().name().ToString();
+  auto mlirType = converter.genType(varType.declTypeSpec->derivedTypeSpec());
+  auto declMapperOp = firOpBuilder.create<mlir::omp::DeclareMapperOp>(
+      loc, mapperNameStr, mlirType);
+  auto &region = declMapperOp.getRegion();
 
+  // Save insert point just after the DeclMapperOp.
   mlir::OpBuilder::InsertPoint insPt = firOpBuilder.saveInsertionPoint();
-  firOpBuilder.setInsertionPointToStart(converter.getModuleOp().getBody());
-  auto mlirType = converter.genType(varType.declTypeSpec->derivedTypeSpec());
-  auto varVal = firOpBuilder.createTemporaryAlloc(
-      converter.getCurrentLocation(), mlirType, varName.ToString());
-  symTable.addSymbol(*varName.symbol, varVal);
+  firOpBuilder.createBlock(&region);
+  auto varVal =
+      firOpBuilder.createTemporaryAlloc(loc, mlirType, varName.ToString());
+  converter.bindSymbol(*varName.symbol, varVal);
 
-  mlir::omp::DeclareMapperOperands clauseOps;
+  // Insert dummy instruction to remember the insertion position. The
+  // marker will be deleted by clean up passes since there are no uses.
+  // Remembering the position for further insertion is important since
+  // there are hlfir.declares inserted above while setting block arguments
+  // and new code from the body should be inserted after that.
+  mlir::Value undefMarker =
+      firOpBuilder.create<fir::UndefOp>(loc, firOpBuilder.getIndexType());
+
+  // Create blocks for unstructured regions. This has to be done since
+  // blocks are initially allocated with the function as the parent region.
+  if (eval.lowerAsUnstructured()) {
+    lower::createEmptyRegionBlocks<mlir::omp::TerminatorOp, mlir::omp::YieldOp>(
+        firOpBuilder, eval.getNestedEvaluations());
+  }
+
+  firOpBuilder.create<mlir::omp::TerminatorOp>(loc);
+
+  // Set the insertion point after the marker.
+  firOpBuilder.setInsertionPointAfter(undefMarker.getDefiningOp());
+  genNestedEvaluations(converter, eval);
+
+  // Populate the declareMapper region with the map information.
+  mlir::omp::DeclareMapperInfoOperands clauseOps;
   const auto *clauseList{
       parser::Unwrap<parser::OmpClauseList>(declareMapperConstruct.t)};
   List<Clause> clauses = makeClauses(*clauseList, semaCtx);
   ClauseProcessor cp(converter, semaCtx, clauses);
-  cp.processMap(converter.getCurrentLocation(), stmtCtx, clauseOps);
-  auto declMapperOp = firOpBuilder.create<mlir::omp::DeclareMapperOp>(
-      converter.getCurrentLocation(), mapperNameStr, varVal, mlirType,
-      clauseOps.mapVars);
-  converter.getMLIRSymbolTable()->insert(declMapperOp.getOperation());
+  cp.processMap(loc, stmtCtx, clauseOps);
+
+  firOpBuilder.create<mlir::omp::DeclareMapperInfoOp>(loc, clauseOps.mapVars);
+
+  // Restore the insert point to just after the DeclareMapperOp.
   firOpBuilder.restoreInsertionPoint(insPt);
 }
 
diff --git a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
index 2991bcd6f242c6..ff3bba04aaf634 100644
--- a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
@@ -451,8 +451,8 @@ class MapInfoFinalizationPass
     for (auto *user : mapOp->getUsers()) {
       if (llvm::isa<mlir::omp::TargetOp, mlir::omp::TargetDataOp,
                     mlir::omp::TargetUpdateOp, mlir::omp::TargetExitDataOp,
-                    mlir::omp::TargetEnterDataOp, mlir::omp::DeclareMapperOp>(
-              user))
+                    mlir::omp::TargetEnterDataOp,
+                    mlir::omp::DeclareMapperInfoOp>(user))
         return user;
 
       if (auto mapUser = llvm::dyn_cast<mlir::omp::MapInfoOp>(user))
diff --git a/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90 b/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
deleted file mode 100644
index 13a4da5849f8c0..00000000000000
--- a/flang/test/Lower/OpenMP/Todo/omp-declare-mapper.f90
+++ /dev/null
@@ -1,47 +0,0 @@
-! This test checks lowering of OpenMP declare mapper Directive.
-
-! RUN: split-file %s %t
-! RUN: not %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-1.f90 2>&1 | FileCheck %t/omp-declare-mapper-1.f90
-! RUN  not %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-2.f90 2>&1 | FileCheck %t/omp-declare-mapper-2.f90
-
-!--- omp-declare-mapper-1.f90
-subroutine declare_mapper_1
- integer,parameter      :: nvals = 250
- type my_type
-   integer              :: num_vals
-   integer, allocatable :: values(:)
- end type
-
- type my_type2
-   type (my_type)        :: my_type_var
-   type (my_type)        :: temp
-   real,dimension(nvals) :: unmapped
-   real,dimension(nvals) :: arr
-  end type
-  type (my_type2)        :: t
-  real                   :: x, y(nvals)
-  !$omp declare mapper (my_type :: var) map (var, var%values (1:var%num_vals))
-!CHECK: not yet implemented: lowering symbol to HLFIR
-end subroutine declare_mapper_1
-
-
-!--- omp-declare-mapper-2.f90
-subroutine declare_mapper_2
- integer,parameter      :: nvals = 250
- type my_type
-   integer              :: num_vals
-   integer, allocatable :: values(:)
- end type
-
- type my_type2
-   type (my_type)        :: my_type_var
-   type (my_type)        :: temp
-   real,dimension(nvals) :: unmapped
-   real,dimension(nvals) :: arr
-  end type
-  type (my_type2)        :: t
-  real                   :: x, y(nvals)
-  !$omp declare mapper (my_mapper : my_type2 :: v) map (v%arr, x, y(:)) &
-  !$omp&                map (alloc : v%temp)
-!CHECK: not yet implemented: lowering symbol to HLFIR
-end subroutine declare_mapper_2
diff --git a/flang/test/Lower/OpenMP/declare-mapper.f90 b/flang/test/Lower/OpenMP/declare-mapper.f90
index eed40d2e4cdce5..e29cb93cf924dc 100644
--- a/flang/test/Lower/OpenMP/declare-mapper.f90
+++ b/flang/test/Lower/OpenMP/declare-mapper.f90
@@ -1,31 +1,92 @@
 ! This test checks lowering of OpenMP declare mapper Directive.
 
 ! RUN: split-file %s %t
-! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/declare-mapper-1.f90 -o - | FileCheck %t/declare-mapper-1.f90
-! RUN  %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/declare-mapper-2.f90 -o - | FileCheck %t/declare-mapper-2.f90
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-1.f90 -o - | FileCheck %t/omp-declare-mapper-1.f90
+! RUN  %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-2.f90 -o - | FileCheck %t/omp-declare-mapper-2.f90
 
-!--- declare-mapper-1.f90
-subroutine mapper
-   implicit none
+!--- omp-declare-mapper-1.f90
+subroutine declare_mapper_1
+   integer, parameter      :: nvals = 250
    type my_type
-      integer, pointer :: my_buffer
-      integer :: my_buffer_size
+      integer              :: num_vals
+      integer, allocatable :: values(:)
    end type
-   !CHECK: %[[MY_VAR:.*]] = fir.alloca ![[VAR_TYPE:.*]] {bindc_name = "my_var"}
-   !CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%[[MY_VAR]] : !fir.ref<![[VAR_TYPE]]>, ![[VAR_TYPE]]) map_clauses(tofrom) capture(ByRef) -> !fir.ref<![[VAR_TYPE]]> {name = "my_var"}
-   !CHECK: omp.declare_mapper @my_mapper : %[[MY_VAR]] : !fir.ref<![[VAR_TYPE]]> : ![[VAR_TYPE]] map_entries(%[[MAP_INFO]] : !fir.ref<![[VAR_TYPE]]>)
-   !$omp DECLARE MAPPER(my_mapper : my_type :: my_var) map(tofrom : my_var)
-end subroutine
 
-!--- declare-mapper-2.f90
-subroutine mapper_default
-   implicit none
+   type my_type2
+      type(my_type)        :: my_type_var
+      type(my_type)        :: temp
+      real, dimension(nvals) :: unmapped
+      real, dimension(nvals) :: arr
+   end type
+   type(my_type2)        :: t
+   real                   :: x, y(nvals)
+   !CHECK: omp.declare_mapper @default_my_type : ![[VAR_TYPE:.*]] {
+   !CHECK:   %[[VAL_5:.*]] = fir.alloca ![[VAR_TYPE]] {bindc_name = "var"}
+   !CHECK:   %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] {uniq_name = "_QFdeclare_mapper_1Evar"} : (!fir.ref<![[VAR_TYPE]]>) -> (!fir.ref<![[VAR_TYPE]]>, !fir.ref<![[VAR_TYPE]]>)
+   !CHECK:   %[[VAL_7:.*]] = hlfir.designate %[[VAL_6]]#0{{.*}} : (!fir.ref<![[VAR_TYPE]]>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+   !CHECK:   %[[VAL_8:.*]] = fir.load %[[VAL_7]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+   !CHECK:   %[[VAL_9:.*]] = arith.constant 0 : index
+   !CHECK:   %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_8]], %[[VAL_9]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+   !CHECK:   %[[VAL_11:.*]] = arith.constant 1 : index
+   !CHECK:   %[[VAL_12:.*]] = arith.constant 1 : index
+   !CHECK:   %[[VAL_13:.*]] = arith.subi %[[VAL_12]], %[[VAL_10]]#0 : index
+   !CHECK:   %[[VAL_14:.*]] = hlfir.designate %[[VAL_6]]#0{"num_vals"}   : (!fir.ref<![[VAR_TYPE]]>) -> !fir.ref<i32>
+   !CHECK:   %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
+   !CHECK:   %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64
+   !CHECK:   %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index
+   !CHECK:   %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_10]]#0 : index
+   !CHECK:   %[[VAL_19:.*]] = omp.map.bounds lower_bound(%[[VAL_13]] : index) upper_bound(%[[VAL_18]] : index) extent(%[[VAL_10]]#1 : index) stride(%[[VAL_11]] : index) start_idx(%[[VAL_10]]#0 : index)
+   !CHECK:   %[[VAL_20:.*]] = arith.constant 1 : index
+   !CHECK:   %[[VAL_21:.*]] = fir.coordinate_of %[[VAL_6]]#0, %[[VAL_20]] : (!fir.ref<![[VAR_TYPE]]>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+   !CHECK:   %[[VAL_22:.*]] = fir.box_offset %[[VAL_21]] base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
+   !CHECK:   %[[VAL_23:.*]] = omp.map.info var_ptr(%[[VAL_21]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAL_22]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_19]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""}
+   !CHECK:   %[[VAL_24:.*]] = omp.map.info var_ptr(%[[VAL_21]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(to) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {name = "var%[[VAL_25:.*]](1:var%[[VAL_26:.*]])"}
+   !CHECK:   %[[VAL_27:.*]] = omp.map.info var_ptr(%[[VAL_6]]#1 : !fir.ref<![[VAR_TYPE]]>, ![[VAR_TYPE]]) map_clauses(tofrom) capture(ByRef) members(%[[VAL_24]], %[[VAL_23]] : [1], [1, 0] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<![[VAR_TYPE]]> {name = "var"}
+   !CHECK:   omp.declare_mapper_info map_entries(%[[VAL_27]], %[[VAL_24]], %[[VAL_23]] : !fir.ref<![[VAR_TYPE]]>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>)
+   !CHECK:   omp.terminator
+   !CHECK: }
+   !$omp declare mapper (my_type :: var) map (var, var%values (1:var%num_vals))
+end subroutine declare_mapper_1
+
+!--- omp-declare-mapper-2.f90
+subroutine declare_mapper_2
+   integer, parameter      :: nvals = 250
    type my_type
-      integer, pointer :: my_buffer
-      integer :: my_buffer_size
+      integer              :: num_vals
+      integer, allocatable :: values(:)
+   end type
+
+   type my_type2
+      type(my_type)        :: my_type_var
+      type(my_type)        :: temp
+      real, dimension(nvals) :: unmapped
+      real, dimension(nvals) :: arr
    end type
-   !CHECK: %[[MY_VAR:.*]] = fir.alloca ![[VAR_TYPE:.*]] {bindc_name = "my_var"}
-   !CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%[[MY_VAR]] : !fir.ref<![[VAR_TYPE]]>, ![[VAR_TYPE]]) map_clauses(tofrom) capture(ByRef) -> !fir.ref<![[VAR_TYPE]]> {name = "my_var"}
-   !CHECK: omp.declare_mapper @default_my_type : %[[MY_VAR]] : !fir.ref<![[VAR_TYPE]]> : ![[VAR_TYPE]] map_entries(%[[MAP_INFO]] : !fir.ref<![[VAR_TYPE]]>)
-   !$omp DECLARE MAPPER(my_type :: my_var) map(tofrom : my_var)
-end subroutine
+   type(my_type2)        :: t
+   real                   :: x, y(nvals)
+   !CHECK: omp.declare_mapper @my_mapper : ![[VAR_TYPE:.*]] {
+   !CHECK:   %[[VAL_0:.*]] = fir.alloca ![[VAR_TYPE]] {bindc_name = "v"}
+   !CHECK:   %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFdeclare_mapper_2Ev"} : (!fir.ref<![[VAR_TYPE]]>) -> (!fir.ref<![[VAR_TYPE]]>, !fir.ref<![[VAR_TYPE]]>)
+   !CHECK:   %[[VAL_2:.*]] = arith.constant 250 : index
+   !CHECK:   %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
+   !CHECK:   %[[VAL_4:.*]] = hlfir.designate %[[VAL_1]]#0{"arr"}   shape %[[VAL_3]] : (!fir.ref<![[VAR_TYPE]]>, !fir.shape<1>) -> !fir.ref<!fir.array<250xf32>>
+   !CHECK:   %[[VAL_5:.*]] = arith.constant 1 : index
+   !CHECK:   %[[VAL_6:.*]] = arith.constant 0 : index
+   !CHECK:   %[[VAL_7:.*]] = arith.subi %[[VAL_2]], %[[VAL_5]] : index
+   !CHECK:   %[[VAL_8:.*]] = omp.map.bounds lower_bound(%[[VAL_6]] : index) upper_bound(%[[VAL_7]] : index) extent(%[[VAL_2]] : index) stride(%[[VAL_5]] : index) start_idx(%[[VAL_5]] : index)
+   !CHECK:   %[[VAL_9:.*]] = omp.map.info var_ptr(%[[VAL_4]] : !fir.ref<!fir.array<250xf32>>, !fir.array<250xf32>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_8]]) -> !fir.ref<!fir.array<250xf32>> {name = "v%[[VAL_10:.*]]"}
+   !CHECK:   %[[VAL_11:.*]] = omp.map.info var_ptr(%[[VAL_12:.*]]#1 : !fir.ref<f32>, f32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<f32> {name = "x"}
+   !CHECK:   %[[VAL_13:.*]] = arith.constant 0 : index
+   !CHECK:   %[[VAL_14:.*]] = arith.constant 1 : index
+   !CHECK:   %[[VAL_15:.*]] = arith.subi %[[VAL_16:.*]], %[[VAL_14]] : index
+   !CHECK:   %[[VAL_17:.*]] = omp.map.bounds lower_bound(%[[VAL_13]] : index) upper_bound(%[[VAL_15]] : index) extent(%[[VAL_16]] : index) stride(%[[VAL_14]] : index) start_idx(%[[VAL_14]] : index)
+   !CHECK:   %[[VAL_18:.*]] = omp.map.info var_ptr(%[[VAL_19:.*]]#1 : !fir.ref<!fir.array<250xf32>>, !fir.array<250xf32>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_17]]) -> !fir.ref<!fir.array<250xf32>> {name = "y(:)"}
+   !CHECK:   %[[VAL_20:.*]] = hlfir.designate %[[VAL_1]]#0{"temp"}   : (!fir.ref<![[VAR_TYPE]]>) -> !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
+   !CHECK:   %[[VAL_21:.*]] = omp.map.info var_ptr(%[[VAL_20]] : !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>> {name = "v%[[VAL_22:.*]]"}
+   !CHECK:   %[[VAL_23:.*]] = omp.map.info var_ptr(%[[VAL_1]]#1 : !fir.ref<![[VAR_TYPE]]>, ![[VAR_TYPE]]) map_clauses(tofrom) capture(ByRef) members(%[[VAL_9]], %[[VAL_21]] : [3], [1] : !fir.ref<!fir.array<250xf32>>, !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<![[VAR_TYPE]]> {name = "v", partial_map = true}
+   !CHECK:   omp.declare_mapper_info map_entries(%[[VAL_11]], %[[VAL_18]], %[[VAL_23]], %[[VAL_9]], %[[VAL_21]] : !fir.ref<f32>, !fir.ref<!fir.array<250xf32>>, !fir.ref<![[VAR_TYPE]]>, !fir.ref<!fir.array<250xf32>>, !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
+   !CHECK:   omp.terminator
+   !CHECK: }
+   !$omp declare mapper (my_mapper : my_type2 :: v) map (v%arr, x, y(:)) &
+   !$omp&                map (alloc : v%temp)
+end subroutine declare_mapper_2

>From 7e504c82d3350a0c2e7bb4b5ab7d1ddebdeed206 Mon Sep 17 00:00:00 2001
From: Akash Banerjee <Akash.Banerjee at amd.com>
Date: Mon, 23 Dec 2024 18:43:49 +0000
Subject: [PATCH 5/5] Add required changes to hoist DeclareMapperOp to the
 ModuleOp's region. Add a new name mangling method which accepts a user
 supplied scope to mangle the name, in addition to the existing function which
 always used the currentScope.

---
 flang/include/flang/Lower/AbstractConverter.h |  2 +
 flang/lib/Lower/Bridge.cpp                    |  5 +
 flang/lib/Lower/OpenMP/OpenMP.cpp             | 45 +++------
 flang/test/Lower/OpenMP/declare-mapper.f90    | 95 +++++++++----------
 4 files changed, 65 insertions(+), 82 deletions(-)

diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h
index 8f026ac3280bf4..da15e621c0fed9 100644
--- a/flang/include/flang/Lower/AbstractConverter.h
+++ b/flang/include/flang/Lower/AbstractConverter.h
@@ -305,6 +305,8 @@ class AbstractConverter {
   mangleName(const Fortran::semantics::DerivedTypeSpec &) = 0;
   /// Unique a compiler generated name (add a containing scope specific prefix)
   virtual std::string mangleName(std::string &) = 0;
+  /// Unique a compiler generated name (add a provided scope specific prefix)
+  virtual std::string mangleName(std::string &, const semantics::Scope &) = 0;
   /// Return the field name for a derived type component inside a fir.record
   /// type.
   virtual std::string
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 17b794d147c6f5..97b4244d42636e 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -1047,6 +1047,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
     return Fortran::lower::mangle::mangleName(name, getCurrentScope(),
                                               scopeBlockIdMap);
   }
+  std::string
+  mangleName(std::string &name,
+             const Fortran::semantics::Scope &myScope) override final {
+    return Fortran::lower::mangle::mangleName(name, myScope, scopeBlockIdMap);
+  }
   std::string getRecordTypeFieldName(
       const Fortran::semantics::Symbol &component) override final {
     return Fortran::lower::mangle::getRecordTypeFieldName(component,
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 259c1c810f9179..80e448481ec2d1 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2625,44 +2625,30 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
          "Expected derived type");
 
   std::string mapperNameStr;
-  if (mapperName.has_value())
+  if (mapperName.has_value()) {
     mapperNameStr = mapperName->ToString();
-  else
     mapperNameStr =
-        "default_" + varType.declTypeSpec->derivedTypeSpec().name().ToString();
+        converter.mangleName(mapperNameStr, mapperName->symbol->owner());
+  } else {
+    mapperNameStr =
+        varType.declTypeSpec->derivedTypeSpec().name().ToString() + ".default";
+    mapperNameStr = converter.mangleName(
+        mapperNameStr, *varType.declTypeSpec->derivedTypeSpec().GetScope());
+  }
+
+  // Save insert point just after the DeclMapperOp.
+  mlir::OpBuilder::InsertPoint insPt = firOpBuilder.saveInsertionPoint();
+
+  firOpBuilder.setInsertionPointToStart(converter.getModuleOp().getBody());
   auto mlirType = converter.genType(varType.declTypeSpec->derivedTypeSpec());
   auto declMapperOp = firOpBuilder.create<mlir::omp::DeclareMapperOp>(
       loc, mapperNameStr, mlirType);
+  converter.getMLIRSymbolTable()->insert(declMapperOp);
   auto &region = declMapperOp.getRegion();
-
-  // Save insert point just after the DeclMapperOp.
-  mlir::OpBuilder::InsertPoint insPt = firOpBuilder.saveInsertionPoint();
   firOpBuilder.createBlock(&region);
-  auto varVal =
-      firOpBuilder.createTemporaryAlloc(loc, mlirType, varName.ToString());
+  auto varVal = region.addArgument(firOpBuilder.getRefType(mlirType), loc);
   converter.bindSymbol(*varName.symbol, varVal);
 
-  // Insert dummy instruction to remember the insertion position. The
-  // marker will be deleted by clean up passes since there are no uses.
-  // Remembering the position for further insertion is important since
-  // there are hlfir.declares inserted above while setting block arguments
-  // and new code from the body should be inserted after that.
-  mlir::Value undefMarker =
-      firOpBuilder.create<fir::UndefOp>(loc, firOpBuilder.getIndexType());
-
-  // Create blocks for unstructured regions. This has to be done since
-  // blocks are initially allocated with the function as the parent region.
-  if (eval.lowerAsUnstructured()) {
-    lower::createEmptyRegionBlocks<mlir::omp::TerminatorOp, mlir::omp::YieldOp>(
-        firOpBuilder, eval.getNestedEvaluations());
-  }
-
-  firOpBuilder.create<mlir::omp::TerminatorOp>(loc);
-
-  // Set the insertion point after the marker.
-  firOpBuilder.setInsertionPointAfter(undefMarker.getDefiningOp());
-  genNestedEvaluations(converter, eval);
-
   // Populate the declareMapper region with the map information.
   mlir::omp::DeclareMapperInfoOperands clauseOps;
   const auto *clauseList{
@@ -2670,7 +2656,6 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
   List<Clause> clauses = makeClauses(*clauseList, semaCtx);
   ClauseProcessor cp(converter, semaCtx, clauses);
   cp.processMap(loc, stmtCtx, clauseOps);
-
   firOpBuilder.create<mlir::omp::DeclareMapperInfoOp>(loc, clauseOps.mapVars);
 
   // Restore the insert point to just after the DeclareMapperOp.
diff --git a/flang/test/Lower/OpenMP/declare-mapper.f90 b/flang/test/Lower/OpenMP/declare-mapper.f90
index e29cb93cf924dc..4d9e201ea07dae 100644
--- a/flang/test/Lower/OpenMP/declare-mapper.f90
+++ b/flang/test/Lower/OpenMP/declare-mapper.f90
@@ -2,7 +2,7 @@
 
 ! RUN: split-file %s %t
 ! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-1.f90 -o - | FileCheck %t/omp-declare-mapper-1.f90
-! RUN  %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-2.f90 -o - | FileCheck %t/omp-declare-mapper-2.f90
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-2.f90 -o - | FileCheck %t/omp-declare-mapper-2.f90
 
 !--- omp-declare-mapper-1.f90
 subroutine declare_mapper_1
@@ -20,31 +20,30 @@ subroutine declare_mapper_1
    end type
    type(my_type2)        :: t
    real                   :: x, y(nvals)
-   !CHECK: omp.declare_mapper @default_my_type : ![[VAR_TYPE:.*]] {
-   !CHECK:   %[[VAL_5:.*]] = fir.alloca ![[VAR_TYPE]] {bindc_name = "var"}
-   !CHECK:   %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] {uniq_name = "_QFdeclare_mapper_1Evar"} : (!fir.ref<![[VAR_TYPE]]>) -> (!fir.ref<![[VAR_TYPE]]>, !fir.ref<![[VAR_TYPE]]>)
-   !CHECK:   %[[VAL_7:.*]] = hlfir.designate %[[VAL_6]]#0{{.*}} : (!fir.ref<![[VAR_TYPE]]>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-   !CHECK:   %[[VAL_8:.*]] = fir.load %[[VAL_7]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-   !CHECK:   %[[VAL_9:.*]] = arith.constant 0 : index
-   !CHECK:   %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_8]], %[[VAL_9]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
-   !CHECK:   %[[VAL_11:.*]] = arith.constant 1 : index
-   !CHECK:   %[[VAL_12:.*]] = arith.constant 1 : index
-   !CHECK:   %[[VAL_13:.*]] = arith.subi %[[VAL_12]], %[[VAL_10]]#0 : index
-   !CHECK:   %[[VAL_14:.*]] = hlfir.designate %[[VAL_6]]#0{"num_vals"}   : (!fir.ref<![[VAR_TYPE]]>) -> !fir.ref<i32>
-   !CHECK:   %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
-   !CHECK:   %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64
-   !CHECK:   %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index
-   !CHECK:   %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_10]]#0 : index
-   !CHECK:   %[[VAL_19:.*]] = omp.map.bounds lower_bound(%[[VAL_13]] : index) upper_bound(%[[VAL_18]] : index) extent(%[[VAL_10]]#1 : index) stride(%[[VAL_11]] : index) start_idx(%[[VAL_10]]#0 : index)
-   !CHECK:   %[[VAL_20:.*]] = arith.constant 1 : index
-   !CHECK:   %[[VAL_21:.*]] = fir.coordinate_of %[[VAL_6]]#0, %[[VAL_20]] : (!fir.ref<![[VAR_TYPE]]>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-   !CHECK:   %[[VAL_22:.*]] = fir.box_offset %[[VAL_21]] base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
-   !CHECK:   %[[VAL_23:.*]] = omp.map.info var_ptr(%[[VAL_21]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAL_22]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_19]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""}
-   !CHECK:   %[[VAL_24:.*]] = omp.map.info var_ptr(%[[VAL_21]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(to) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {name = "var%[[VAL_25:.*]](1:var%[[VAL_26:.*]])"}
-   !CHECK:   %[[VAL_27:.*]] = omp.map.info var_ptr(%[[VAL_6]]#1 : !fir.ref<![[VAR_TYPE]]>, ![[VAR_TYPE]]) map_clauses(tofrom) capture(ByRef) members(%[[VAL_24]], %[[VAL_23]] : [1], [1, 0] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<![[VAR_TYPE]]> {name = "var"}
-   !CHECK:   omp.declare_mapper_info map_entries(%[[VAL_27]], %[[VAL_24]], %[[VAL_23]] : !fir.ref<![[VAR_TYPE]]>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>)
-   !CHECK:   omp.terminator
-   !CHECK: }
+   !CHECK-LABEL: omp.declare_mapper @_QQFdeclare_mapper_1my_type.default : !fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}> {
+   !CHECK:       ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>):
+   !CHECK:         %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFdeclare_mapper_1Evar"} : (!fir.ref<!fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
+   !CHECK:         %[[VAL_2:.*]] = hlfir.designate %[[VAL_1]]#0{"values"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+   !CHECK:         %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+   !CHECK:         %[[VAL_4:.*]] = fir.box_addr %[[VAL_3]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+   !CHECK:         %[[VAL_5:.*]] = arith.constant 0 : index
+   !CHECK:         %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_3]], %[[VAL_5]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+   !CHECK:         %[[VAL_7:.*]] = arith.constant 0 : index
+   !CHECK:         %[[VAL_8:.*]] = arith.constant 1 : index
+   !CHECK:         %[[VAL_9:.*]] = arith.constant 1 : index
+   !CHECK:         %[[VAL_10:.*]] = arith.subi %[[VAL_9]], %[[VAL_6]]#0 : index
+   !CHECK:         %[[VAL_11:.*]] = hlfir.designate %[[VAL_1]]#0{"num_vals"}   : (!fir.ref<!fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<i32>
+   !CHECK:         %[[VAL_12:.*]] = fir.load %[[VAL_11]] : !fir.ref<i32>
+   !CHECK:         %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i32) -> i64
+   !CHECK:         %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> index
+   !CHECK:         %[[VAL_15:.*]] = arith.subi %[[VAL_14]], %[[VAL_6]]#0 : index
+   !CHECK:         %[[VAL_16:.*]] = omp.map.bounds lower_bound(%[[VAL_10]] : index) upper_bound(%[[VAL_15]] : index) extent(%[[VAL_6]]#1 : index) stride(%[[VAL_8]] : index) start_idx(%[[VAL_6]]#0 : index)
+   !CHECK:         %[[VAL_17:.*]] = arith.constant 1 : index
+   !CHECK:         %[[VAL_18:.*]] = fir.coordinate_of %[[VAL_1]]#0, %[[VAL_17]] : (!fir.ref<!fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+   !CHECK:         %[[VAL_19:.*]] = omp.map.info var_ptr(%[[VAL_18]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_16]]) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {name = "var%[[VAL_20:.*]](1:var%[[VAL_21:.*]])"}
+   !CHECK:         %[[VAL_22:.*]] = omp.map.info var_ptr(%[[VAL_1]]#1 : !fir.ref<!fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>) map_clauses(tofrom) capture(ByRef) members(%[[VAL_19]] : [1] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>> {name = "var"}
+   !CHECK:         omp.declare_mapper_info map_entries(%[[VAL_22]] : !fir.ref<!fir.type<_QFdeclare_mapper_1Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
+   !CHECK:       }
    !$omp declare mapper (my_type :: var) map (var, var%values (1:var%num_vals))
 end subroutine declare_mapper_1
 
@@ -63,30 +62,22 @@ subroutine declare_mapper_2
       real, dimension(nvals) :: arr
    end type
    type(my_type2)        :: t
-   real                   :: x, y(nvals)
-   !CHECK: omp.declare_mapper @my_mapper : ![[VAR_TYPE:.*]] {
-   !CHECK:   %[[VAL_0:.*]] = fir.alloca ![[VAR_TYPE]] {bindc_name = "v"}
-   !CHECK:   %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFdeclare_mapper_2Ev"} : (!fir.ref<![[VAR_TYPE]]>) -> (!fir.ref<![[VAR_TYPE]]>, !fir.ref<![[VAR_TYPE]]>)
-   !CHECK:   %[[VAL_2:.*]] = arith.constant 250 : index
-   !CHECK:   %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
-   !CHECK:   %[[VAL_4:.*]] = hlfir.designate %[[VAL_1]]#0{"arr"}   shape %[[VAL_3]] : (!fir.ref<![[VAR_TYPE]]>, !fir.shape<1>) -> !fir.ref<!fir.array<250xf32>>
-   !CHECK:   %[[VAL_5:.*]] = arith.constant 1 : index
-   !CHECK:   %[[VAL_6:.*]] = arith.constant 0 : index
-   !CHECK:   %[[VAL_7:.*]] = arith.subi %[[VAL_2]], %[[VAL_5]] : index
-   !CHECK:   %[[VAL_8:.*]] = omp.map.bounds lower_bound(%[[VAL_6]] : index) upper_bound(%[[VAL_7]] : index) extent(%[[VAL_2]] : index) stride(%[[VAL_5]] : index) start_idx(%[[VAL_5]] : index)
-   !CHECK:   %[[VAL_9:.*]] = omp.map.info var_ptr(%[[VAL_4]] : !fir.ref<!fir.array<250xf32>>, !fir.array<250xf32>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_8]]) -> !fir.ref<!fir.array<250xf32>> {name = "v%[[VAL_10:.*]]"}
-   !CHECK:   %[[VAL_11:.*]] = omp.map.info var_ptr(%[[VAL_12:.*]]#1 : !fir.ref<f32>, f32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<f32> {name = "x"}
-   !CHECK:   %[[VAL_13:.*]] = arith.constant 0 : index
-   !CHECK:   %[[VAL_14:.*]] = arith.constant 1 : index
-   !CHECK:   %[[VAL_15:.*]] = arith.subi %[[VAL_16:.*]], %[[VAL_14]] : index
-   !CHECK:   %[[VAL_17:.*]] = omp.map.bounds lower_bound(%[[VAL_13]] : index) upper_bound(%[[VAL_15]] : index) extent(%[[VAL_16]] : index) stride(%[[VAL_14]] : index) start_idx(%[[VAL_14]] : index)
-   !CHECK:   %[[VAL_18:.*]] = omp.map.info var_ptr(%[[VAL_19:.*]]#1 : !fir.ref<!fir.array<250xf32>>, !fir.array<250xf32>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_17]]) -> !fir.ref<!fir.array<250xf32>> {name = "y(:)"}
-   !CHECK:   %[[VAL_20:.*]] = hlfir.designate %[[VAL_1]]#0{"temp"}   : (!fir.ref<![[VAR_TYPE]]>) -> !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
-   !CHECK:   %[[VAL_21:.*]] = omp.map.info var_ptr(%[[VAL_20]] : !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>> {name = "v%[[VAL_22:.*]]"}
-   !CHECK:   %[[VAL_23:.*]] = omp.map.info var_ptr(%[[VAL_1]]#1 : !fir.ref<![[VAR_TYPE]]>, ![[VAR_TYPE]]) map_clauses(tofrom) capture(ByRef) members(%[[VAL_9]], %[[VAL_21]] : [3], [1] : !fir.ref<!fir.array<250xf32>>, !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<![[VAR_TYPE]]> {name = "v", partial_map = true}
-   !CHECK:   omp.declare_mapper_info map_entries(%[[VAL_11]], %[[VAL_18]], %[[VAL_23]], %[[VAL_9]], %[[VAL_21]] : !fir.ref<f32>, !fir.ref<!fir.array<250xf32>>, !fir.ref<![[VAR_TYPE]]>, !fir.ref<!fir.array<250xf32>>, !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
-   !CHECK:   omp.terminator
-   !CHECK: }
-   !$omp declare mapper (my_mapper : my_type2 :: v) map (v%arr, x, y(:)) &
-   !$omp&                map (alloc : v%temp)
+   real                  :: x, y(nvals)
+   !CHECK-LABEL: omp.declare_mapper @_QQFdeclare_mapper_2my_mapper : !fir.type<_QFdeclare_mapper_2Tmy_type2{my_type_var:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,temp:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,unmapped:!fir.array<250xf32>,arr:!fir.array<250xf32>}> {
+   !CHECK:       ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type2{my_type_var:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,temp:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,unmapped:!fir.array<250xf32>,arr:!fir.array<250xf32>}>>):
+   !CHECK:         %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFdeclare_mapper_2Ev"} : (!fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type2{my_type_var:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,temp:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,unmapped:!fir.array<250xf32>,arr:!fir.array<250xf32>}>>) -> (!fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type2{my_type_var:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,temp:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,unmapped:!fir.array<250xf32>,arr:!fir.array<250xf32>}>>, !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type2{my_type_var:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,temp:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,unmapped:!fir.array<250xf32>,arr:!fir.array<250xf32>}>>)
+   !CHECK:         %[[VAL_2:.*]] = arith.constant 250 : index
+   !CHECK:         %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
+   !CHECK:         %[[VAL_4:.*]] = hlfir.designate %[[VAL_1]]#0{"arr"}   shape %[[VAL_3]] : (!fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type2{my_type_var:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,temp:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,unmapped:!fir.array<250xf32>,arr:!fir.array<250xf32>}>>, !fir.shape<1>) -> !fir.ref<!fir.array<250xf32>>
+   !CHECK:         %[[VAL_5:.*]] = arith.constant 1 : index
+   !CHECK:         %[[VAL_6:.*]] = arith.constant 0 : index
+   !CHECK:         %[[VAL_7:.*]] = arith.subi %[[VAL_2]], %[[VAL_5]] : index
+   !CHECK:         %[[VAL_8:.*]] = omp.map.bounds lower_bound(%[[VAL_6]] : index) upper_bound(%[[VAL_7]] : index) extent(%[[VAL_2]] : index) stride(%[[VAL_5]] : index) start_idx(%[[VAL_5]] : index)
+   !CHECK:         %[[VAL_9:.*]] = omp.map.info var_ptr(%[[VAL_4]] : !fir.ref<!fir.array<250xf32>>, !fir.array<250xf32>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_8]]) -> !fir.ref<!fir.array<250xf32>> {name = "v%[[VAL_10:.*]]"}
+   !CHECK:         %[[VAL_11:.*]] = hlfir.designate %[[VAL_1]]#0{"temp"}   : (!fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type2{my_type_var:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,temp:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,unmapped:!fir.array<250xf32>,arr:!fir.array<250xf32>}>>) -> !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
+   !CHECK:         %[[VAL_12:.*]] = omp.map.info var_ptr(%[[VAL_11]] : !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>> {name = "v%[[VAL_13:.*]]"}
+   !CHECK:         %[[VAL_14:.*]] = omp.map.info var_ptr(%[[VAL_1]]#1 : !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type2{my_type_var:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,temp:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,unmapped:!fir.array<250xf32>,arr:!fir.array<250xf32>}>>, !fir.type<_QFdeclare_mapper_2Tmy_type2{my_type_var:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,temp:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,unmapped:!fir.array<250xf32>,arr:!fir.array<250xf32>}>) map_clauses(tofrom) capture(ByRef) members(%[[VAL_9]], %[[VAL_12]] : [3], [1] : !fir.ref<!fir.array<250xf32>>, !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type2{my_type_var:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,temp:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,unmapped:!fir.array<250xf32>,arr:!fir.array<250xf32>}>> {name = "v", partial_map = true}
+   !CHECK:         omp.declare_mapper_info map_entries(%[[VAL_14]] : !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type2{my_type_var:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,temp:!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>,unmapped:!fir.array<250xf32>,arr:!fir.array<250xf32>}>>)
+   !CHECK:       }
+   !$omp declare mapper (my_mapper : my_type2 :: v) map (v%arr) map (alloc : v%temp)
 end subroutine declare_mapper_2



More information about the llvm-branch-commits mailing list