diff --git a/llvm/include/llvm/Transforms/Utils/Debugify.h b/llvm/include/llvm/Transforms/Utils/Debugify.h --- a/llvm/include/llvm/Transforms/Utils/Debugify.h +++ b/llvm/include/llvm/Transforms/Utils/Debugify.h @@ -92,6 +92,12 @@ llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM); }; +struct DebugifyEachInstrumentation { + DebugifyStatsMap StatsMap; + + void registerCallbacks(PassInstrumentationCallbacks &PIC); +}; + /// DebugifyCustomPassManager wraps each pass with the debugify passes if /// needed. /// NOTE: We support legacy custom pass manager only. diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp b/llvm/lib/Transforms/Utils/Debugify.cpp --- a/llvm/lib/Transforms/Utils/Debugify.cpp +++ b/llvm/lib/Transforms/Utils/Debugify.cpp @@ -198,6 +198,18 @@ return true; } +static bool applyDebugify(Function &F) { + Module &M = *F.getParent(); + auto FuncIt = F.getIterator(); + return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)), + "FunctionDebugify: ", /*ApplyToMF=*/nullptr); +} + +static bool applyDebugify(Module &M) { + return applyDebugifyMetadata(M, M.functions(), + "ModuleDebugify: ", /*ApplyToMF=*/nullptr); +} + bool llvm::stripDebugifyMetadata(Module &M) { bool Changed = false; @@ -383,10 +395,7 @@ /// ModulePass for attaching synthetic debug info to everything, used with the /// legacy module pass manager. struct DebugifyModulePass : public ModulePass { - bool runOnModule(Module &M) override { - return applyDebugifyMetadata(M, M.functions(), - "ModuleDebugify: ", /*ApplyToMF*/ nullptr); - } + bool runOnModule(Module &M) override { return applyDebugify(M); } DebugifyModulePass() : ModulePass(ID) {} @@ -400,12 +409,7 @@ /// FunctionPass for attaching synthetic debug info to instructions within a /// single function, used with the legacy module pass manager. struct DebugifyFunctionPass : public FunctionPass { - bool runOnFunction(Function &F) override { - Module &M = *F.getParent(); - auto FuncIt = F.getIterator(); - return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)), - "FunctionDebugify: ", /*ApplyToMF*/ nullptr); - } + bool runOnFunction(Function &F) override { return applyDebugify(F); } DebugifyFunctionPass() : FunctionPass(ID) {} @@ -526,6 +530,30 @@ return PreservedAnalyses::all(); } +void DebugifyEachInstrumentation::registerCallbacks( + PassInstrumentationCallbacks &PIC) { + PIC.registerBeforeNonSkippedPassCallback([](StringRef P, Any IR) { + if (any_isa(IR)) + applyDebugify(*const_cast(any_cast(IR))); + else if (any_isa(IR)) + applyDebugify(*const_cast(any_cast(IR))); + }); + PIC.registerAfterPassCallback([this](StringRef P, Any IR, + const PreservedAnalyses &PassPA) { + if (any_isa(IR)) { + auto &F = *const_cast(any_cast(IR)); + Module &M = *F.getParent(); + auto It = F.getIterator(); + checkDebugifyMetadata(M, make_range(It, std::next(It)), P, + "CheckFunctionDebugify", /*Strip=*/true, &StatsMap); + } else if (any_isa(IR)) { + auto &M = *const_cast(any_cast(IR)); + checkDebugifyMetadata(M, M.functions(), P, "CheckModuleDebugify", + /*Strip=*/true, &StatsMap); + } + }); +} + char DebugifyModulePass::ID = 0; static RegisterPass DM("debugify", "Attach debug info to everything"); diff --git a/llvm/test/DebugInfo/debugify-each.ll b/llvm/test/DebugInfo/debugify-each.ll --- a/llvm/test/DebugInfo/debugify-each.ll +++ b/llvm/test/DebugInfo/debugify-each.ll @@ -1,6 +1,9 @@ ; RUN: opt -debugify-each -O3 -S -o /dev/null < %s 2> %t ; RUN: FileCheck %s -input-file=%t -check-prefix=MODULE-PASS ; RUN: FileCheck %s -input-file=%t -check-prefix=FUNCTION-PASS +; RUN: opt -disable-output -debugify-each -passes='default' %s 2> %t +; RUN: FileCheck %s -input-file=%t -check-prefix=MODULE-PASS +; RUN: FileCheck %s -input-file=%t -check-prefix=FUNCTION-PASS ; RUN: opt -enable-debugify -debugify-each -O3 -S -o /dev/null < %s 2> %t ; RUN: FileCheck %s -input-file=%t -check-prefix=MODULE-PASS diff --git a/llvm/test/DebugInfo/debugify-export.ll b/llvm/test/DebugInfo/debugify-export.ll --- a/llvm/test/DebugInfo/debugify-export.ll +++ b/llvm/test/DebugInfo/debugify-export.ll @@ -1,4 +1,5 @@ -; RUN: opt < %s -debugify-each -debugify-quiet -debugify-export - -o /dev/null | FileCheck %s +; RUN: opt %s -disable-output -debugify-each -debugify-quiet -debugify-export - -enable-new-pm=0 | FileCheck %s +; RUN: opt %s -disable-output -debugify-each -debugify-quiet -debugify-export - -enable-new-pm=1 | FileCheck %s ; CHECK: Pass Name ; CHECK-SAME: # of missing debug values @@ -6,7 +7,7 @@ ; CHECK-SAME: Missing/Expected value ratio ; CHECK-SAME: Missing/Expected location ratio -; CHECK: Module Verifier +; CHECK: {{Module Verifier|VerifierPass}} ; CHECK-SAME: 0,0,0.000000e+00,0.000000e+00 define void @foo() { diff --git a/llvm/test/DebugInfo/pr37964.ll b/llvm/test/DebugInfo/pr37964.ll --- a/llvm/test/DebugInfo/pr37964.ll +++ b/llvm/test/DebugInfo/pr37964.ll @@ -1,7 +1,7 @@ -; RUN: opt -disable-output -debugify-each -gvn < %s 2>&1 | FileCheck %s +; RUN: opt -disable-output -debugify-each -passes=gvn < %s 2>&1 | FileCheck %s ; CHECK-NOT: ERROR: Instruction with empty DebugLoc in function _Z3bazv -- {{%.*}} = phi -; CHECK: CheckFunctionDebugify [Global Value Numbering]: PASS +; CHECK: CheckFunctionDebugify [GVN]: PASS @foo = dso_local local_unnamed_addr global i32 0, align 4 @x = global i8 17 diff --git a/llvm/tools/opt/NewPMDriver.h b/llvm/tools/opt/NewPMDriver.h --- a/llvm/tools/opt/NewPMDriver.h +++ b/llvm/tools/opt/NewPMDriver.h @@ -21,6 +21,7 @@ #define LLVM_TOOLS_OPT_NEWPMDRIVER_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/CommandLine.h" namespace llvm { class StringRef; @@ -29,6 +30,9 @@ class ToolOutputFile; class TargetLibraryInfoImpl; +extern cl::opt DebugifyEach; +extern cl::opt DebugifyExport; + namespace opt_tool { enum OutputKind { OK_NoOutput, diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -30,7 +30,6 @@ #include "llvm/Passes/PassBuilder.h" #include "llvm/Passes/PassPlugin.h" #include "llvm/Passes/StandardInstrumentations.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Target/TargetMachine.h" @@ -42,6 +41,17 @@ using namespace llvm; using namespace opt_tool; +namespace llvm { +cl::opt DebugifyEach( + "debugify-each", + cl::desc("Start each pass with debugify and end it with check-debugify")); + +cl::opt + DebugifyExport("debugify-export", + cl::desc("Export per-pass debugify statistics to this file"), + cl::value_desc("filename")); +} // namespace llvm + static cl::opt DebugPM("debug-pass-manager", cl::Hidden, cl::desc("Print pass management debugging information")); @@ -249,6 +259,9 @@ PassInstrumentationCallbacks PIC; StandardInstrumentations SI(DebugPM, VerifyEachPass); SI.registerCallbacks(PIC); + DebugifyEachInstrumentation Debugify; + if (DebugifyEach) + Debugify.registerCallbacks(PIC); PipelineTuningOptions PTO; // LoopUnrolling defaults on to true and DisableLoopUnrolling is initialized @@ -421,5 +434,8 @@ if (OptRemarkFile) OptRemarkFile->keep(); + if (DebugifyEach && !DebugifyExport.empty()) + exportDebugifyStats(DebugifyExport, Debugify.StatsMap); + return true; } diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp --- a/llvm/tools/opt/opt.cpp +++ b/llvm/tools/opt/opt.cpp @@ -209,16 +209,6 @@ cl::desc( "Start the pipeline with debugify and end it with check-debugify")); -static cl::opt DebugifyEach( - "debugify-each", - cl::desc( - "Start each pass with debugify and end it with check-debugify")); - -static cl::opt - DebugifyExport("debugify-export", - cl::desc("Export per-pass debugify statistics to this file"), - cl::value_desc("filename"), cl::init("")); - static cl::opt PrintBreakpoints("print-breakpoints-for-testing", cl::desc("Print select breakpoints location for testing"));