Skip to content

Commit 07cc7ea

Browse files
authored
Reland [flang][cuda] Do not create global for derived-type with allocatable device components (#147402)
Reviewed in #146780 derived type with CUDA device allocatable components will be handle via CUDA allocation. Do not create global for them.
1 parent 4946db1 commit 07cc7ea

File tree

6 files changed

+76
-21
lines changed

6 files changed

+76
-21
lines changed

flang/include/flang/Evaluate/tools.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,17 +1286,6 @@ bool CheckForCoindexedObject(parser::ContextualMessages &,
12861286
const std::optional<ActualArgument> &, const std::string &procName,
12871287
const std::string &argName);
12881288

1289-
inline bool CanCUDASymbolHaveSaveAttr(const Symbol &sym) {
1290-
if (const auto *details =
1291-
sym.GetUltimate().detailsIf<semantics::ObjectEntityDetails>()) {
1292-
if (details->cudaDataAttr() &&
1293-
*details->cudaDataAttr() != common::CUDADataAttr::Unified) {
1294-
return false;
1295-
}
1296-
}
1297-
return true;
1298-
}
1299-
13001289
inline bool IsCUDADeviceSymbol(const Symbol &sym) {
13011290
if (const auto *details =
13021291
sym.GetUltimate().detailsIf<semantics::ObjectEntityDetails>()) {

flang/include/flang/Semantics/tools.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ inline bool NeedCUDAAlloc(const Symbol &sym) {
248248
return false;
249249
}
250250

251+
bool CanCUDASymbolBeGlobal(const Symbol &sym);
252+
251253
const Scope *FindCUDADeviceContext(const Scope *);
252254
std::optional<common::CUDADataAttr> GetCUDADataAttr(const Symbol *);
253255

flang/lib/Evaluate/tools.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2194,8 +2194,7 @@ bool IsSaved(const Symbol &original) {
21942194
return false;
21952195
} else if (scopeKind == Scope::Kind::Module ||
21962196
(scopeKind == Scope::Kind::MainProgram &&
2197-
(symbol.attrs().test(Attr::TARGET) || evaluate::IsCoarray(symbol)) &&
2198-
Fortran::evaluate::CanCUDASymbolHaveSaveAttr(symbol))) {
2197+
(symbol.attrs().test(Attr::TARGET) || evaluate::IsCoarray(symbol)))) {
21992198
// 8.5.16p4
22002199
// In main programs, implied SAVE matters only for pointer
22012200
// initialization targets and coarrays.
@@ -2204,8 +2203,7 @@ bool IsSaved(const Symbol &original) {
22042203
(features.IsEnabled(common::LanguageFeature::SaveMainProgram) ||
22052204
(features.IsEnabled(
22062205
common::LanguageFeature::SaveBigMainProgramVariables) &&
2207-
symbol.size() > 32)) &&
2208-
Fortran::evaluate::CanCUDASymbolHaveSaveAttr(symbol)) {
2206+
symbol.size() > 32))) {
22092207
// With SaveBigMainProgramVariables, keeping all unsaved main program
22102208
// variables of 32 bytes or less on the stack allows keeping numerical and
22112209
// logical scalars, small scalar characters or derived, small arrays, and
@@ -2223,15 +2221,15 @@ bool IsSaved(const Symbol &original) {
22232221
} else if (symbol.test(Symbol::Flag::InDataStmt)) {
22242222
return true;
22252223
} else if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()};
2226-
object && object->init()) {
2224+
object && object->init()) {
22272225
return true;
22282226
} else if (IsProcedurePointer(symbol) && symbol.has<ProcEntityDetails>() &&
22292227
symbol.get<ProcEntityDetails>().init()) {
22302228
return true;
22312229
} else if (scope.hasSAVE()) {
22322230
return true; // bare SAVE statement
2233-
} else if (const Symbol * block{FindCommonBlockContaining(symbol)};
2234-
block && block->attrs().test(Attr::SAVE)) {
2231+
} else if (const Symbol *block{FindCommonBlockContaining(symbol)};
2232+
block && block->attrs().test(Attr::SAVE)) {
22352233
return true; // in COMMON with SAVE
22362234
} else {
22372235
return false;

flang/lib/Lower/PFTBuilder.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,8 +1472,8 @@ bool Fortran::lower::definedInCommonBlock(const semantics::Symbol &sym) {
14721472

14731473
/// Is the symbol `sym` a global?
14741474
bool Fortran::lower::symbolIsGlobal(const semantics::Symbol &sym) {
1475-
return semantics::IsSaved(sym) || lower::definedInCommonBlock(sym) ||
1476-
semantics::IsNamedConstant(sym);
1475+
return (semantics::IsSaved(sym) && semantics::CanCUDASymbolBeGlobal(sym)) ||
1476+
lower::definedInCommonBlock(sym) || semantics::IsNamedConstant(sym);
14771477
}
14781478

14791479
namespace {

flang/lib/Semantics/tools.cpp

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,52 @@ std::optional<common::CUDADataAttr> GetCUDADataAttr(const Symbol *symbol) {
10871087
return object ? object->cudaDataAttr() : std::nullopt;
10881088
}
10891089

1090+
bool IsDeviceAllocatable(const Symbol &symbol) {
1091+
if (IsAllocatable(symbol)) {
1092+
if (const auto *details{
1093+
symbol.GetUltimate().detailsIf<semantics::ObjectEntityDetails>()}) {
1094+
if (details->cudaDataAttr() &&
1095+
*details->cudaDataAttr() != common::CUDADataAttr::Pinned) {
1096+
return true;
1097+
}
1098+
}
1099+
}
1100+
return false;
1101+
}
1102+
1103+
UltimateComponentIterator::const_iterator
1104+
FindCUDADeviceAllocatableUltimateComponent(const DerivedTypeSpec &derived) {
1105+
UltimateComponentIterator ultimates{derived};
1106+
return std::find_if(ultimates.begin(), ultimates.end(), IsDeviceAllocatable);
1107+
}
1108+
1109+
bool CanCUDASymbolBeGlobal(const Symbol &sym) {
1110+
const Symbol &symbol{GetAssociationRoot(sym)};
1111+
const Scope &scope{symbol.owner()};
1112+
auto scopeKind{scope.kind()};
1113+
const common::LanguageFeatureControl &features{
1114+
scope.context().languageFeatures()};
1115+
if (features.IsEnabled(common::LanguageFeature::CUDA) &&
1116+
scopeKind == Scope::Kind::MainProgram) {
1117+
if (const auto *details{
1118+
sym.GetUltimate().detailsIf<semantics::ObjectEntityDetails>()}) {
1119+
const Fortran::semantics::DeclTypeSpec *type{details->type()};
1120+
const Fortran::semantics::DerivedTypeSpec *derived{
1121+
type ? type->AsDerived() : nullptr};
1122+
if (derived) {
1123+
if (FindCUDADeviceAllocatableUltimateComponent(*derived)) {
1124+
return false;
1125+
}
1126+
}
1127+
if (details->cudaDataAttr() &&
1128+
*details->cudaDataAttr() != common::CUDADataAttr::Unified) {
1129+
return false;
1130+
}
1131+
}
1132+
}
1133+
return true;
1134+
}
1135+
10901136
bool IsAccessible(const Symbol &original, const Scope &scope) {
10911137
const Symbol &ultimate{original.GetUltimate()};
10921138
if (ultimate.attrs().test(Attr::PRIVATE)) {
@@ -1788,4 +1834,4 @@ bool HadUseError(
17881834
}
17891835
}
17901836

1791-
} // namespace Fortran::semantics
1837+
} // namespace Fortran::semantics
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
! RUN: bbc -emit-hlfir -fcuda %s -o - | FileCheck %s
2+
3+
module m1
4+
type ty_device
5+
integer, device, allocatable, dimension(:) :: x
6+
end type
7+
8+
type t1; real, device, allocatable :: a(:); end type
9+
type t2; type(t1) :: b; end type
10+
end module
11+
12+
program main
13+
use m1
14+
type(ty_device) :: a
15+
type(t2) :: b
16+
end
17+
18+
! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "main"}
19+
! CHECK: %{{.*}} = fir.alloca !fir.type<_QMm1Tty_device{x:!fir.box<!fir.heap<!fir.array<?xi32>>>}> {bindc_name = "a", uniq_name = "_QFEa"}
20+
! CHECK: %{{.*}} = fir.alloca !fir.type<_QMm1Tt2{b:!fir.type<_QMm1Tt1{a:!fir.box<!fir.heap<!fir.array<?xf32>>>}>}> {bindc_name = "b", uniq_name = "_QFEb"}

0 commit comments

Comments
 (0)