[flang-commits] [flang] [flang] [cuda] Move SetImplicityCUDADevice after symbols in block construct are converted to objects (PR #143791)
Zhen Wang via flang-commits
flang-commits at lists.llvm.org
Wed Jun 11 19:55:18 PDT 2025
https://github.com/wangzpgi updated https://github.com/llvm/llvm-project/pull/143791
>From a929e62fdc53d8460fddf72bb43a594182740505 Mon Sep 17 00:00:00 2001
From: Zhen Wang <zhenw at nvidia.com>
Date: Wed, 11 Jun 2025 14:23:58 -0700
Subject: [PATCH 1/3] move SetImplicitCUDADevice call after symbols inside
block construct are converted to object
---
flang/lib/Semantics/resolve-names.cpp | 50 ++++++++++++++-------------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 7db447aee0026..63ebcb01b9b96 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -58,6 +58,8 @@ using MessageFormattedText = parser::MessageFormattedText;
class ResolveNamesVisitor;
class ScopeHandler;
+void SetImplicitCUDADevice(bool inDeviceSubprogram, Symbol &symbol);
+
// ImplicitRules maps initial character of identifier to the DeclTypeSpec
// representing the implicit type; std::nullopt if none.
// It also records the presence of IMPLICIT NONE statements.
@@ -2867,8 +2869,31 @@ void ScopeHandler::PopScope() {
// Entities that are not yet classified as objects or procedures are now
// assumed to be objects.
// TODO: Statement functions
+ bool inDeviceSubprogram{false};
+ Symbol *scopeSym{currScope().symbol()};
+ if (currScope().kind() == Scope::Kind::BlockConstruct) {
+ scopeSym = currScope().parent().symbol();
+ }
+ if (scopeSym) {
+ if (auto *details{scopeSym->detailsIf<SubprogramDetails>()}) {
+ // Check the current procedure is a device procedure to apply implicit
+ // attribute at the end.
+ if (auto attrs{details->cudaSubprogramAttrs()}) {
+ if (*attrs == common::CUDASubprogramAttrs::Device ||
+ *attrs == common::CUDASubprogramAttrs::Global ||
+ *attrs == common::CUDASubprogramAttrs::Grid_Global) {
+ inDeviceSubprogram = true;
+ }
+ }
+ }
+ }
for (auto &pair : currScope()) {
ConvertToObjectEntity(*pair.second);
+ if (currScope_->kind() == Scope::Kind::BlockConstruct) {
+ // Only look for specification in BlockConstruct. Other cases are done in
+ // ResolveSpecificationParts.
+ SetImplicitCUDADevice(inDeviceSubprogram, *pair.second);
+ }
}
funcResultStack_.Pop();
// If popping back into a global scope, pop back to the top scope.
@@ -9555,7 +9580,7 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
info.Resolve(&MakeSymbol(symbolName, Attrs{}, std::move(genericDetails)));
}
-static void SetImplicitCUDADevice(bool inDeviceSubprogram, Symbol &symbol) {
+void SetImplicitCUDADevice(bool inDeviceSubprogram, Symbol &symbol) {
if (inDeviceSubprogram && symbol.has<ObjectEntityDetails>()) {
auto *object{symbol.detailsIf<ObjectEntityDetails>()};
if (!object->cudaDataAttr() && !IsValue(symbol) &&
@@ -9571,24 +9596,6 @@ void ResolveNamesVisitor::FinishSpecificationPart(
misparsedStmtFuncFound_ = false;
funcResultStack().CompleteFunctionResultType();
CheckImports();
- bool inDeviceSubprogram{false};
- Symbol *scopeSym{currScope().symbol()};
- if (currScope().kind() == Scope::Kind::BlockConstruct) {
- scopeSym = currScope().parent().symbol();
- }
- if (scopeSym) {
- if (auto *details{scopeSym->detailsIf<SubprogramDetails>()}) {
- // Check the current procedure is a device procedure to apply implicit
- // attribute at the end.
- if (auto attrs{details->cudaSubprogramAttrs()}) {
- if (*attrs == common::CUDASubprogramAttrs::Device ||
- *attrs == common::CUDASubprogramAttrs::Global ||
- *attrs == common::CUDASubprogramAttrs::Grid_Global) {
- inDeviceSubprogram = true;
- }
- }
- }
- }
for (auto &pair : currScope()) {
auto &symbol{*pair.second};
if (inInterfaceBlock()) {
@@ -9623,11 +9630,6 @@ void ResolveNamesVisitor::FinishSpecificationPart(
SetBindNameOn(symbol);
}
}
- if (currScope().kind() == Scope::Kind::BlockConstruct) {
- // Only look for specification in BlockConstruct. Other cases are done in
- // ResolveSpecificationParts.
- SetImplicitCUDADevice(inDeviceSubprogram, symbol);
- }
}
currScope().InstantiateDerivedTypes();
for (const auto &decl : decls) {
>From fa34a6c6fbacba5de046a6b1ae97a599c7bd762d Mon Sep 17 00:00:00 2001
From: Zhen Wang <zhenw at nvidia.com>
Date: Wed, 11 Jun 2025 14:25:58 -0700
Subject: [PATCH 2/3] add test
---
flang/test/Semantics/cuf21.cuf | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/flang/test/Semantics/cuf21.cuf b/flang/test/Semantics/cuf21.cuf
index 077657c8a52d5..db32f1dbd0e7b 100644
--- a/flang/test/Semantics/cuf21.cuf
+++ b/flang/test/Semantics/cuf21.cuf
@@ -13,18 +13,21 @@ contains
implicit none
logical, intent(in), value :: back
real(4) :: mval
-
- call maxlocUpdate(mval, back)
-
+ block
+ integer(8) :: xloc
+ call maxlocUpdate(mval, xloc, back)
+ end block
end subroutine maxlocPartialMaskR_32F1D
- attributes(device) subroutine maxlocUpdateR_32F(mval, back)
+ attributes(device) subroutine maxlocUpdateR_32F(mval, xloc, back)
real(4) :: mval
+ integer(8) :: xloc
logical :: back
end subroutine maxlocUpdateR_32F
- attributes(device) subroutine maxlocUpdateR_64F(mval, back)
+ attributes(device) subroutine maxlocUpdateR_64F(mval, xloc, back)
real(8) :: mval
+ integer(8) :: xloc
logical :: back
end subroutine maxlocUpdateR_64F
end module
>From 2836b7b9e268b1d2fddbc11f9c6be9d8ac024121 Mon Sep 17 00:00:00 2001
From: Zhen Wang <zhenw at nvidia.com>
Date: Wed, 11 Jun 2025 19:52:52 -0700
Subject: [PATCH 3/3] move up definition of SetImplicitCUDADevice
---
flang/lib/Semantics/resolve-names.cpp | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 63ebcb01b9b96..4c6e11380a545 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -58,8 +58,6 @@ using MessageFormattedText = parser::MessageFormattedText;
class ResolveNamesVisitor;
class ScopeHandler;
-void SetImplicitCUDADevice(bool inDeviceSubprogram, Symbol &symbol);
-
// ImplicitRules maps initial character of identifier to the DeclTypeSpec
// representing the implicit type; std::nullopt if none.
// It also records the presence of IMPLICIT NONE statements.
@@ -2830,6 +2828,17 @@ Scope &ScopeHandler::NonDerivedTypeScope() {
return currScope_->IsDerivedType() ? currScope_->parent() : *currScope_;
}
+static void SetImplicitCUDADevice(bool inDeviceSubprogram, Symbol &symbol) {
+ if (inDeviceSubprogram && symbol.has<ObjectEntityDetails>()) {
+ auto *object{symbol.detailsIf<ObjectEntityDetails>()};
+ if (!object->cudaDataAttr() && !IsValue(symbol) &&
+ !IsFunctionResult(symbol)) {
+ // Implicitly set device attribute if none is set in device context.
+ object->set_cudaDataAttr(common::CUDADataAttr::Device);
+ }
+ }
+}
+
void ScopeHandler::PushScope(Scope::Kind kind, Symbol *symbol) {
PushScope(currScope().MakeScope(kind, symbol));
}
@@ -9580,17 +9589,6 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
info.Resolve(&MakeSymbol(symbolName, Attrs{}, std::move(genericDetails)));
}
-void SetImplicitCUDADevice(bool inDeviceSubprogram, Symbol &symbol) {
- if (inDeviceSubprogram && symbol.has<ObjectEntityDetails>()) {
- auto *object{symbol.detailsIf<ObjectEntityDetails>()};
- if (!object->cudaDataAttr() && !IsValue(symbol) &&
- !IsFunctionResult(symbol)) {
- // Implicitly set device attribute if none is set in device context.
- object->set_cudaDataAttr(common::CUDADataAttr::Device);
- }
- }
-}
-
void ResolveNamesVisitor::FinishSpecificationPart(
const std::list<parser::DeclarationConstruct> &decls) {
misparsedStmtFuncFound_ = false;
More information about the flang-commits
mailing list