mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-26 19:36:28 +00:00
[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
This commit is contained in:
parent
aa44815f84
commit
529f71811b
@ -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">;
|
||||
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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, (...)
|
||||
|
@ -16,6 +16,7 @@ add_flang_library(flangFrontend
|
||||
FortranSemantics
|
||||
FortranEvaluate
|
||||
FortranCommon
|
||||
FortranLower
|
||||
clangBasic
|
||||
clangDriver
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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(
|
||||
|
@ -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:
|
||||
|
26
flang/test/Flang-Driver/debug-measure-parse-tree.f90
Normal file
26
flang/test/Flang-Driver/debug-measure-parse-tree.f90
Normal file
@ -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
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user