diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp --- a/flang/lib/Lower/PFTBuilder.cpp +++ b/flang/lib/Lower/PFTBuilder.cpp @@ -30,6 +30,13 @@ "default for all Fortran standards prior to 2018."), llvm::cl::init(/*2018 standard=*/false)); +static llvm::cl::opt mainProgramGlobals( + "main-program-globals", + llvm::cl::desc( + "Allocate all variables in the main program as global variables and " + "not on the stack regardless of type, kind, and rank."), + llvm::cl::init(/*2018 standard=*/false), llvm::cl::Hidden); + using namespace Fortran; namespace { @@ -416,6 +423,8 @@ } else if (const auto *entryStmt = p->getIf()) { const semantics::Symbol *sym = std::get(entryStmt->t).symbol; + if (auto *details = sym->detailsIf()) + sym = details->specific(); assert(sym->has() && "entry must be a subprogram"); entryPointList.push_back(std::pair{sym, p}); @@ -1257,7 +1266,7 @@ return semantics::FindCommonBlockContaining(sym); } -static bool isReEntrant(const Fortran::semantics::Scope &scope) { +static bool isReentrant(const Fortran::semantics::Scope &scope) { if (scope.kind() == Fortran::semantics::Scope::Kind::MainProgram) return false; if (scope.kind() == Fortran::semantics::Scope::Kind::Subprogram) { @@ -1277,7 +1286,7 @@ if (const auto *details = sym.detailsIf()) { if (details->init()) return true; - if (!isReEntrant(sym.owner())) { + if (!isReentrant(sym.owner())) { // Turn array and character of non re-entrant programs (like the main // program) into global memory. if (const Fortran::semantics::DeclTypeSpec *symTy = sym.GetType()) @@ -1287,6 +1296,9 @@ if (!details->shape().empty() || !details->coshape().empty()) return true; } + if (mainProgramGlobals && + sym.owner().kind() == Fortran::semantics::Scope::Kind::MainProgram) + return true; } return semantics::IsSaved(sym) || lower::definedInCommonBlock(sym) || semantics::IsNamedConstant(sym); @@ -1821,10 +1833,9 @@ if (std::optional length = dynamicType->GetCharLength()) visitExpr(*length); - } else if (dynamicType->category() == common::TypeCategory::Derived) { - const Fortran::semantics::DerivedTypeSpec &derivedTypeSpec = - dynamicType->GetDerivedTypeSpec(); - for (const auto &[_, param] : derivedTypeSpec.parameters()) + } else if (const Fortran::semantics::DerivedTypeSpec *derivedTypeSpec = + Fortran::evaluate::GetDerivedTypeSpec(dynamicType)) { + for (const auto &[_, param] : derivedTypeSpec->parameters()) if (const Fortran::semantics::MaybeIntExpr &expr = param.GetExplicit()) visitExpr(expr.value());