-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[flang][cuda] Do not create global for derived-type with allocatable device components #146780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…device components
@llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-flang-semantics Author: Valentin Clement (バレンタイン クレメン) (clementval) Changesderived type with CUDA device allocatable components will be handle via CUDA allocation. Do not create global for them. Full diff: https://github.com/llvm/llvm-project/pull/146780.diff 5 Files Affected:
diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index cad1b634f8924..814fe4cccede6 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -1286,16 +1286,7 @@ bool CheckForCoindexedObject(parser::ContextualMessages &,
const std::optional<ActualArgument> &, const std::string &procName,
const std::string &argName);
-inline bool CanCUDASymbolHaveSaveAttr(const Symbol &sym) {
- if (const auto *details =
- sym.GetUltimate().detailsIf<semantics::ObjectEntityDetails>()) {
- if (details->cudaDataAttr() &&
- *details->cudaDataAttr() != common::CUDADataAttr::Unified) {
- return false;
- }
- }
- return true;
-}
+bool CanCUDASymbolHaveSaveAttr(const Symbol &sym);
inline bool IsCUDADeviceSymbol(const Symbol &sym) {
if (const auto *details =
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index f3cfa9b99fb4d..ca58e1065d3e5 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -654,6 +654,8 @@ DirectComponentIterator::const_iterator FindAllocatableOrPointerDirectComponent(
const DerivedTypeSpec &);
PotentialComponentIterator::const_iterator
FindPolymorphicAllocatablePotentialComponent(const DerivedTypeSpec &);
+UltimateComponentIterator::const_iterator
+FindCUDADeviceAllocatableUltimateComponent(const DerivedTypeSpec &);
// The LabelEnforce class (given a set of labels) provides an error message if
// there is a branch to a label which is not in the given set.
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index fcacdb93d662b..7e5061d3cb2f5 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -2173,6 +2173,25 @@ bool IsAutomatic(const Symbol &original) {
return false;
}
+bool CanCUDASymbolHaveSaveAttr(const Symbol &sym) {
+ if (const auto *details =
+ sym.GetUltimate().detailsIf<semantics::ObjectEntityDetails>()) {
+ const Fortran::semantics::DeclTypeSpec *type{details->type()};
+ const Fortran::semantics::DerivedTypeSpec *derived{
+ type ? type->AsDerived() : nullptr};
+ if (derived) {
+ if (auto iter{FindCUDADeviceAllocatableUltimateComponent(*derived)}) {
+ return false;
+ }
+ }
+ if (details->cudaDataAttr() &&
+ *details->cudaDataAttr() != common::CUDADataAttr::Unified) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool IsSaved(const Symbol &original) {
const Symbol &symbol{GetAssociationRoot(original)};
const Scope &scope{symbol.owner()};
@@ -2195,7 +2214,7 @@ bool IsSaved(const Symbol &original) {
} else if (scopeKind == Scope::Kind::Module ||
(scopeKind == Scope::Kind::MainProgram &&
(symbol.attrs().test(Attr::TARGET) || evaluate::IsCoarray(symbol)) &&
- Fortran::evaluate::CanCUDASymbolHaveSaveAttr(symbol))) {
+ CanCUDASymbolHaveSaveAttr(symbol))) {
// 8.5.16p4
// In main programs, implied SAVE matters only for pointer
// initialization targets and coarrays.
@@ -2205,7 +2224,7 @@ bool IsSaved(const Symbol &original) {
(features.IsEnabled(
common::LanguageFeature::SaveBigMainProgramVariables) &&
symbol.size() > 32)) &&
- Fortran::evaluate::CanCUDASymbolHaveSaveAttr(symbol)) {
+ CanCUDASymbolHaveSaveAttr(symbol)) {
// With SaveBigMainProgramVariables, keeping all unsaved main program
// variables of 32 bytes or less on the stack allows keeping numerical and
// logical scalars, small scalar characters or derived, small arrays, and
@@ -2223,15 +2242,15 @@ bool IsSaved(const Symbol &original) {
} else if (symbol.test(Symbol::Flag::InDataStmt)) {
return true;
} else if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()};
- object && object->init()) {
+ object && object->init()) {
return true;
} else if (IsProcedurePointer(symbol) && symbol.has<ProcEntityDetails>() &&
symbol.get<ProcEntityDetails>().init()) {
return true;
} else if (scope.hasSAVE()) {
return true; // bare SAVE statement
- } else if (const Symbol * block{FindCommonBlockContaining(symbol)};
- block && block->attrs().test(Attr::SAVE)) {
+ } else if (const Symbol *block{FindCommonBlockContaining(symbol)};
+ block && block->attrs().test(Attr::SAVE)) {
return true; // in COMMON with SAVE
} else {
return false;
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index d053179448c00..4b1d1b170816d 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -1081,6 +1081,19 @@ const Scope *FindCUDADeviceContext(const Scope *scope) {
});
}
+bool IsDeviceAllocatable(const Symbol &symbol) {
+ if (IsAllocatable(symbol)) {
+ if (const auto *details =
+ symbol.GetUltimate().detailsIf<semantics::ObjectEntityDetails>()) {
+ if (details->cudaDataAttr() &&
+ *details->cudaDataAttr() != common::CUDADataAttr::Pinned) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
std::optional<common::CUDADataAttr> GetCUDADataAttr(const Symbol *symbol) {
const auto *object{
symbol ? symbol->detailsIf<ObjectEntityDetails>() : nullptr};
@@ -1426,6 +1439,12 @@ FindPolymorphicAllocatablePotentialComponent(const DerivedTypeSpec &derived) {
potentials.begin(), potentials.end(), IsPolymorphicAllocatable);
}
+UltimateComponentIterator::const_iterator
+FindCUDADeviceAllocatableUltimateComponent(const DerivedTypeSpec &derived) {
+ UltimateComponentIterator ultimates{derived};
+ return std::find_if(ultimates.begin(), ultimates.end(), IsDeviceAllocatable);
+}
+
const Symbol *FindUltimateComponent(const DerivedTypeSpec &derived,
const std::function<bool(const Symbol &)> &predicate) {
UltimateComponentIterator ultimates{derived};
@@ -1788,4 +1807,4 @@ bool HadUseError(
}
}
-} // namespace Fortran::semantics
\ No newline at end of file
+} // namespace Fortran::semantics
diff --git a/flang/test/Lower/CUDA/cuda-derived.cuf b/flang/test/Lower/CUDA/cuda-derived.cuf
new file mode 100644
index 0000000000000..670dd1b10896a
--- /dev/null
+++ b/flang/test/Lower/CUDA/cuda-derived.cuf
@@ -0,0 +1,15 @@
+! RUN: bbc -emit-hlfir -fcuda %s -o - | FileCheck %s
+
+module m1
+ type ty_device
+ integer, device, allocatable, dimension(:) :: x
+ end type
+end module
+
+program main
+ use m1
+ type(ty_device) :: a
+end
+
+! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "main"}
+! CHECK: %{{.*}} = fir.alloca !fir.type<_QMm1Tty_device{x:!fir.box<!fir.heap<!fir.array<?xi32>>>}> {bindc_name = "a", uniq_name = "_QFEa"}
|
9ca53db
to
2578891
Compare
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/204/builds/14222 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/203/builds/15409 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/205/builds/14199 Here is the relevant piece of the build log for the reference
|
derived type with CUDA device allocatable components will be handle via CUDA allocation. Do not create global for them.