Skip to content

Commit dd2a159

Browse files
authored
[flang][acc] Generate constructors and destructors for common blocks (#137691)
1 parent bdfa1ec commit dd2a159

File tree

2 files changed

+104
-67
lines changed

2 files changed

+104
-67
lines changed

flang/lib/Lower/OpenACC.cpp

Lines changed: 71 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4058,6 +4058,66 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
40584058
const Fortran::parser::AccObjectList &accObjectList,
40594059
mlir::acc::DataClause clause) {
40604060
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
4061+
auto genCtors = [&](const mlir::Location operandLocation,
4062+
const Fortran::semantics::Symbol &symbol) {
4063+
std::string globalName = converter.mangleName(symbol);
4064+
fir::GlobalOp globalOp = builder.getNamedGlobal(globalName);
4065+
std::stringstream declareGlobalCtorName;
4066+
declareGlobalCtorName << globalName << "_acc_ctor";
4067+
std::stringstream declareGlobalDtorName;
4068+
declareGlobalDtorName << globalName << "_acc_dtor";
4069+
std::stringstream asFortran;
4070+
asFortran << symbol.name().ToString();
4071+
4072+
if (builder.getModule().lookupSymbol<mlir::acc::GlobalConstructorOp>(
4073+
declareGlobalCtorName.str()))
4074+
return;
4075+
4076+
if (!globalOp) {
4077+
if (Fortran::semantics::FindEquivalenceSet(symbol)) {
4078+
for (Fortran::semantics::EquivalenceObject eqObj :
4079+
*Fortran::semantics::FindEquivalenceSet(symbol)) {
4080+
std::string eqName = converter.mangleName(eqObj.symbol);
4081+
globalOp = builder.getNamedGlobal(eqName);
4082+
if (globalOp)
4083+
break;
4084+
}
4085+
4086+
if (!globalOp)
4087+
llvm::report_fatal_error("could not retrieve global symbol");
4088+
} else {
4089+
llvm::report_fatal_error("could not retrieve global symbol");
4090+
}
4091+
}
4092+
4093+
addDeclareAttr(builder, globalOp.getOperation(), clause);
4094+
auto crtPos = builder.saveInsertionPoint();
4095+
modBuilder.setInsertionPointAfter(globalOp);
4096+
if (mlir::isa<fir::BaseBoxType>(fir::unwrapRefType(globalOp.getType()))) {
4097+
createDeclareGlobalOp<mlir::acc::GlobalConstructorOp, mlir::acc::CopyinOp,
4098+
mlir::acc::DeclareEnterOp, ExitOp>(
4099+
modBuilder, builder, operandLocation, globalOp, clause,
4100+
declareGlobalCtorName.str(), /*implicit=*/true, asFortran);
4101+
createDeclareAllocFunc<EntryOp>(modBuilder, builder, operandLocation,
4102+
globalOp, clause);
4103+
if constexpr (!std::is_same_v<EntryOp, ExitOp>)
4104+
createDeclareDeallocFunc<ExitOp>(modBuilder, builder, operandLocation,
4105+
globalOp, clause);
4106+
} else {
4107+
createDeclareGlobalOp<mlir::acc::GlobalConstructorOp, EntryOp,
4108+
mlir::acc::DeclareEnterOp, ExitOp>(
4109+
modBuilder, builder, operandLocation, globalOp, clause,
4110+
declareGlobalCtorName.str(), /*implicit=*/false, asFortran);
4111+
}
4112+
if constexpr (!std::is_same_v<EntryOp, ExitOp>) {
4113+
createDeclareGlobalOp<mlir::acc::GlobalDestructorOp,
4114+
mlir::acc::GetDevicePtrOp, mlir::acc::DeclareExitOp,
4115+
ExitOp>(
4116+
modBuilder, builder, operandLocation, globalOp, clause,
4117+
declareGlobalDtorName.str(), /*implicit=*/false, asFortran);
4118+
}
4119+
builder.restoreInsertionPoint(crtPos);
4120+
};
40614121
for (const auto &accObject : accObjectList.v) {
40624122
mlir::Location operandLocation = genOperandLocation(converter, accObject);
40634123
Fortran::common::visit(
@@ -4066,76 +4126,20 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
40664126
if (const auto *name =
40674127
Fortran::semantics::getDesignatorNameIfDataRef(
40684128
designator)) {
4069-
std::string globalName = converter.mangleName(*name->symbol);
4070-
fir::GlobalOp globalOp = builder.getNamedGlobal(globalName);
4071-
std::stringstream declareGlobalCtorName;
4072-
declareGlobalCtorName << globalName << "_acc_ctor";
4073-
std::stringstream declareGlobalDtorName;
4074-
declareGlobalDtorName << globalName << "_acc_dtor";
4075-
std::stringstream asFortran;
4076-
asFortran << name->symbol->name().ToString();
4077-
4078-
if (builder.getModule()
4079-
.lookupSymbol<mlir::acc::GlobalConstructorOp>(
4080-
declareGlobalCtorName.str()))
4081-
return;
4082-
4083-
if (!globalOp) {
4084-
if (Fortran::semantics::FindEquivalenceSet(*name->symbol)) {
4085-
for (Fortran::semantics::EquivalenceObject eqObj :
4086-
*Fortran::semantics::FindEquivalenceSet(
4087-
*name->symbol)) {
4088-
std::string eqName = converter.mangleName(eqObj.symbol);
4089-
globalOp = builder.getNamedGlobal(eqName);
4090-
if (globalOp)
4091-
break;
4092-
}
4093-
4094-
if (!globalOp)
4095-
llvm::report_fatal_error(
4096-
"could not retrieve global symbol");
4097-
} else {
4098-
llvm::report_fatal_error(
4099-
"could not retrieve global symbol");
4100-
}
4101-
}
4102-
4103-
addDeclareAttr(builder, globalOp.getOperation(), clause);
4104-
auto crtPos = builder.saveInsertionPoint();
4105-
modBuilder.setInsertionPointAfter(globalOp);
4106-
if (mlir::isa<fir::BaseBoxType>(
4107-
fir::unwrapRefType(globalOp.getType()))) {
4108-
createDeclareGlobalOp<mlir::acc::GlobalConstructorOp,
4109-
mlir::acc::CopyinOp,
4110-
mlir::acc::DeclareEnterOp, ExitOp>(
4111-
modBuilder, builder, operandLocation, globalOp, clause,
4112-
declareGlobalCtorName.str(), /*implicit=*/true,
4113-
asFortran);
4114-
createDeclareAllocFunc<EntryOp>(
4115-
modBuilder, builder, operandLocation, globalOp, clause);
4116-
if constexpr (!std::is_same_v<EntryOp, ExitOp>)
4117-
createDeclareDeallocFunc<ExitOp>(
4118-
modBuilder, builder, operandLocation, globalOp, clause);
4119-
} else {
4120-
createDeclareGlobalOp<mlir::acc::GlobalConstructorOp, EntryOp,
4121-
mlir::acc::DeclareEnterOp, ExitOp>(
4122-
modBuilder, builder, operandLocation, globalOp, clause,
4123-
declareGlobalCtorName.str(), /*implicit=*/false,
4124-
asFortran);
4125-
}
4126-
if constexpr (!std::is_same_v<EntryOp, ExitOp>) {
4127-
createDeclareGlobalOp<mlir::acc::GlobalDestructorOp,
4128-
mlir::acc::GetDevicePtrOp,
4129-
mlir::acc::DeclareExitOp, ExitOp>(
4130-
modBuilder, builder, operandLocation, globalOp, clause,
4131-
declareGlobalDtorName.str(), /*implicit=*/false,
4132-
asFortran);
4133-
}
4134-
builder.restoreInsertionPoint(crtPos);
4129+
genCtors(operandLocation, *name->symbol);
41354130
}
41364131
},
41374132
[&](const Fortran::parser::Name &name) {
4138-
TODO(operandLocation, "OpenACC Global Ctor from parser::Name");
4133+
if (const auto *symbol = name.symbol) {
4134+
if (const auto *commonBlockDetails =
4135+
symbol->detailsIf<
4136+
Fortran::semantics::CommonBlockDetails>()) {
4137+
genCtors(operandLocation, *symbol);
4138+
} else {
4139+
TODO(operandLocation,
4140+
"OpenACC Global Ctor from parser::Name");
4141+
}
4142+
}
41394143
}},
41404144
accObject.u);
41414145
}

