[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:10:58 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
@llvm/pr-subscribers-openacc
Author: None (khaki3)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/137691.diff
2 Files Affected:
- (modified) flang/lib/Lower/OpenACC.cpp (+71-67)
- (modified) flang/test/Lower/OpenACC/acc-declare-globals.f90 (+33)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/137691
More information about the flang-commits
mailing list