@@ -1087,6 +1087,52 @@ std::optional<common::CUDADataAttr> GetCUDADataAttr(const Symbol *symbol) {
1087
1087
return object ? object->cudaDataAttr () : std::nullopt ;
1088
1088
}
1089
1089
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
+
1090
1136
bool IsAccessible (const Symbol &original, const Scope &scope) {
1091
1137
const Symbol &ultimate{original.GetUltimate ()};
1092
1138
if (ultimate.attrs ().test (Attr::PRIVATE)) {
@@ -1788,4 +1834,4 @@ bool HadUseError(
1788
1834
}
1789
1835
}
1790
1836
1791
- } // namespace Fortran::semantics
1837
+ } // namespace Fortran::semantics
0 commit comments