aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorSacha Ballantyne <Sacha.Ballantyne@arm.com>2023-03-27 13:12:10 +0000
committerSacha Ballantyne <Sacha.Ballantyne@arm.com>2023-03-29 12:21:26 +0000
commite2b7424d06663f92b958c0b4649ed08b55216a49 (patch)
treecd3c6c6efe6befab936c78f3a246a88e2aa163cb /flang
parent6b6f312ccedff8322e246f9022148a5bc8805ae5 (diff)
downloadllvm-e2b7424d06663f92b958c0b4649ed08b55216a49.zip
llvm-e2b7424d06663f92b958c0b4649ed08b55216a49.tar.gz
llvm-e2b7424d06663f92b958c0b4649ed08b55216a49.tar.bz2
[Flang] Add debug flag to enable current debug information pass
While a pass exists to generate basic debug information, currently there is not a corresponding flag to enable it. This patch adds support for activating this pass at any debug level >= -g1, as well as emiting a warning for higher levels that the functionality is not yet fully implemented. This patch also adds -g and -gline-tables-only to appear when `flang-new` --help is run Depends on D142347. Reviewed By: awarzynski Differential Revision: https://reviews.llvm.org/D146814
Diffstat (limited to 'flang')
-rw-r--r--flang/include/flang/Frontend/CodeGenOptions.def1
-rw-r--r--flang/include/flang/Frontend/CodeGenOptions.h1
-rw-r--r--flang/include/flang/Tools/CLOptions.inc32
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp34
-rw-r--r--flang/lib/Frontend/FrontendActions.cpp2
-rw-r--r--flang/test/Driver/driver-help-hidden.f902
-rw-r--r--flang/test/Driver/driver-help.f902
-rw-r--r--flang/test/Driver/mlir-debug-pass-pipeline.f9083
8 files changed, 153 insertions, 4 deletions
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index c6bd7a5..dbdfe07 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -34,6 +34,7 @@ CODEGENOPT(StackArrays, 1, 0) ///< -fstack-arrays (enable the stack-arrays pass)
CODEGENOPT(Underscoring, 1, 1)
ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use.
+ENUM_CODEGENOPT(DebugInfo, llvm::codegenoptions::DebugInfoKind, 4, llvm::codegenoptions::NoDebugInfo) ///< Level of debug info to generate
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
index 925de7f..60aa38a 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_BASIC_CODEGENOPTIONS_H
#define LLVM_CLANG_BASIC_CODEGENOPTIONS_H
+#include "llvm/Frontend/Debug/Options.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Regex.h"
#include "llvm/Target/TargetOptions.h"
diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc
index 3058162..8a1f7eb 100644
--- a/flang/include/flang/Tools/CLOptions.inc
+++ b/flang/include/flang/Tools/CLOptions.inc
@@ -16,6 +16,7 @@
#include "flang/Optimizer/CodeGen/CodeGen.h"
#include "flang/Optimizer/HLFIR/Passes.h"
#include "flang/Optimizer/Transforms/Passes.h"
+#include "llvm/Frontend/Debug/Options.h"
#include "llvm/Passes/OptimizationLevel.h"
#include "llvm/Support/CommandLine.h"
@@ -56,6 +57,9 @@ namespace {
const static llvm::OptimizationLevel &defaultOptLevel{
llvm::OptimizationLevel::O0};
+const static llvm::codegenoptions::DebugInfoKind &NoDebugInfo{
+ llvm::codegenoptions::NoDebugInfo};
+
/// Optimizer Passes
DisableOption(CfgConversion, "cfg-conversion", "disable FIR to CFG pass");
DisableOption(FirAvc, "avc", "array value copy analysis and transformation");
@@ -228,9 +232,28 @@ inline void createHLFIRToFIRPassPipeline(
}
#if !defined(FLANG_EXCLUDE_CODEGEN)
+inline void createDebugPasses(
+ mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel) {
+ // Currently only -g1, -g, -gline-tables-only supported
+ switch (debugLevel) {
+ case llvm::codegenoptions::DebugLineTablesOnly:
+ addDebugFoundationPass(pm);
+ return;
+ case llvm::codegenoptions::NoDebugInfo:
+ return;
+ default:
+ // TODO: Add cases and passes for other debug options.
+ // All other debug options not implemented yet, currently emits warning
+ // and generates as much debug information as possible.
+ addDebugFoundationPass(pm);
+ return;
+ }
+}
+
inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
llvm::OptimizationLevel optLevel = defaultOptLevel,
- bool underscoring = true) {
+ bool underscoring = true,
+ llvm::codegenoptions::DebugInfoKind debugInfo = NoDebugInfo) {
fir::addBoxedProcedurePass(pm);
pm.addNestedPass<mlir::func::FuncOp>(
fir::createAbstractResultOnFuncOptPass());
@@ -238,6 +261,7 @@ inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
fir::addCodeGenRewritePass(pm);
fir::addTargetRewritePass(pm);
fir::addExternalNameConversionPass(pm, underscoring);
+ fir::createDebugPasses(pm, debugInfo);
fir::addFIRToLLVMPass(pm, optLevel);
}
@@ -248,14 +272,16 @@ inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
/// passes pipeline
inline void createMLIRToLLVMPassPipeline(mlir::PassManager &pm,
llvm::OptimizationLevel optLevel = defaultOptLevel,
- bool stackArrays = false, bool underscoring = true) {
+ bool stackArrays = false, bool underscoring = true,
+ llvm::codegenoptions::DebugInfoKind debugInfo = NoDebugInfo) {
fir::createHLFIRToFIRPassPipeline(pm, optLevel);
// Add default optimizer pass pipeline.
fir::createDefaultFIROptimizerPassPipeline(pm, optLevel, stackArrays);
// Add codegen pass pipeline.
- fir::createDefaultFIRCodeGenPassPipeline(pm, optLevel, underscoring);
+ fir::createDefaultFIRCodeGenPassPipeline(
+ pm, optLevel, underscoring, debugInfo);
}
#undef FLANG_EXCLUDE_CODEGEN
#endif
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 49dfeed..9fbf5bb 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -25,6 +25,7 @@
#include "clang/Driver/Options.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Frontend/Debug/Options.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
@@ -117,6 +118,38 @@ bool Fortran::frontend::parseDiagnosticArgs(clang::DiagnosticOptions &opts,
return true;
}
+static bool parseDebugArgs(Fortran::frontend::CodeGenOptions &opts,
+ llvm::opt::ArgList &args,
+ clang::DiagnosticsEngine &diags) {
+ using DebugInfoKind = llvm::codegenoptions::DebugInfoKind;
+ if (llvm::opt::Arg *arg =
+ args.getLastArg(clang::driver::options::OPT_debug_info_kind_EQ)) {
+ std::optional<DebugInfoKind> val =
+ llvm::StringSwitch<std::optional<DebugInfoKind>>(arg->getValue())
+ .Case("line-tables-only", llvm::codegenoptions::DebugLineTablesOnly)
+ .Case("line-directives-only",
+ llvm::codegenoptions::DebugDirectivesOnly)
+ .Case("constructor", llvm::codegenoptions::DebugInfoConstructor)
+ .Case("limited", llvm::codegenoptions::LimitedDebugInfo)
+ .Case("standalone", llvm::codegenoptions::FullDebugInfo)
+ .Case("unused-types", llvm::codegenoptions::UnusedTypeInfo)
+ .Default(std::nullopt);
+ if (!val.has_value()) {
+ diags.Report(clang::diag::err_drv_invalid_value)
+ << arg->getAsString(args) << arg->getValue();
+ return false;
+ }
+ opts.setDebugInfo(val.value());
+ if (val != llvm::codegenoptions::DebugLineTablesOnly &&
+ val != llvm::codegenoptions::NoDebugInfo) {
+ const auto debugWarning = diags.getCustomDiagID(
+ clang::DiagnosticsEngine::Warning, "Unsupported debug option: %0");
+ diags.Report(debugWarning) << arg->getValue();
+ }
+ }
+ return true;
+}
+
static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
llvm::opt::ArgList &args,
clang::DiagnosticsEngine &diags) {
@@ -830,6 +863,7 @@ bool CompilerInvocation::createFromArgs(
parseTargetArgs(res.getTargetOpts(), args);
parsePreprocessorArgs(res.getPreprocessorOpts(), args);
parseCodeGenArgs(res.getCodeGenOpts(), args, diags);
+ success &= parseDebugArgs(res.getCodeGenOpts(), args, diags);
success &= parseSemaArgs(res, args, diags);
success &= parseDialectArgs(res, args, diags);
success &= parseDiagArgs(res, args, diags);
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 8b2055e..3e8bebd 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -662,7 +662,7 @@ void CodeGenAction::generateLLVMIR() {
// Create the pass pipeline
fir::createMLIRToLLVMPassPipeline(pm, level, opts.StackArrays,
- opts.Underscoring);
+ opts.Underscoring, opts.getDebugInfo());
mlir::applyPassManagerCLOptions(pm);
// run the pass manager
diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90
index 535bb82..1a5fb4e 100644
--- a/flang/test/Driver/driver-help-hidden.f90
+++ b/flang/test/Driver/driver-help-hidden.f90
@@ -60,6 +60,8 @@
! CHECK-NEXT: -fsyntax-only Run the preprocessor, parser and semantic analysis stages
! CHECK-NEXT: -funderscoring Appends one trailing underscore to external names
! CHECK-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV.
+! CHECK-NEXT: -gline-tables-only Emit debug line number tables only
+! CHECK-NEXT: -g Generate source-level debug information
! CHECK-NEXT: -help Display available options
! CHECK-NEXT: -I <dir> Add directory to the end of the list of include search paths
! CHECK-NEXT: -mllvm=<arg> Alias for -mllvm
diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90
index a1fdfb3..f50b14e 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -56,6 +56,8 @@
! HELP-NEXT: -fsyntax-only Run the preprocessor, parser and semantic analysis stages
! HELP-NEXT: -funderscoring Appends one trailing underscore to external names
! HELP-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV.
+! HELP-NEXT: -gline-tables-only Emit debug line number tables only
+! HELP-NEXT: -g Generate source-level debug information
! HELP-NEXT: -help Display available options
! HELP-NEXT: -I <dir> Add directory to the end of the list of include search paths
! HELP-NEXT: -mllvm=<arg> Alias for -mllvm
diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90
new file mode 100644
index 0000000..d397b29
--- /dev/null
+++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90
@@ -0,0 +1,83 @@
+! Test the debug pass pipeline
+
+! RUN: %flang -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefixes=ALL,NO-DEBUG %s
+
+! RUN: %flang -g0 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,NO-DEBUG %s
+! RUN: %flang -g -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s
+! RUN: %flang -g1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s
+! RUN: %flang -gline-tables-only -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s
+! RUN: %flang -gline-directives-only -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-DIRECTIVES %s
+! RUN: %flang -g2 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-CONSTRUCT %s
+! RUN: %flang -g3 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-CONSTRUCT %s
+
+! RUN: not %flang_fc1 -debug-info-kind=invalid -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=DEBUG-ERR %s
+
+! REQUIRES: asserts
+
+end program
+
+! DEBUG-CONSTRUCT: warning: Unsupported debug option: constructor
+! DEBUG-DIRECTIVES: warning: Unsupported debug option: line-directives-only
+!
+! DEBUG-ERR: error: invalid value 'invalid' in '-debug-info-kind=invalid'
+! DEBUG-ERR-NOT: Pass statistics report
+
+! ALL: Pass statistics report
+
+! ALL: Fortran::lower::VerifierPass
+! ALL-NEXT: LowerHLFIRIntrinsics
+! ALL-NEXT: BufferizeHLFIR
+! ALL-NEXT: ConvertHLFIRtoFIR
+! ALL-NEXT: CSE
+! Ideally, we need an output with only the pass names, but
+! there is currently no way to get that, so in order to
+! guarantee that the passes are in the expected order
+! (i.e. use -NEXT) we have to check the statistics output as well.
+! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
+! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+
+! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT: ArrayValueCopy
+! ALL-NEXT: CharacterConversion
+
+! ALL-NEXT: Canonicalizer
+! ALL-NEXT: SimplifyRegionLite
+! ALL-NEXT: CSE
+! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
+! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+
+! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT: MemoryAllocationOpt
+
+! ALL-NEXT: Inliner
+! ALL-NEXT: SimplifyRegionLite
+! ALL-NEXT: CSE
+! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
+! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+
+! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT: PolymorphicOpConversion
+! ALL-NEXT: CFGConversion
+
+! ALL-NEXT: SCFToControlFlow
+! ALL-NEXT: Canonicalizer
+! ALL-NEXT: SimplifyRegionLite
+! ALL-NEXT: CSE
+! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
+! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+! ALL-NEXT: BoxedProcedurePass
+
+! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func']
+! ALL-NEXT: 'fir.global' Pipeline
+! ALL-NEXT: AbstractResultOnGlobalOpt
+! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT: AbstractResultOnFuncOpt
+
+! ALL-NEXT: CodeGenRewrite
+! ALL-NEXT: (S) 0 num-dce'd - Number of operations eliminated
+! ALL-NEXT: TargetRewrite
+! ALL-NEXT: ExternalNameConversion
+! DEBUG-NEXT: AddDebugFoundation
+! NO-DEBUG-NOT: AddDebugFoundation
+! ALL-NEXT: FIRToLLVMLowering
+! ALL-NOT: LLVMIRLoweringPass