Skip to content

Commit 3ddd137

Browse files
authored
[flang] [cuda] Move SetImplicityCUDADevice after symbols in block construct are converted to objects (#143791)
`SetImplicitCUDADevice` looks for `symbol.has<ObjectEntityDetails>()` to set the device attribute before symbols inside block constructs are converted to ObjectEntity. Fix is to move the call to `SetImplicitCUDADevice` after those symbols are converted.
1 parent e1bb35d commit 3ddd137

File tree

2 files changed

+47
-40
lines changed

2 files changed

+47
-40
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,6 +2828,16 @@ Scope &ScopeHandler::NonDerivedTypeScope() {
28282828
return currScope_->IsDerivedType() ? currScope_->parent() : *currScope_;
28292829
}
28302830

2831+
static void SetImplicitCUDADevice(Symbol &symbol) {
2832+
if (auto *object{symbol.detailsIf<ObjectEntityDetails>()}) {
2833+
if (!object->cudaDataAttr() && !IsValue(symbol) &&
2834+
!IsFunctionResult(symbol)) {
2835+
// Implicitly set device attribute if none is set in device context.
2836+
object->set_cudaDataAttr(common::CUDADataAttr::Device);
2837+
}
2838+
}
2839+
}
2840+
28312841
void ScopeHandler::PushScope(Scope::Kind kind, Symbol *symbol) {
28322842
PushScope(currScope().MakeScope(kind, symbol));
28332843
}
@@ -2867,9 +2877,35 @@ void ScopeHandler::PopScope() {
28672877
// Entities that are not yet classified as objects or procedures are now
28682878
// assumed to be objects.
28692879
// TODO: Statement functions
2880+
bool inDeviceSubprogram{false};
2881+
const Symbol *scopeSym{currScope().GetSymbol()};
2882+
if (currScope().kind() == Scope::Kind::BlockConstruct) {
2883+
scopeSym = GetProgramUnitContaining(currScope()).GetSymbol();
2884+
}
2885+
if (scopeSym) {
2886+
if (auto *details{scopeSym->detailsIf<SubprogramDetails>()}) {
2887+
// Check the current procedure is a device procedure to apply implicit
2888+
// attribute at the end.
2889+
if (auto attrs{details->cudaSubprogramAttrs()}) {
2890+
if (*attrs == common::CUDASubprogramAttrs::Device ||
2891+
*attrs == common::CUDASubprogramAttrs::Global ||
2892+
*attrs == common::CUDASubprogramAttrs::Grid_Global) {
2893+
inDeviceSubprogram = true;
2894+
}
2895+
}
2896+
}
2897+
}
28702898
for (auto &pair : currScope()) {
28712899
ConvertToObjectEntity(*pair.second);
28722900
}
2901+
2902+
// Apply CUDA device attributes if in a device subprogram
2903+
if (inDeviceSubprogram && currScope().kind() == Scope::Kind::BlockConstruct) {
2904+
for (auto &pair : currScope()) {
2905+
SetImplicitCUDADevice(*pair.second);
2906+
}
2907+
}
2908+
28732909
funcResultStack_.Pop();
28742910
// If popping back into a global scope, pop back to the top scope.
28752911
Scope *hermetic{context().currentHermeticModuleFileScope()};
@@ -9555,40 +9591,11 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
95559591
info.Resolve(&MakeSymbol(symbolName, Attrs{}, std::move(genericDetails)));
95569592
}
95579593

9558-
static void SetImplicitCUDADevice(bool inDeviceSubprogram, Symbol &symbol) {
9559-
if (inDeviceSubprogram && symbol.has<ObjectEntityDetails>()) {
9560-
auto *object{symbol.detailsIf<ObjectEntityDetails>()};
9561-
if (!object->cudaDataAttr() && !IsValue(symbol) &&
9562-
!IsFunctionResult(symbol)) {
9563-
// Implicitly set device attribute if none is set in device context.
9564-
object->set_cudaDataAttr(common::CUDADataAttr::Device);
9565-
}
9566-
}
9567-
}
9568-
95699594
void ResolveNamesVisitor::FinishSpecificationPart(
95709595
const std::list<parser::DeclarationConstruct> &decls) {
95719596
misparsedStmtFuncFound_ = false;
95729597
funcResultStack().CompleteFunctionResultType();
95739598
CheckImports();
9574-
bool inDeviceSubprogram{false};
9575-
Symbol *scopeSym{currScope().symbol()};
9576-
if (currScope().kind() == Scope::Kind::BlockConstruct) {
9577-
scopeSym = currScope().parent().symbol();
9578-
}
9579-
if (scopeSym) {
9580-
if (auto *details{scopeSym->detailsIf<SubprogramDetails>()}) {
9581-
// Check the current procedure is a device procedure to apply implicit
9582-
// attribute at the end.
9583-
if (auto attrs{details->cudaSubprogramAttrs()}) {
9584-
if (*attrs == common::CUDASubprogramAttrs::Device ||
9585-
*attrs == common::CUDASubprogramAttrs::Global ||
9586-
*attrs == common::CUDASubprogramAttrs::Grid_Global) {
9587-
inDeviceSubprogram = true;
9588-
}
9589-
}
9590-
}
9591-
}
95929599
for (auto &pair : currScope()) {
95939600
auto &symbol{*pair.second};
95949601
if (inInterfaceBlock()) {
@@ -9623,11 +9630,6 @@ void ResolveNamesVisitor::FinishSpecificationPart(
96239630
SetBindNameOn(symbol);
96249631
}
96259632
}
9626-
if (currScope().kind() == Scope::Kind::BlockConstruct) {
9627-
// Only look for specification in BlockConstruct. Other cases are done in
9628-
// ResolveSpecificationParts.
9629-
SetImplicitCUDADevice(inDeviceSubprogram, symbol);
9630-
}
96319633
}
96329634
currScope().InstantiateDerivedTypes();
96339635
for (const auto &decl : decls) {
@@ -10187,7 +10189,9 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
1018710189
}
1018810190
ApplyImplicitRules(symbol);
1018910191
// Apply CUDA implicit attributes if needed.
10190-
SetImplicitCUDADevice(inDeviceSubprogram, symbol);
10192+
if (inDeviceSubprogram) {
10193+
SetImplicitCUDADevice(symbol);
10194+
}
1019110195
// Main program local objects usually don't have an implied SAVE attribute,
1019210196
// as one might think, but in the exceptional case of a derived type
1019310197
// local object that contains a coarray, we have to mark it as an

flang/test/Semantics/cuf21.cuf

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,21 @@ contains
1313
implicit none
1414
logical, intent(in), value :: back
1515
real(4) :: mval
16-
17-
call maxlocUpdate(mval, back)
18-
16+
block
17+
integer(8) :: xloc
18+
call maxlocUpdate(mval, xloc, back)
19+
end block
1920
end subroutine maxlocPartialMaskR_32F1D
2021

21-
attributes(device) subroutine maxlocUpdateR_32F(mval, back)
22+
attributes(device) subroutine maxlocUpdateR_32F(mval, xloc, back)
2223
real(4) :: mval
24+
integer(8) :: xloc
2325
logical :: back
2426
end subroutine maxlocUpdateR_32F
2527

26-
attributes(device) subroutine maxlocUpdateR_64F(mval, back)
28+
attributes(device) subroutine maxlocUpdateR_64F(mval, xloc, back)
2729
real(8) :: mval
30+
integer(8) :: xloc
2831
logical :: back
2932
end subroutine maxlocUpdateR_64F
3033
end module

0 commit comments

Comments
 (0)