aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFaris Rehman <faris.rehman@arm.com>2021-02-17 18:53:05 +0000
committerFaris Rehman <faris.rehman@arm.com>2021-02-19 11:27:54 +0000
commit529f71811b0475995f2d9cf766f18d897eec574c (patch)
tree38a91175d41a58a35a1caffc1abae6fe8513d861
parentaa44815f849f2928f998499b163c8c3230a73c95 (diff)
downloadllvm-529f71811b0475995f2d9cf766f18d897eec574c.zip
llvm-529f71811b0475995f2d9cf766f18d897eec574c.tar.gz
llvm-529f71811b0475995f2d9cf766f18d897eec574c.tar.bz2
[flang][driver] Add debug measure-parse-tree and pre-fir-tree options
Add the following options: * -fdebug-measure-parse-tree * -fdebug-pre-fir-tree Summary of changes: - Add 2 new frontend actions: DebugMeasureParseTreeAction and DebugPreFIRTreeAction - Add MeasurementVisitor to FrontendActions.h - Make reportFatalSemanticErrors return true if there are any fatal errors - Port most of the `-fdebug-pre-fir-tree` tests to use the new driver if built, otherwise use f18. Differential Revision: https://reviews.llvm.org/D96884
-rw-r--r--clang/include/clang/Driver/Options.td4
-rw-r--r--flang/include/flang/Frontend/FrontendActions.h19
-rw-r--r--flang/include/flang/Frontend/FrontendOptions.h9
-rw-r--r--flang/lib/Frontend/CMakeLists.txt1
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp6
-rw-r--r--flang/lib/Frontend/FrontendActions.cpp62
-rw-r--r--flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp6
-rw-r--r--flang/test/Flang-Driver/debug-measure-parse-tree.f9026
-rw-r--r--flang/test/Flang-Driver/driver-help.f903
-rw-r--r--flang/test/Lower/pre-fir-tree01.f902
-rw-r--r--flang/test/Lower/pre-fir-tree02.f902
-rw-r--r--flang/test/Lower/pre-fir-tree03.f902
-rw-r--r--flang/test/Lower/pre-fir-tree05.f902
13 files changed, 138 insertions, 6 deletions
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 17eb0ad..ade330b 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4288,6 +4288,10 @@ def fdebug_dump_parse_tree : Flag<["-"], "fdebug-dump-parse-tree">, Group<Action
HelpText<"Dump the parse tree">;
def fdebug_dump_provenance : Flag<["-"], "fdebug-dump-provenance">, Group<Action_Group>,
HelpText<"Dump provenance">;
+def fdebug_measure_parse_tree : Flag<["-"], "fdebug-measure-parse-tree">, Group<Action_Group>,
+ HelpText<"Measure the parse tree">;
+def fdebug_pre_fir_tree : Flag<["-"], "fdebug-pre-fir-tree">, Group<Action_Group>,
+ HelpText<"Dump the pre-FIR tree">;
}
diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h
index ebcb695..f6dfdd2 100644
--- a/flang/include/flang/Frontend/FrontendActions.h
+++ b/flang/include/flang/Frontend/FrontendActions.h
@@ -15,6 +15,17 @@
namespace Fortran::frontend {
+// TODO: This is a copy from f18.cpp. It doesn't really belong here and should
+// be moved to a more suitable place in future.
+struct MeasurementVisitor {
+ template <typename A> bool Pre(const A &) { return true; }
+ template <typename A> void Post(const A &) {
+ ++objects;
+ bytes += sizeof(A);
+ }
+ size_t objects{0}, bytes{0};
+};
+
//===----------------------------------------------------------------------===//
// Custom Consumer Actions
//===----------------------------------------------------------------------===//
@@ -43,6 +54,10 @@ class DebugDumpProvenanceAction : public PrescanAction {
void ExecuteAction() override;
};
+class DebugMeasureParseTreeAction : public PrescanAction {
+ void ExecuteAction() override;
+};
+
//===----------------------------------------------------------------------===//
// PrescanAndSema Actions
//===----------------------------------------------------------------------===//
@@ -77,6 +92,10 @@ class DebugDumpParseTreeAction : public PrescanAndSemaAction {
void ExecuteAction() override;
};
+class DebugPreFIRTreeAction : public PrescanAndSemaAction {
+ void ExecuteAction() override;
+};
+
class ParseSyntaxOnlyAction : public PrescanAndSemaAction {
void ExecuteAction() override;
};
diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h
index a26e1e3..98a717df 100644
--- a/flang/include/flang/Frontend/FrontendOptions.h
+++ b/flang/include/flang/Frontend/FrontendOptions.h
@@ -48,7 +48,14 @@ enum ActionKind {
DebugDumpParseTree,
/// Dump provenance
- DebugDumpProvenance
+ DebugDumpProvenance,
+
+ /// Parse then output the number of objects in the parse tree and the overall
+ /// size
+ DebugMeasureParseTree,
+
+ /// Parse, run semantics and then output the pre-FIR tree
+ DebugPreFIRTree
/// TODO: RunPreprocessor, EmitLLVM, EmitLLVMOnly,
/// EmitCodeGenOnly, EmitAssembly, (...)
diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt
index 53c2518..abaa77f 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -16,6 +16,7 @@ add_flang_library(flangFrontend
FortranSemantics
FortranEvaluate
FortranCommon
+ FortranLower
clangBasic
clangDriver
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index ecc0fda..822bf26 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -125,6 +125,12 @@ static InputKind ParseFrontendArgs(FrontendOptions &opts,
case clang::driver::options::OPT_fdebug_dump_provenance:
opts.programAction_ = DebugDumpProvenance;
break;
+ case clang::driver::options::OPT_fdebug_measure_parse_tree:
+ opts.programAction_ = DebugMeasureParseTree;
+ break;
+ case clang::driver::options::OPT_fdebug_pre_fir_tree:
+ opts.programAction_ = DebugPreFIRTree;
+ break;
// TODO:
// case calng::driver::options::OPT_emit_llvm:
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 91e19a7..b7e4f91 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -10,6 +10,7 @@
#include "flang/Common/default-kinds.h"
#include "flang/Frontend/CompilerInstance.h"
#include "flang/Frontend/FrontendOptions.h"
+#include "flang/Lower/PFTBuilder.h"
#include "flang/Parser/dump-parse-tree.h"
#include "flang/Parser/parsing.h"
#include "flang/Parser/provenance.h"
@@ -23,13 +24,22 @@
using namespace Fortran::frontend;
-void reportFatalSemanticErrors(const Fortran::semantics::Semantics &semantics,
+/// Report fatal semantic errors if present.
+///
+/// \param semantics The semantics instance
+/// \param diags The diagnostics engine instance
+/// \param bufferName The file or buffer name
+///
+/// \return True if fatal semantic errors are present, false if not
+bool reportFatalSemanticErrors(const Fortran::semantics::Semantics &semantics,
clang::DiagnosticsEngine &diags, const llvm::StringRef &bufferName) {
if (semantics.AnyFatalError()) {
unsigned DiagID = diags.getCustomDiagID(
clang::DiagnosticsEngine::Error, "Semantic errors in %0");
diags.Report(DiagID) << bufferName;
+ return true;
}
+ return false;
}
bool PrescanAction::BeginSourceFileAction(CompilerInstance &c1) {
@@ -247,6 +257,56 @@ void DebugDumpParseTreeAction::ExecuteAction() {
GetCurrentFileOrBufferName());
}
+void DebugMeasureParseTreeAction::ExecuteAction() {
+ CompilerInstance &ci = this->instance();
+
+ // Parse. In case of failure, report and return.
+ ci.parsing().Parse(llvm::outs());
+
+ if (ci.parsing().messages().AnyFatalError()) {
+ unsigned diagID = ci.diagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Error, "Could not parse %0");
+ ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName();
+
+ ci.parsing().messages().Emit(
+ llvm::errs(), this->instance().allCookedSources());
+ return;
+ }
+
+ // Report the diagnostics from parsing
+ ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources());
+
+ auto &parseTree{*ci.parsing().parseTree()};
+
+ // Measure the parse tree
+ MeasurementVisitor visitor;
+ Fortran::parser::Walk(parseTree, visitor);
+ llvm::outs() << "Parse tree comprises " << visitor.objects
+ << " objects and occupies " << visitor.bytes
+ << " total bytes.\n";
+}
+
+void DebugPreFIRTreeAction::ExecuteAction() {
+ CompilerInstance &ci = this->instance();
+ // Report and exit if fatal semantic errors are present
+ if (reportFatalSemanticErrors(
+ semantics(), ci.diagnostics(), GetCurrentFileOrBufferName())) {
+ return;
+ }
+
+ auto &parseTree{*ci.parsing().parseTree()};
+
+ // Dump pre-FIR tree
+ if (auto ast{Fortran::lower::createPFT(
+ parseTree, ci.invocation().semanticsContext())}) {
+ Fortran::lower::dumpPFT(llvm::outs(), *ast);
+ } else {
+ unsigned diagID = ci.diagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Error, "Pre FIR Tree is NULL.");
+ ci.diagnostics().Report(diagID);
+ }
+}
+
void EmitObjAction::ExecuteAction() {
CompilerInstance &ci = this->instance();
unsigned DiagID = ci.diagnostics().getCustomDiagID(
diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index aec968b..c5f7bb2 100644
--- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -52,6 +52,12 @@ static std::unique_ptr<FrontendAction> CreateFrontendBaseAction(
case DebugDumpProvenance:
return std::make_unique<DebugDumpProvenanceAction>();
break;
+ case DebugMeasureParseTree:
+ return std::make_unique<DebugMeasureParseTreeAction>();
+ break;
+ case DebugPreFIRTree:
+ return std::make_unique<DebugPreFIRTreeAction>();
+ break;
default:
break;
// TODO:
diff --git a/flang/test/Flang-Driver/debug-measure-parse-tree.f90 b/flang/test/Flang-Driver/debug-measure-parse-tree.f90
new file mode 100644
index 0000000..fd43468
--- /dev/null
+++ b/flang/test/Flang-Driver/debug-measure-parse-tree.f90
@@ -0,0 +1,26 @@
+! Ensure argument -fdebug-measure-parse-tree works as expected.
+
+! REQUIRES: new-flang-driver
+
+!--------------------------
+! FLANG DRIVER (flang-new)
+!--------------------------
+! RUN: not %flang-new -fdebug-measure-parse-tree %s 2>&1 | FileCheck %s --check-prefix=FLANG
+
+!----------------------------------------
+! FRONTEND FLANG DRIVER (flang-new -fc1)
+!----------------------------------------
+! RUN: %flang-new -fc1 -fdebug-measure-parse-tree %s 2>&1 | FileCheck %s --check-prefix=FRONTEND
+
+!----------------------------------
+! EXPECTED OUTPUT WITH `flang-new`
+!----------------------------------
+! FLANG:warning: argument unused during compilation: '-fdebug-measure-parse-tree'
+
+!---------------------------------------
+! EXPECTED OUTPUT WITH `flang-new -fc1`
+!---------------------------------------
+! FRONTEND:Parse tree comprises {{[0-9]+}} objects and occupies {{[0-9]+}} total bytes.
+
+program A
+end
diff --git a/flang/test/Flang-Driver/driver-help.f90 b/flang/test/Flang-Driver/driver-help.f90
index fd05331..b4072c1 100644
--- a/flang/test/Flang-Driver/driver-help.f90
+++ b/flang/test/Flang-Driver/driver-help.f90
@@ -59,6 +59,9 @@
! HELP-FC1-NEXT: -fdebug-dump-parse-tree Dump the parse tree
! HELP-FC1-NEXT: -fdebug-dump-provenance Dump provenance
! HELP-FC1-NEXT: -fdebug-dump-symbols Dump symbols after the semantic analysis
+! HELP-FC1-NEXT: -fdebug-measure-parse-tree
+! HELP-FC1-NEXT: Measure the parse tree
+! HELP-FC1-NEXT: -fdebug-pre-fir-tree Dump the pre-FIR tree
! HELP-FC1-NEXT: -fdebug-unparse-with-symbols
! HELP-FC1-NEXT: Unparse and stop.
! HELP-FC1-NEXT: -fdebug-unparse Unparse and stop.
diff --git a/flang/test/Lower/pre-fir-tree01.f90 b/flang/test/Lower/pre-fir-tree01.f90
index 5e59ff7..23f9fd1 100644
--- a/flang/test/Lower/pre-fir-tree01.f90
+++ b/flang/test/Lower/pre-fir-tree01.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -fdebug-pre-fir-tree -fsyntax-only %s | FileCheck %s
+! RUN: %flang_fc1 -fsyntax-only -fdebug-pre-fir-tree %s | FileCheck %s
! Test structure of the Pre-FIR tree
diff --git a/flang/test/Lower/pre-fir-tree02.f90 b/flang/test/Lower/pre-fir-tree02.f90
index 1db4960..9e16c4e 100644
--- a/flang/test/Lower/pre-fir-tree02.f90
+++ b/flang/test/Lower/pre-fir-tree02.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -fdebug-pre-fir-tree -fsyntax-only %s | FileCheck %s
+! RUN: %flang_fc1 -fsyntax-only -fdebug-pre-fir-tree %s | FileCheck %s
! Test Pre-FIR Tree captures all the intended nodes from the parse-tree
! Coarray and OpenMP related nodes are tested in other files.
diff --git a/flang/test/Lower/pre-fir-tree03.f90 b/flang/test/Lower/pre-fir-tree03.f90
index efc923a..19cf098 100644
--- a/flang/test/Lower/pre-fir-tree03.f90
+++ b/flang/test/Lower/pre-fir-tree03.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -fdebug-pre-fir-tree -fsyntax-only -fopenmp %s | FileCheck %s
+! RUN: %flang_fc1 -fsyntax-only -fdebug-pre-fir-tree -fopenmp %s | FileCheck %s
! Test Pre-FIR Tree captures OpenMP related constructs
diff --git a/flang/test/Lower/pre-fir-tree05.f90 b/flang/test/Lower/pre-fir-tree05.f90
index 3acc38b..fb57663 100644
--- a/flang/test/Lower/pre-fir-tree05.f90
+++ b/flang/test/Lower/pre-fir-tree05.f90
@@ -1,4 +1,4 @@
-! RUN: %f18 -fdebug-pre-fir-tree -fsyntax-only -fopenacc %s | FileCheck %s
+! RUN: %flang_fc1 -fsyntax-only -fdebug-pre-fir-tree -fopenacc %s | FileCheck %s
! Test structure of the Pre-FIR tree with OpenACC construct