@@ -1223,11 +1223,37 @@ bool Fortran::lower::definedInCommonBlock(const semantics::Symbol &sym) {
1223
1223
return semantics::FindCommonBlockContaining (sym);
1224
1224
}
1225
1225
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
+
1226
1241
// / Is the symbol `sym` a global?
1227
1242
bool 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>()) {
1229
1244
if (details->init ())
1230
1245
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
+ }
1231
1257
return semantics::IsSaved (sym) || lower::definedInCommonBlock (sym);
1232
1258
}
1233
1259
@@ -1238,8 +1264,8 @@ namespace {
1238
1264
// / symbol table, which is sorted by name.
1239
1265
struct SymbolDependenceDepth {
1240
1266
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} {}
1243
1269
1244
1270
void analyzeAliasesInCurrentScope (const semantics::Scope &scope) {
1245
1271
// FIXME: When this function is called on the scope of an internal
@@ -1348,7 +1374,6 @@ struct SymbolDependenceDepth {
1348
1374
llvm_unreachable (" not yet implemented - derived type analysis" );
1349
1375
1350
1376
// Symbol must be something lowering will have to allocate.
1351
- bool global = lower::symbolIsGlobal (sym);
1352
1377
int depth = 0 ;
1353
1378
const auto *symTy = sym.GetType ();
1354
1379
assert (symTy && " symbol must have a type" );
@@ -1361,12 +1386,9 @@ struct SymbolDependenceDepth {
1361
1386
if (const auto *details = sym.detailsIf <semantics::ObjectEntityDetails>()) {
1362
1387
// check CHARACTER's length
1363
1388
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 ())
1367
1390
for (const auto &s : evaluate::CollectSymbols (*e))
1368
1391
depth = std::max (analyze (s) + 1 , depth);
1369
- }
1370
1392
1371
1393
auto doExplicit = [&](const auto &bound) {
1372
1394
if (bound.isExplicit ()) {
@@ -1376,15 +1398,11 @@ struct SymbolDependenceDepth {
1376
1398
}
1377
1399
};
1378
1400
// handle any symbols in array bound declarations
1379
- if (!details->shape ().empty ())
1380
- global = global || !reentrant;
1381
1401
for (const auto &subs : details->shape ()) {
1382
1402
doExplicit (subs.lbound ());
1383
1403
doExplicit (subs.ubound ());
1384
1404
}
1385
1405
// handle any symbols in coarray bound declarations
1386
- if (!details->coshape ().empty ())
1387
- global = global || !reentrant;
1388
1406
for (const auto &subs : details->coshape ()) {
1389
1407
doExplicit (subs.lbound ());
1390
1408
doExplicit (subs.ubound ());
@@ -1395,6 +1413,7 @@ struct SymbolDependenceDepth {
1395
1413
depth = std::max (analyze (s) + 1 , depth);
1396
1414
}
1397
1415
adjustSize (depth + 1 );
1416
+ auto global = lower::symbolIsGlobal (sym);
1398
1417
vars[depth].emplace_back (sym, global, depth);
1399
1418
if (semantics::IsAllocatable (sym))
1400
1419
vars[depth].back ().setHeapAlloc ();
@@ -1479,15 +1498,13 @@ struct SymbolDependenceDepth {
1479
1498
// / Set of Scope that have been analyzed for aliases.
1480
1499
llvm::SmallSet<const semantics::Scope *, 4 > analyzedScopes;
1481
1500
std::vector<Fortran::lower::pft::Variable::AggregateStore> stores;
1482
- bool reentrant;
1483
1501
};
1484
1502
} // namespace
1485
1503
1486
1504
static void processSymbolTable (
1487
1505
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};
1491
1508
sdd.analyzeAliasesInCurrentScope (scope);
1492
1509
for (const auto &iter : scope)
1493
1510
sdd.analyze (iter.second .get ());
@@ -1510,12 +1527,12 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
1510
1527
beginStmt = FunctionStatement (programStmt.value ());
1511
1528
auto symbol = getSymbol (*beginStmt);
1512
1529
entryPointList[0 ].first = symbol;
1513
- processSymbolTable (*symbol->scope (), varList, isRecursive () );
1530
+ processSymbolTable (*symbol->scope (), varList);
1514
1531
} else {
1515
1532
processSymbolTable (
1516
1533
semanticsContext.FindScope (
1517
1534
std::get<parser::Statement<parser::EndProgramStmt>>(func.t ).source ),
1518
- varList, isRecursive () );
1535
+ varList);
1519
1536
}
1520
1537
}
1521
1538
@@ -1527,7 +1544,7 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
1527
1544
endStmt{getFunctionStmt<parser::EndFunctionStmt>(func)} {
1528
1545
auto symbol = getSymbol (*beginStmt);
1529
1546
entryPointList[0 ].first = symbol;
1530
- processSymbolTable (*symbol->scope (), varList, isRecursive () );
1547
+ processSymbolTable (*symbol->scope (), varList);
1531
1548
}
1532
1549
1533
1550
Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit (
@@ -1538,7 +1555,7 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
1538
1555
endStmt{getFunctionStmt<parser::EndSubroutineStmt>(func)} {
1539
1556
auto symbol = getSymbol (*beginStmt);
1540
1557
entryPointList[0 ].first = symbol;
1541
- processSymbolTable (*symbol->scope (), varList, isRecursive () );
1558
+ processSymbolTable (*symbol->scope (), varList);
1542
1559
}
1543
1560
1544
1561
Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit (
@@ -1549,7 +1566,7 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
1549
1566
endStmt{getFunctionStmt<parser::EndMpSubprogramStmt>(func)} {
1550
1567
auto symbol = getSymbol (*beginStmt);
1551
1568
entryPointList[0 ].first = symbol;
1552
- processSymbolTable (*symbol->scope (), varList, isRecursive () );
1569
+ processSymbolTable (*symbol->scope (), varList);
1553
1570
}
1554
1571
1555
1572
Fortran::lower::HostAssociations &
@@ -1583,7 +1600,7 @@ Fortran::lower::pft::ModuleLikeUnit::ModuleLikeUnit(
1583
1600
: ProgramUnit{m, parent}, beginStmt{getModuleStmt<parser::ModuleStmt>(m)},
1584
1601
endStmt{getModuleStmt<parser::EndModuleStmt>(m)} {
1585
1602
auto symbol = getSymbol (beginStmt);
1586
- processSymbolTable (*symbol->scope (), varList, /* reentrant= */ false );
1603
+ processSymbolTable (*symbol->scope (), varList);
1587
1604
}
1588
1605
1589
1606
Fortran::lower::pft::ModuleLikeUnit::ModuleLikeUnit (
@@ -1592,7 +1609,7 @@ Fortran::lower::pft::ModuleLikeUnit::ModuleLikeUnit(
1592
1609
m)},
1593
1610
endStmt{getModuleStmt<parser::EndSubmoduleStmt>(m)} {
1594
1611
auto symbol = getSymbol (beginStmt);
1595
- processSymbolTable (*symbol->scope (), varList, /* reentrant= */ false );
1612
+ processSymbolTable (*symbol->scope (), varList);
1596
1613
}
1597
1614
1598
1615
parser::CharBlock
@@ -1686,8 +1703,7 @@ std::vector<Fortran::lower::pft::Variable>
1686
1703
Fortran::lower::pft::buildFuncResultDependencyList (
1687
1704
const Fortran::semantics::Symbol &symbol) {
1688
1705
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);
1691
1707
sdd.analyzeAliasesInCurrentScope (symbol.owner ());
1692
1708
sdd.analyze (symbol);
1693
1709
sdd.finalize ();
0 commit comments