@@ -2217,6 +2217,20 @@ static bool IsPrivatizable(const Symbol *sym) {
22172217 misc->kind () != MiscDetails::Kind::ConstructName));
22182218}
22192219
2220+ static bool IsSymbolStaticStorageDuration (const Symbol &symbol) {
2221+ LLVM_DEBUG (llvm::dbgs () << " IsSymbolStaticStorageDuration(" << symbol.name ()
2222+ << " ):\n " );
2223+ auto ultSym = symbol.GetUltimate ();
2224+ // Module-scope variable
2225+ return (ultSym.owner ().kind () == Scope::Kind::Module) ||
2226+ // Data statement variable
2227+ (ultSym.flags ().test (Symbol::Flag::InDataStmt)) ||
2228+ // Save attribute variable
2229+ (ultSym.attrs ().test (Attr::SAVE)) ||
2230+ // Referenced in a common block
2231+ (ultSym.flags ().test (Symbol::Flag::InCommonBlock));
2232+ }
2233+
22202234void OmpAttributeVisitor::CreateImplicitSymbols (const Symbol *symbol) {
22212235 if (!IsPrivatizable (symbol)) {
22222236 return ;
@@ -2310,6 +2324,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(const Symbol *symbol) {
23102324 bool targetDir = llvm::omp::allTargetSet.test (dirContext.directive );
23112325 bool parallelDir = llvm::omp::allParallelSet.test (dirContext.directive );
23122326 bool teamsDir = llvm::omp::allTeamsSet.test (dirContext.directive );
2327+ bool isStaticStorageDuration = IsSymbolStaticStorageDuration (*symbol);
23132328
23142329 if (dsa.any ()) {
23152330 if (parallelDir || taskGenDir || teamsDir) {
@@ -2367,7 +2382,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(const Symbol *symbol) {
23672382 dsa = prevDSA;
23682383 } else if (taskGenDir) {
23692384 // TODO 5) dummy arg in orphaned taskgen construct -> firstprivate
2370- if (prevDSA.test (Symbol::Flag::OmpShared)) {
2385+ if (prevDSA.test (Symbol::Flag::OmpShared) || isStaticStorageDuration ) {
23712386 // 6) shared in enclosing context -> shared
23722387 dsa = {Symbol::Flag::OmpShared};
23732388 makeSymbol (dsa);
@@ -2886,20 +2901,6 @@ void ResolveOmpTopLevelParts(
28862901 });
28872902}
28882903
2889- static bool IsSymbolInCommonBlock (const Symbol &symbol) {
2890- // TODO Improve the performance of this predicate function.
2891- // Going through all symbols sequentially, in all common blocks, can be
2892- // slow when there are many symbols. A possible optimization is to add
2893- // an OmpInCommonBlock flag to Symbol, to make it possible to quickly
2894- // test if a given symbol is in a common block.
2895- for (const auto &cb : symbol.owner ().commonBlocks ()) {
2896- if (IsCommonBlockContaining (cb.second .get (), symbol)) {
2897- return true ;
2898- }
2899- }
2900- return false ;
2901- }
2902-
29032904static bool IsSymbolThreadprivate (const Symbol &symbol) {
29042905 if (const auto *details{symbol.detailsIf <HostAssocDetails>()}) {
29052906 return details->symbol ().test (Symbol::Flag::OmpThreadprivate);
@@ -2928,7 +2929,7 @@ static bool IsSymbolPrivate(const Symbol &symbol) {
29282929 case Scope::Kind::BlockConstruct:
29292930 return !symbol.attrs ().test (Attr::SAVE) &&
29302931 !symbol.attrs ().test (Attr::PARAMETER) && !IsAssumedShape (symbol) &&
2931- !IsSymbolInCommonBlock ( symbol);
2932+ !symbol. flags (). test (Symbol::Flag::InCommonBlock );
29322933 default :
29332934 return false ;
29342935 }
0 commit comments