Skip to content

Commit 29b7c96

Browse files
EricjeanPerier
authored andcommitted
Split out the target rewrite pass into its own source file.
Add the ability to test if a subprogram is recursive or not.
1 parent ee6eb03 commit 29b7c96

File tree

4 files changed

+739
-685
lines changed

4 files changed

+739
-685
lines changed

flang/include/flang/Lower/PFTBuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ class ReferenceVariantBase {
7070
return std::get<Ref<B>>(u).get();
7171
}
7272
template <typename B>
73+
constexpr BaseType<B> &getStatement() const {
74+
return std::get<Ref<parser::Statement<B>>>(u).get().statement;
75+
}
76+
template <typename B>
7377
constexpr BaseType<B> *getIf() const {
7478
auto *ptr = std::get_if<Ref<B>>(&u);
7579
return ptr ? &ptr->get() : nullptr;
@@ -547,6 +551,8 @@ struct FunctionLikeUnit : public ProgramUnit {
547551
FunctionLikeUnit(FunctionLikeUnit &&) = default;
548552
FunctionLikeUnit(const FunctionLikeUnit &) = delete;
549553

554+
bool isRecursive() { return isMainProgram() ? false : recursiveFunction; }
555+
550556
std::vector<Variable> getOrderedSymbolTable() { return varList[0]; }
551557

552558
bool isMainProgram() const {
@@ -574,6 +580,7 @@ struct FunctionLikeUnit : public ProgramUnit {
574580
assert(symbol && "not inside a procedure");
575581
return *symbol;
576582
}
583+
577584
/// Return a pointer to the current entry point Evaluation.
578585
/// This is null for a primary entry point.
579586
Evaluation *getEntryEval() const {
@@ -611,6 +618,7 @@ struct FunctionLikeUnit : public ProgramUnit {
611618
/// Terminal basic block (if any)
612619
mlir::Block *finalBlock{};
613620
std::vector<std::vector<Variable>> varList;
621+
bool recursiveFunction{};
614622
};
615623

616624
/// Module-like units contain a list of function-like units.

flang/lib/Lower/PFTBuilder.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ static llvm::cl::opt<bool> clDisableStructuredFir(
2323
"no-structured-fir", llvm::cl::desc("disable generation of structured FIR"),
2424
llvm::cl::init(false), llvm::cl::Hidden);
2525

26+
// FIXME: should be set with switch such as `--std=2018`.
27+
static llvm::cl::opt<bool> nonRecursiveProcedures(
28+
"non-recursive-procedures",
29+
llvm::cl::desc("Make procedures non-recursive by default. This was the "
30+
"default for all Fortran standards prior to 2018."),
31+
llvm::cl::init(/*2018 standard=*/false));
32+
33+
static bool defaultRecursiveFunctionSetting() {
34+
return !nonRecursiveProcedures;
35+
}
36+
2637
using namespace Fortran;
2738

2839
namespace {
@@ -1275,6 +1286,17 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
12751286
}
12761287
}
12771288

1289+
template <typename A>
1290+
static bool procedureIsRecursive(const A &stmt) {
1291+
for (const auto &p : std::get<std::list<parser::PrefixSpec>>(stmt.t)) {
1292+
if (std::holds_alternative<parser::PrefixSpec::Recursive>(p.u))
1293+
return true;
1294+
if (std::holds_alternative<parser::PrefixSpec::Non_Recursive>(p.u))
1295+
return false;
1296+
}
1297+
return defaultRecursiveFunctionSetting();
1298+
}
1299+
12781300
Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
12791301
const parser::FunctionSubprogram &func,
12801302
const lower::pft::ParentVariant &parent,
@@ -1283,6 +1305,8 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
12831305
beginStmt{getFunctionStmt<parser::FunctionStmt>(func)},
12841306
endStmt{getFunctionStmt<parser::EndFunctionStmt>(func)} {
12851307
auto symbol = getSymbol(*beginStmt);
1308+
recursiveFunction =
1309+
procedureIsRecursive(beginStmt->getStatement<parser::FunctionStmt>());
12861310
entryPointList[0].first = symbol;
12871311
processSymbolTable(*symbol->scope(), varList);
12881312
}
@@ -1295,6 +1319,8 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
12951319
beginStmt{getFunctionStmt<parser::SubroutineStmt>(func)},
12961320
endStmt{getFunctionStmt<parser::EndSubroutineStmt>(func)} {
12971321
auto symbol = getSymbol(*beginStmt);
1322+
recursiveFunction =
1323+
procedureIsRecursive(beginStmt->getStatement<parser::SubroutineStmt>());
12981324
entryPointList[0].first = symbol;
12991325
processSymbolTable(*symbol->scope(), varList);
13001326
}
@@ -1305,7 +1331,8 @@ Fortran::lower::pft::FunctionLikeUnit::FunctionLikeUnit(
13051331
const semantics::SemanticsContext &)
13061332
: ProgramUnit{func, parent},
13071333
beginStmt{getFunctionStmt<parser::MpSubprogramStmt>(func)},
1308-
endStmt{getFunctionStmt<parser::EndMpSubprogramStmt>(func)} {
1334+
endStmt{getFunctionStmt<parser::EndMpSubprogramStmt>(func)},
1335+
recursiveFunction{defaultRecursiveFunctionSetting()} {
13091336
auto symbol = getSymbol(*beginStmt);
13101337
entryPointList[0].first = symbol;
13111338
processSymbolTable(*symbol->scope(), varList);

0 commit comments

Comments
 (0)