[flang-commits] [flang] [flang][acc] Generate constructors and destructors for common blocks (PR #137691)

via flang-commits flang-commits at lists.llvm.org
Mon Apr 28 12:11:49 PDT 2025


https://github.com/khaki3 updated https://github.com/llvm/llvm-project/pull/137691

>From 7a930ab08360d49d9d10894c1693dbbf600240cd Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Mon, 28 Apr 2025 12:02:27 -0700
Subject: [PATCH 1/2] [flang][acc] Generate constructors and destructor for
 common blocks

---
 flang/lib/Lower/OpenACC.cpp                   | 138 +++++++++---------
 .../Lower/OpenACC/acc-declare-globals.f90     |  33 +++++
 2 files changed, 104 insertions(+), 67 deletions(-)

diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 418bf4ee3d15f..27e08d4b6f20e 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -3754,6 +3754,66 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
                            const Fortran::parser::AccObjectList &accObjectList,
                            mlir::acc::DataClause clause) {
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+  auto genCtros = [&](const mlir::Location operandLocation,
+                      const Fortran::semantics::Symbol &symbol) {
+    std::string globalName = converter.mangleName(symbol);
+    fir::GlobalOp globalOp = builder.getNamedGlobal(globalName);
+    std::stringstream declareGlobalCtorName;
+    declareGlobalCtorName << globalName << "_acc_ctor";
+    std::stringstream declareGlobalDtorName;
+    declareGlobalDtorName << globalName << "_acc_dtor";
+    std::stringstream asFortran;
+    asFortran << symbol.name().ToString();
+
+    if (builder.getModule().lookupSymbol<mlir::acc::GlobalConstructorOp>(
+            declareGlobalCtorName.str()))
+      return;
+
+    if (!globalOp) {
+      if (Fortran::semantics::FindEquivalenceSet(symbol)) {
+        for (Fortran::semantics::EquivalenceObject eqObj :
+             *Fortran::semantics::FindEquivalenceSet(symbol)) {
+          std::string eqName = converter.mangleName(eqObj.symbol);
+          globalOp = builder.getNamedGlobal(eqName);
+          if (globalOp)
+            break;
+        }
+
+        if (!globalOp)
+          llvm::report_fatal_error("could not retrieve global symbol");
+      } else {
+        llvm::report_fatal_error("could not retrieve global symbol");
+      }
+    }
+
+    addDeclareAttr(builder, globalOp.getOperation(), clause);
+    auto crtPos = builder.saveInsertionPoint();
+    modBuilder.setInsertionPointAfter(globalOp);
+    if (mlir::isa<fir::BaseBoxType>(fir::unwrapRefType(globalOp.getType()))) {
+      createDeclareGlobalOp<mlir::acc::GlobalConstructorOp, mlir::acc::CopyinOp,
+                            mlir::acc::DeclareEnterOp, ExitOp>(
+          modBuilder, builder, operandLocation, globalOp, clause,
+          declareGlobalCtorName.str(), /*implicit=*/true, asFortran);
+      createDeclareAllocFunc<EntryOp>(modBuilder, builder, operandLocation,
+                                      globalOp, clause);
+      if constexpr (!std::is_same_v<EntryOp, ExitOp>)
+        createDeclareDeallocFunc<ExitOp>(modBuilder, builder, operandLocation,
+                                         globalOp, clause);
+    } else {
+      createDeclareGlobalOp<mlir::acc::GlobalConstructorOp, EntryOp,
+                            mlir::acc::DeclareEnterOp, ExitOp>(
+          modBuilder, builder, operandLocation, globalOp, clause,
+          declareGlobalCtorName.str(), /*implicit=*/false, asFortran);
+    }
+    if constexpr (!std::is_same_v<EntryOp, ExitOp>) {
+      createDeclareGlobalOp<mlir::acc::GlobalDestructorOp,
+                            mlir::acc::GetDevicePtrOp, mlir::acc::DeclareExitOp,
+                            ExitOp>(
+          modBuilder, builder, operandLocation, globalOp, clause,
+          declareGlobalDtorName.str(), /*implicit=*/false, asFortran);
+    }
+    builder.restoreInsertionPoint(crtPos);
+  };
   for (const auto &accObject : accObjectList.v) {
     mlir::Location operandLocation = genOperandLocation(converter, accObject);
     Fortran::common::visit(
@@ -3762,76 +3822,20 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
               if (const auto *name =
                       Fortran::semantics::getDesignatorNameIfDataRef(
                           designator)) {
-                std::string globalName = converter.mangleName(*name->symbol);
-                fir::GlobalOp globalOp = builder.getNamedGlobal(globalName);
-                std::stringstream declareGlobalCtorName;
-                declareGlobalCtorName << globalName << "_acc_ctor";
-                std::stringstream declareGlobalDtorName;
-                declareGlobalDtorName << globalName << "_acc_dtor";
-                std::stringstream asFortran;
-                asFortran << name->symbol->name().ToString();
-
-                if (builder.getModule()
-                        .lookupSymbol<mlir::acc::GlobalConstructorOp>(
-                            declareGlobalCtorName.str()))
-                  return;
-
-                if (!globalOp) {
-                  if (Fortran::semantics::FindEquivalenceSet(*name->symbol)) {
-                    for (Fortran::semantics::EquivalenceObject eqObj :
-                         *Fortran::semantics::FindEquivalenceSet(
-                             *name->symbol)) {
-                      std::string eqName = converter.mangleName(eqObj.symbol);
-                      globalOp = builder.getNamedGlobal(eqName);
-                      if (globalOp)
-                        break;
-                    }
-
-                    if (!globalOp)
-                      llvm::report_fatal_error(
-                          "could not retrieve global symbol");
-                  } else {
-                    llvm::report_fatal_error(
-                        "could not retrieve global symbol");
-                  }
-                }
-
-                addDeclareAttr(builder, globalOp.getOperation(), clause);
-                auto crtPos = builder.saveInsertionPoint();
-                modBuilder.setInsertionPointAfter(globalOp);
-                if (mlir::isa<fir::BaseBoxType>(
-                        fir::unwrapRefType(globalOp.getType()))) {
-                  createDeclareGlobalOp<mlir::acc::GlobalConstructorOp,
-                                        mlir::acc::CopyinOp,
-                                        mlir::acc::DeclareEnterOp, ExitOp>(
-                      modBuilder, builder, operandLocation, globalOp, clause,
-                      declareGlobalCtorName.str(), /*implicit=*/true,
-                      asFortran);
-                  createDeclareAllocFunc<EntryOp>(
-                      modBuilder, builder, operandLocation, globalOp, clause);
-                  if constexpr (!std::is_same_v<EntryOp, ExitOp>)
-                    createDeclareDeallocFunc<ExitOp>(
-                        modBuilder, builder, operandLocation, globalOp, clause);
-                } else {
-                  createDeclareGlobalOp<mlir::acc::GlobalConstructorOp, EntryOp,
-                                        mlir::acc::DeclareEnterOp, ExitOp>(
-                      modBuilder, builder, operandLocation, globalOp, clause,
-                      declareGlobalCtorName.str(), /*implicit=*/false,
-                      asFortran);
-                }
-                if constexpr (!std::is_same_v<EntryOp, ExitOp>) {
-                  createDeclareGlobalOp<mlir::acc::GlobalDestructorOp,
-                                        mlir::acc::GetDevicePtrOp,
-                                        mlir::acc::DeclareExitOp, ExitOp>(
-                      modBuilder, builder, operandLocation, globalOp, clause,
-                      declareGlobalDtorName.str(), /*implicit=*/false,
-                      asFortran);
-                }
-                builder.restoreInsertionPoint(crtPos);
+                genCtros(operandLocation, *name->symbol);
               }
             },
             [&](const Fortran::parser::Name &name) {
-              TODO(operandLocation, "OpenACC Global Ctor from parser::Name");
+              if (const auto *symbol = name.symbol) {
+                if (const auto *commonBlockDetails =
+                        symbol->detailsIf<
+                            Fortran::semantics::CommonBlockDetails>()) {
+                  genCtros(operandLocation, *symbol);
+                } else {
+                  TODO(operandLocation,
+                       "OpenACC Global Ctor from parser::Name");
+                }
+              }
             }},
         accObject.u);
   }
