@@ -1223,11 +1223,37 @@ bool Fortran::lower::definedInCommonBlock(const semantics::Symbol &sym) {
12231223 return semantics::FindCommonBlockContaining (sym);
12241224}
12251225
1226+ static bool isReEntrant (const Fortran::semantics::Scope &scope) {
1227+ if (scope.kind () == Fortran::semantics::Scope::Kind::MainProgram)
1228+ return false ;
1229+ if (scope.kind () == Fortran::semantics::Scope::Kind::Subprogram) {
1230+ const auto *sym = scope.symbol ();
1231+ assert (sym && " Subprogram scope must have a symbol" );
1232+ return sym->attrs ().test (semantics::Attr::RECURSIVE) ||
1233+ (!sym->attrs ().test (semantics::Attr::NON_RECURSIVE) &&
1234+ Fortran::lower::defaultRecursiveFunctionSetting ());
1235+ }
1236+ if (scope.kind () == Fortran::semantics::Scope::Kind::Module)
1237+ return false ;
1238+ return true ;
1239+ }
1240+
12261241// / Is the symbol `sym` a global?
12271242bool Fortran::lower::symbolIsGlobal (const semantics::Symbol &sym) {
1228- if (const auto *details = sym.detailsIf <semantics::ObjectEntityDetails>())
1243+ if (const auto *details = sym.detailsIf <semantics::ObjectEntityDetails>()) {
12291244 if (details->init ())
12301245 return true ;
1246+ if (!isReEntrant (sym.owner ())) {
1247+ // Turn array and character of non re-entrant programs (like the main
1248+ // program) into global memory.
1249+ if (const auto *symTy = sym.GetType ())
1250+ if (symTy->category () == semantics::DeclTypeSpec::Character)
1251+ if (auto e = symTy->characterTypeSpec ().length ().GetExplicit ())
1252+ return true ;
1253+ if (!details->shape ().empty () || !details->coshape ().empty ())
1254+ return true ;
1255+ }
1256+ }
12311257 return semantics::IsSaved (sym) || lower::definedInCommonBlock (sym);
12321258}
12331259
@@ -1238,8 +1264,8 @@ namespace {
12381264// / symbol table, which is sorted by name.
12391265struct SymbolDependenceDepth {
12401266 explicit SymbolDependenceDepth (
1241- std::vector<std::vector<lower::pft::Variable>> &vars, bool reentrant )
1242- : vars{vars}, reentrant{reentrant} {}
1267+ std::vector<std::vector<lower::pft::Variable>> &vars)
1268+ : vars{vars} {}
12431269
12441270 void analyzeAliasesInCurrentScope (const semantics::Scope &scope) {
12451271 // FIXME: When this function is called on the scope of an internal
@@ -1348,7 +1374,6 @@ struct SymbolDependenceDepth {
13481374 llvm_unreachable (" not yet implemented - derived type analysis" );
13491375
13501376 // Symbol must be something lowering will have to allocate.
1351- bool global = lower::symbolIsGlobal (sym);
13521377 int depth = 0 ;
13531378 const auto *symTy = sym.GetType ();
13541379 assert (symTy && " symbol must have a type" );
@@ -1361,12 +1386,9 @@ struct SymbolDependenceDepth {
13611386 if (const auto *details = sym.detailsIf <semantics::ObjectEntityDetails>()) {
13621387 // check CHARACTER's length
13631388 if (symTy->category () == semantics::DeclTypeSpec::Character)
1364- if (auto e = symTy->characterTypeSpec ().length ().GetExplicit ()) {
1365- // turn variable into a global if this unit is not reentrant
1366- global = global || !reentrant;
1389+ if (auto e = symTy->characterTypeSpec ().length ().GetExplicit ())
13671390 for (const auto &s : evaluate::CollectSymbols (*e))
13681391 depth = std::max (analyze (s) + 1 , depth);
1369- }
13701392
13711393 auto doExplicit = [&](const auto &bound) {
13721394 if (bound.isExplicit ()) {
@@ -1376,15 +1398,11 @@ struct SymbolDependenceDepth {
13761398 }
13771399 };
13781400 // handle any symbols in array bound declarations
1379- if (!details->shape ().empty ())
1380- global = global || !reentrant;
13811401 for (const auto &subs : details->shape ()) {
13821402 doExplicit (subs.lbound ());
13831403 doExplicit (subs.ubound ());
13841404 }
13851405 // handle any symbols in coarray bound declarations
1386- if (!details->coshape ().empty ())
1387- global = global || !reentrant;
13881406 for (const auto &subs : details->coshape ()) {
13891407 doExplicit (subs.lbound ());
13901408 doExplicit (subs.ubound ());
@@ -1395,6 +1413,7 @@ struct SymbolDependenceDepth {
13951413 depth = std::max (analyze (s) + 1 , depth);
13961414 }
13971415 adjustSize (depth + 1 );
1416+ auto global = lower::symbolIsGlobal (sym);
13981417 vars[depth].emplace_back (sym, global, depth);
13991418 if (semantics::IsAllocatable (sym))
14001419 vars[depth].back ().setHeapAlloc ();
@@ -1479,15 +1498,13 @@ struct SymbolDependenceDepth {
14791498 // / Set of Scope that have been analyzed for aliases.
14801499 llvm::SmallSet<const semantics::Scope *, 4 > analyzedScopes;
14811500 std::vector<Fortran::lower::pft::Variable::AggregateStore> stores;
1482- bool reentrant;
14831501};
14841502} // namespace
14851503
14861504static void processSymbolTable (
14871505 const semantics::Scope &scope,
1488- std::vector<std::vector<Fortran::lower::pft::Variable>> &varList,
1489- bool reentrant) {
1490- SymbolDependenceDepth sdd{varList, reentrant};
1506+ std::vector<std::vector<Fortran::lower::pft::Variable>> &varList) {
1507+ SymbolDependenceDepth sdd{varList};
14911508 sdd.analyzeAliasesInCurrentScope (scope);
14921509 for (const auto &iter : scope)
14931510 sdd.analyze (iter.second .get ());
@@ -1510,12 +1527,12 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
15101527 beginStmt = FunctionStatement (programStmt.value ());
15111528 auto symbol = getSymbol (*beginStmt);
15121529 entryPointList[0 ].first = symbol;
1513- processSymbolTable (*symbol->scope (), varList, isRecursive () );
1530+ processSymbolTable (*symbol->scope (), varList);
15141531 } else {
15151532 processSymbolTable (
15161533 semanticsContext.FindScope (
15171534 std::get<parser::Statement<parser::EndProgramStmt>>(func.t ).source ),
1518- varList, isRecursive () );
1535+ varList);
15191536 }
15201537}
15211538
@@ -1527,7 +1544,7 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
15271544 endStmt{getFunctionStmt<parser::EndFunctionStmt>(func)} {
15281545 auto symbol = getSymbol (*beginStmt);
15291546 entryPointList[0 ].first = symbol;
1530- processSymbolTable (*symbol->scope (), varList, isRecursive () );
1547+ processSymbolTable (*symbol->scope (), varList);
15311548}
15321549
15331550Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit (
@@ -1538,7 +1555,7 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
15381555 endStmt{getFunctionStmt<parser::EndSubroutineStmt>(func)} {
15391556 auto symbol = getSymbol (*beginStmt);
15401557 entryPointList[0 ].first = symbol;
1541- processSymbolTable (*symbol->scope (), varList, isRecursive () );
1558+ processSymbolTable (*symbol->scope (), varList);
15421559}
15431560
15441561Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit (
@@ -1549,7 +1566,7 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
15491566 endStmt{getFunctionStmt<parser::EndMpSubprogramStmt>(func)} {
15501567 auto symbol = getSymbol (*beginStmt);
15511568 entryPointList[0 ].first = symbol;
1552- processSymbolTable (*symbol->scope (), varList, isRecursive () );
1569+ processSymbolTable (*symbol->scope (), varList);
15531570}
15541571
15551572Fortran::lower::HostAssociations &
@@ -1583,7 +1600,7 @@ Fortran::lower::pft::ModuleLikeUnit::ModuleLikeUnit(
15831600 : ProgramUnit{m, parent}, beginStmt{getModuleStmt<parser::ModuleStmt>(m)},
15841601 endStmt{getModuleStmt<parser::EndModuleStmt>(m)} {
15851602 auto symbol = getSymbol (beginStmt);
1586- processSymbolTable (*symbol->scope (), varList, /* reentrant= */ false );
1603+ processSymbolTable (*symbol->scope (), varList);
15871604}
15881605
15891606Fortran::lower::pft::ModuleLikeUnit::ModuleLikeUnit (
@@ -1592,7 +1609,7 @@ Fortran::lower::pft::ModuleLikeUnit::ModuleLikeUnit(
15921609 m)},
15931610 endStmt{getModuleStmt<parser::EndSubmoduleStmt>(m)} {
15941611 auto symbol = getSymbol (beginStmt);
1595- processSymbolTable (*symbol->scope (), varList, /* reentrant= */ false );
1612+ processSymbolTable (*symbol->scope (), varList);
15961613}
15971614
15981615parser::CharBlock
@@ -1686,8 +1703,7 @@ std::vector<Fortran::lower::pft::Variable>
16861703Fortran::lower::pft::buildFuncResultDependencyList (
16871704 const Fortran::semantics::Symbol &symbol) {
16881705 std::vector<std::vector<pft::Variable>> variableList;
1689- // reentrant does not matter, no locals involved for results ().
1690- SymbolDependenceDepth sdd (variableList, /* reentrant=*/ true );
1706+ SymbolDependenceDepth sdd (variableList);
16911707 sdd.analyzeAliasesInCurrentScope (symbol.owner ());
16921708 sdd.analyze (symbol);
16931709 sdd.finalize ();
0 commit comments