diff options
author | Sacha Ballantyne <Sacha.Ballantyne@arm.com> | 2023-03-27 13:12:10 +0000 |
---|---|---|
committer | Sacha Ballantyne <Sacha.Ballantyne@arm.com> | 2023-03-29 12:21:26 +0000 |
commit | e2b7424d06663f92b958c0b4649ed08b55216a49 (patch) | |
tree | cd3c6c6efe6befab936c78f3a246a88e2aa163cb /flang | |
parent | 6b6f312ccedff8322e246f9022148a5bc8805ae5 (diff) | |
download | llvm-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.def | 1 | ||||
-rw-r--r-- | flang/include/flang/Frontend/CodeGenOptions.h | 1 | ||||
-rw-r--r-- | flang/include/flang/Tools/CLOptions.inc | 32 | ||||
-rw-r--r-- | flang/lib/Frontend/CompilerInvocation.cpp | 34 | ||||
-rw-r--r-- | flang/lib/Frontend/FrontendActions.cpp | 2 | ||||
-rw-r--r-- | flang/test/Driver/driver-help-hidden.f90 | 2 | ||||
-rw-r--r-- | flang/test/Driver/driver-help.f90 | 2 | ||||
-rw-r--r-- | flang/test/Driver/mlir-debug-pass-pipeline.f90 | 83 |
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 |