flang/test/Lower/OpenACC/acc-declare-globals.f90

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,39 @@
33

44
! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
55

6+
module acc_declare_common_test
7+
! CHECK-LABEL: fir.global @numbers_ {acc.declare = #acc.declare<dataClause = acc_declare_device_resident>, alignment = 4 : i64} : tuple<f32, f32> {
8+
! CHECK: acc.global_ctor @numbers__acc_ctor
9+
! CHECK: acc.global_dtor @numbers__acc_dtor
10+
REAL :: one = 1
11+
REAL :: two = 2
12+
COMMON /numbers/ one, two
13+
!$acc declare device_resident(/numbers/)
14+
15+
! CHECK-LABEL: fir.global @numbers_create_ {acc.declare = #acc.declare<dataClause = acc_create>, alignment = 4 : i64} : tuple<f32, f32> {
16+
! CHECK: acc.global_ctor @numbers_create__acc_ctor
17+
! CHECK: acc.global_dtor @numbers_create__acc_dtor
18+
REAL :: one_create = 1
19+
REAL :: two_create = 2
20+
COMMON /numbers_create/ one_create, two_create
21+
!$acc declare create(/numbers_create/)
22+
23+
! CHECK-LABEL: fir.global @numbers_in_ {acc.declare = #acc.declare<dataClause = acc_copyin>, alignment = 4 : i64} : tuple<f32, f32> {
24+
! CHECK: acc.global_ctor @numbers_in__acc_ctor
25+
! CHECK: acc.global_dtor @numbers_in__acc_dtor
26+
REAL :: one_in = 1
27+
REAL :: two_in = 2
28+
COMMON /numbers_in/ one_in, two_in
29+
!$acc declare copyin(/numbers_in/)
30+
31+
! CHECK-LABEL: fir.global @numbers_link_ {acc.declare = #acc.declare<dataClause = acc_declare_link>, alignment = 4 : i64} : tuple<f32, f32> {
32+
! CHECK: acc.global_ctor @numbers_link__acc_ctor
33+
REAL :: one_link = 1
34+
REAL :: two_link = 2
35+
COMMON /numbers_link/ one_link, two_link
36+
!$acc declare link(/numbers_link/)
37+
end module
38+
639
module acc_declare_test
740
integer, parameter :: n = 100000
841
real, dimension(n) :: data1

0 commit comments

Comments
 (0)