diff --git a/flang/test/Lower/OpenACC/acc-declare-globals.f90 b/flang/test/Lower/OpenACC/acc-declare-globals.f90
index b64bbbcc0d12f..4556c5f4ddb1c 100644
--- a/flang/test/Lower/OpenACC/acc-declare-globals.f90
+++ b/flang/test/Lower/OpenACC/acc-declare-globals.f90
@@ -3,6 +3,39 @@
 
 ! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
 
+module acc_declare_common_test
+! CHECK-LABEL: fir.global @numbers_ {acc.declare = #acc.declare<dataClause = acc_declare_device_resident>, alignment = 4 : i64} : tuple<f32, f32> {
+! CHECK: acc.global_ctor @numbers__acc_ctor
+! CHECK: acc.global_dtor @numbers__acc_dtor
+ REAL :: one = 1
+ REAL :: two = 2
+ COMMON /numbers/ one, two
+ !$acc declare device_resident(/numbers/)
+
+! CHECK-LABEL: fir.global @numbers_create_ {acc.declare = #acc.declare<dataClause = acc_create>, alignment = 4 : i64} : tuple<f32, f32> {
+! CHECK: acc.global_ctor @numbers_create__acc_ctor
+! CHECK: acc.global_dtor @numbers_create__acc_dtor
+ REAL :: one_create = 1
+ REAL :: two_create = 2
+ COMMON /numbers_create/ one_create, two_create
+ !$acc declare create(/numbers_create/)
+
+! CHECK-LABEL: fir.global @numbers_in_ {acc.declare = #acc.declare<dataClause = acc_copyin>, alignment = 4 : i64} : tuple<f32, f32> {
+! CHECK: acc.global_ctor @numbers_in__acc_ctor
+! CHECK: acc.global_dtor @numbers_in__acc_dtor
+ REAL :: one_in = 1
+ REAL :: two_in = 2
+ COMMON /numbers_in/ one_in, two_in
+ !$acc declare copyin(/numbers_in/)
+
+! CHECK-LABEL: fir.global @numbers_link_ {acc.declare = #acc.declare<dataClause = acc_declare_link>, alignment = 4 : i64} : tuple<f32, f32> {
+! CHECK: acc.global_ctor @numbers_link__acc_ctor
+ REAL :: one_link = 1
+ REAL :: two_link = 2
+ COMMON /numbers_link/ one_link, two_link
+ !$acc declare link(/numbers_link/)
+end module
+
 module acc_declare_test
  integer, parameter :: n = 100000
  real, dimension(n) :: data1

>From 59fce2e559a49ee7cc0df93070b56c37c8d14998 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Mon, 28 Apr 2025 12:11:37 -0700
Subject: [PATCH 2/2] Fix a typo

---
 flang/lib/Lower/OpenACC.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 27e08d4b6f20e..0cccd5eda3c81 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -3754,7 +3754,7 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
                            const Fortran::parser::AccObjectList &accObjectList,
                            mlir::acc::DataClause clause) {
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
-  auto genCtros = [&](const mlir::Location operandLocation,
+  auto genCtors = [&](const mlir::Location operandLocation,
                       const Fortran::semantics::Symbol &symbol) {
     std::string globalName = converter.mangleName(symbol);
     fir::GlobalOp globalOp = builder.getNamedGlobal(globalName);
@@ -3822,7 +3822,7 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
               if (const auto *name =
                       Fortran::semantics::getDesignatorNameIfDataRef(
                           designator)) {
-                genCtros(operandLocation, *name->symbol);
+                genCtors(operandLocation, *name->symbol);
               }
             },
             [&](const Fortran::parser::Name &name) {
@@ -3830,7 +3830,7 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
                 if (const auto *commonBlockDetails =
                         symbol->detailsIf<
                             Fortran::semantics::CommonBlockDetails>()) {
-                  genCtros(operandLocation, *symbol);
+                  genCtors(operandLocation, *symbol);
                 } else {
                   TODO(operandLocation,
                        "OpenACC Global Ctor from parser::Name");



More information about the flang-commits mailing list