From e2b7424d06663f92b958c0b4649ed08b55216a49 Mon Sep 17 00:00:00 2001 From: Sacha Ballantyne Date: Mon, 27 Mar 2023 13:12:10 +0000 Subject: [PATCH] [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 --- clang/include/clang/Driver/Options.td | 6 +- clang/lib/Driver/ToolChains/Clang.cpp | 41 +----------- clang/lib/Driver/ToolChains/CommonArgs.cpp | 42 +++++++++++++ clang/lib/Driver/ToolChains/CommonArgs.h | 6 ++ clang/lib/Driver/ToolChains/Flang.cpp | 12 ++++ flang/include/flang/Frontend/CodeGenOptions.def | 1 + flang/include/flang/Frontend/CodeGenOptions.h | 1 + flang/include/flang/Tools/CLOptions.inc | 32 +++++++++- flang/lib/Frontend/CompilerInvocation.cpp | 34 ++++++++++ flang/lib/Frontend/FrontendActions.cpp | 2 +- flang/test/Driver/driver-help-hidden.f90 | 2 + flang/test/Driver/driver-help.f90 | 2 + flang/test/Driver/mlir-debug-pass-pipeline.f90 | 83 +++++++++++++++++++++++++ 13 files changed, 218 insertions(+), 46 deletions(-) create mode 100644 flang/test/Driver/mlir-debug-pass-pipeline.f90 diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 6f3a325d..0cc7052 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3232,9 +3232,9 @@ def femit_dwarf_unwind_EQ : Joined<["-"], "femit-dwarf-unwind=">, NormalizedValuesScope<"llvm::EmitDwarfUnwindType">, MarshallingInfoEnum, "Default">; def g_Flag : Flag<["-"], "g">, Group, - HelpText<"Generate source-level debug information">; + Flags<[CoreOption,FlangOption]>, HelpText<"Generate source-level debug information">; def gline_tables_only : Flag<["-"], "gline-tables-only">, Group, - Flags<[CoreOption]>, HelpText<"Emit debug line number tables only">; + Flags<[CoreOption,FlangOption]>, HelpText<"Emit debug line number tables only">; def gline_directives_only : Flag<["-"], "gline-directives-only">, Group, Flags<[CoreOption]>, HelpText<"Emit debug line info directives only">; def gmlt : Flag<["-"], "gmlt">, Alias; @@ -5466,12 +5466,12 @@ def mrelocation_model : Separate<["-"], "mrelocation-model">, NormalizedValuesScope<"llvm::Reloc">, NormalizedValues<["Static", "PIC_", "ROPI", "RWPI", "ROPI_RWPI", "DynamicNoPIC"]>, MarshallingInfoEnum, "PIC_">; +def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">; } // let Flags = [CC1Option, CC1AsOption, FC1Option, NoDriverOption] let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { -def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">; def debug_info_macro : Flag<["-"], "debug-info-macro">, HelpText<"Emit macro debug information">, MarshallingInfoFlag>; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 873fb35..f5efceb 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -403,22 +403,6 @@ static bool ShouldEnableAutolink(const ArgList &Args, const ToolChain &TC, Default); } -// Convert an arg of the form "-gN" or "-ggdbN" or one of their aliases -// to the corresponding DebugInfoKind. -static llvm::codegenoptions::DebugInfoKind DebugLevelToInfoKind(const Arg &A) { - assert(A.getOption().matches(options::OPT_gN_Group) && - "Not a -g option that specifies a debug-info level"); - if (A.getOption().matches(options::OPT_g0) || - A.getOption().matches(options::OPT_ggdb0)) - return llvm::codegenoptions::NoDebugInfo; - if (A.getOption().matches(options::OPT_gline_tables_only) || - A.getOption().matches(options::OPT_ggdb1)) - return llvm::codegenoptions::DebugLineTablesOnly; - if (A.getOption().matches(options::OPT_gline_directives_only)) - return llvm::codegenoptions::DebugDirectivesOnly; - return llvm::codegenoptions::DebugInfoConstructor; -} - static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) { switch (Triple.getArch()){ default: @@ -977,28 +961,7 @@ RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs, llvm::codegenoptions::DebugInfoKind DebugInfoKind, unsigned DwarfVersion, llvm::DebuggerKind DebuggerTuning) { - switch (DebugInfoKind) { - case llvm::codegenoptions::DebugDirectivesOnly: - CmdArgs.push_back("-debug-info-kind=line-directives-only"); - break; - case llvm::codegenoptions::DebugLineTablesOnly: - CmdArgs.push_back("-debug-info-kind=line-tables-only"); - break; - case llvm::codegenoptions::DebugInfoConstructor: - CmdArgs.push_back("-debug-info-kind=constructor"); - break; - case llvm::codegenoptions::LimitedDebugInfo: - CmdArgs.push_back("-debug-info-kind=limited"); - break; - case llvm::codegenoptions::FullDebugInfo: - CmdArgs.push_back("-debug-info-kind=standalone"); - break; - case llvm::codegenoptions::UnusedTypeInfo: - CmdArgs.push_back("-debug-info-kind=unused-types"); - break; - default: - break; - } + addDebugInfoKind(CmdArgs, DebugInfoKind); if (DwarfVersion > 0) CmdArgs.push_back( Args.MakeArgString("-dwarf-version=" + Twine(DwarfVersion))); @@ -4170,7 +4133,7 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, // If the last option explicitly specified a debug-info level, use it. if (checkDebugInfoOption(A, Args, D, TC) && A->getOption().matches(options::OPT_gN_Group)) { - DebugInfoKind = DebugLevelToInfoKind(*A); + DebugInfoKind = debugLevelToInfoKind(*A); // For -g0 or -gline-tables-only, drop -gsplit-dwarf. This gets a bit more // complicated if you've disabled inline info in the skeleton CUs // (SplitDWARFInlining) - then there's value in composing split-dwarf and diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 7f4d82a..020ae8a 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1584,6 +1584,48 @@ unsigned tools::ParseFunctionAlignment(const ToolChain &TC, return Value ? llvm::Log2_32_Ceil(std::min(Value, 65536u)) : Value; } +void tools::addDebugInfoKind( + ArgStringList &CmdArgs, llvm::codegenoptions::DebugInfoKind DebugInfoKind) { + switch (DebugInfoKind) { + case llvm::codegenoptions::DebugDirectivesOnly: + CmdArgs.push_back("-debug-info-kind=line-directives-only"); + break; + case llvm::codegenoptions::DebugLineTablesOnly: + CmdArgs.push_back("-debug-info-kind=line-tables-only"); + break; + case llvm::codegenoptions::DebugInfoConstructor: + CmdArgs.push_back("-debug-info-kind=constructor"); + break; + case llvm::codegenoptions::LimitedDebugInfo: + CmdArgs.push_back("-debug-info-kind=limited"); + break; + case llvm::codegenoptions::FullDebugInfo: + CmdArgs.push_back("-debug-info-kind=standalone"); + break; + case llvm::codegenoptions::UnusedTypeInfo: + CmdArgs.push_back("-debug-info-kind=unused-types"); + break; + default: + break; + } +} + +// Convert an arg of the form "-gN" or "-ggdbN" or one of their aliases +// to the corresponding DebugInfoKind. +llvm::codegenoptions::DebugInfoKind tools::debugLevelToInfoKind(const Arg &A) { + assert(A.getOption().matches(options::OPT_gN_Group) && + "Not a -g option that specifies a debug-info level"); + if (A.getOption().matches(options::OPT_g0) || + A.getOption().matches(options::OPT_ggdb0)) + return llvm::codegenoptions::NoDebugInfo; + if (A.getOption().matches(options::OPT_gline_tables_only) || + A.getOption().matches(options::OPT_ggdb1)) + return llvm::codegenoptions::DebugLineTablesOnly; + if (A.getOption().matches(options::OPT_gline_directives_only)) + return llvm::codegenoptions::DebugDirectivesOnly; + return llvm::codegenoptions::DebugInfoConstructor; +} + static unsigned ParseDebugDefaultVersion(const ToolChain &TC, const ArgList &Args) { const Arg *A = Args.getLastArg(options::OPT_fdebug_default_version); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index e64e952..50769ef 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -104,6 +104,12 @@ ParsePICArgs(const ToolChain &ToolChain, const llvm::opt::ArgList &Args); unsigned ParseFunctionAlignment(const ToolChain &TC, const llvm::opt::ArgList &Args); +void addDebugInfoKind(llvm::opt::ArgStringList &CmdArgs, + llvm::codegenoptions::DebugInfoKind DebugInfoKind); + +llvm::codegenoptions::DebugInfoKind +debugLevelToInfoKind(const llvm::opt::Arg &A); + // Extract the integer N from a string spelled "-dwarf-N", returning 0 // on mismatch. The StringRef input (rather than an Arg) allows // for use by the "-Xassembler" option parser. diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index cd5782d..79d6dcf 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -11,6 +11,7 @@ #include "CommonArgs.h" #include "clang/Driver/Options.h" +#include "llvm/Frontend/Debug/Options.h" #include @@ -68,6 +69,17 @@ void Flang::addOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const { if (Args.hasArg(options::OPT_flang_experimental_hlfir)) CmdArgs.push_back("-flang-experimental-hlfir"); + + llvm::codegenoptions::DebugInfoKind DebugInfoKind; + if (Args.hasArg(options::OPT_gN_Group)) { + Arg *gNArg = Args.getLastArg(options::OPT_gN_Group); + DebugInfoKind = debugLevelToInfoKind(*gNArg); + } else if (Args.hasArg(options::OPT_g_Flag)) { + DebugInfoKind = llvm::codegenoptions::DebugLineTablesOnly; + } else { + DebugInfoKind = llvm::codegenoptions::NoDebugInfo; + } + addDebugInfoKind(CmdArgs, DebugInfoKind); } void Flang::addPicOptions(const ArgList &Args, ArgStringList &CmdArgs) const { 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( 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 val = + llvm::StringSwitch>(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 Add directory to the end of the list of include search paths ! CHECK-NEXT: -mllvm= 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 Add directory to the end of the list of include search paths ! HELP-NEXT: -mllvm= 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 -- 2.7.4