Skip to content

Commit 793249c

Browse files
Add a pass to collect dropped variable statistics
Add an instrumentation pass to llvm to collect dropped debug information variable statistics for every Function-level and Module-level IR pass.
1 parent 1fb1a5d commit 793249c

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

llvm/include/llvm/Passes/StandardInstrumentations.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,35 @@ class DotCfgChangeReporter : public ChangeReporter<IRDataT<DCData>> {
559559
std::unique_ptr<raw_fd_ostream> HTML;
560560
};
561561

562+
class DroppedVariableStats {
563+
public:
564+
DroppedVariableStats() {
565+
llvm::outs() << "Pass Level, Pass Name, Num of Dropped Variables, Func or "
566+
"Module Name\n";
567+
};
568+
// We intend this to be unique per-compilation, thus no copies.
569+
DroppedVariableStats(const DroppedVariableStats &) = delete;
570+
void operator=(const DroppedVariableStats &) = delete;
571+
572+
void registerCallbacks(PassInstrumentationCallbacks &PIC);
573+
574+
private:
575+
using VarID =
576+
std::tuple<const DILocalScope *, llvm::StringRef, unsigned, unsigned>;
577+
578+
SmallVector<std::pair<llvm::DenseSet<VarID>, std::string>>
579+
DebugVariablesBefore;
580+
SmallVector<std::pair<llvm::DenseSet<VarID>, std::string>>
581+
DebugVariablesAfter;
582+
583+
// Implementation of pass instrumentation callbacks.
584+
void runBeforePass(StringRef PassID, Any IR);
585+
void runAfterPass(StringRef PassID, Any IR, const PreservedAnalyses &PA);
586+
587+
void runOnFunction(const Function *F, bool Before);
588+
void runOnModule(const Module *M, bool Before);
589+
};
590+
562591
// Print IR on crash.
563592
class PrintCrashIRInstrumentation {
564593
public:
@@ -595,6 +624,7 @@ class StandardInstrumentations {
595624
PrintCrashIRInstrumentation PrintCrashIR;
596625
IRChangedTester ChangeTester;
597626
VerifyInstrumentation Verify;
627+
DroppedVariableStats DroppedStats;
598628

599629
bool VerifyEach;
600630

llvm/lib/Passes/StandardInstrumentations.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/Demangle/Demangle.h"
2626
#include "llvm/IR/Constants.h"
2727
#include "llvm/IR/Function.h"
28+
#include "llvm/IR/IntrinsicInst.h"
2829
#include "llvm/IR/Module.h"
2930
#include "llvm/IR/PassInstrumentation.h"
3031
#include "llvm/IR/PassManager.h"
@@ -139,6 +140,11 @@ static cl::opt<std::string> IRDumpDirectory(
139140
"files in this directory rather than written to stderr"),
140141
cl::Hidden, cl::value_desc("filename"));
141142

143+
static cl::opt<bool>
144+
DroppedVarStats("dropped-variable-stats", cl::Hidden,
145+
cl::desc("Dump dropped debug variables stats"),
146+
cl::init(false));
147+
142148
template <typename IRUnitT> static const IRUnitT *unwrapIR(Any IR) {
143149
const IRUnitT **IRPtr = llvm::any_cast<const IRUnitT *>(&IR);
144150
return IRPtr ? *IRPtr : nullptr;
@@ -2441,6 +2447,84 @@ void DotCfgChangeReporter::registerCallbacks(
24412447
}
24422448
}
24432449

2450+
void DroppedVariableStats::registerCallbacks(
2451+
PassInstrumentationCallbacks &PIC) {
2452+
if (!DroppedVarStats)
2453+
return;
2454+
2455+
PIC.registerBeforeNonSkippedPassCallback(
2456+
[this](StringRef P, Any IR) { return this->runBeforePass(P, IR); });
2457+
PIC.registerAfterPassCallback(
2458+
[this](StringRef P, Any IR, const PreservedAnalyses &PA) {
2459+
return this->runAfterPass(P, IR, PA);
2460+
});
2461+
}
2462+
2463+
void DroppedVariableStats::runBeforePass(StringRef PassID, Any IR) {
2464+
DebugVariablesBefore.push_back(
2465+
std::make_pair(llvm::DenseSet<VarID>(), PassID.str()));
2466+
DebugVariablesAfter.push_back(
2467+
std::make_pair(llvm::DenseSet<VarID>(), PassID.str()));
2468+
if (auto *M = unwrapIR<Module>(IR))
2469+
return this->runOnModule(M, true);
2470+
if (auto *F = unwrapIR<Function>(IR))
2471+
return this->runOnFunction(F, true);
2472+
return;
2473+
}
2474+
2475+
void DroppedVariableStats::runOnFunction(const Function *F, bool Before) {
2476+
auto &DebugVariables = Before ? DebugVariablesBefore : DebugVariablesAfter;
2477+
for (auto &BB : *F) {
2478+
for (const Instruction &I : BB) {
2479+
for (DbgRecord &DR : I.getDbgRecordRange()) {
2480+
if (auto *Dbg = dyn_cast<DbgVariableRecord>(&DR)) {
2481+
llvm::StringRef UniqueName = Dbg->getVariable()->getName();
2482+
auto DbgLoc = DR.getDebugLoc();
2483+
unsigned Line = DbgLoc.getLine();
2484+
unsigned Col = DbgLoc->getColumn();
2485+
VarID Key(cast<DILocalScope>(DbgLoc.getScope()), UniqueName, Line,
2486+
Col);
2487+
DebugVariables.back().first.insert(Key);
2488+
}
2489+
}
2490+
}
2491+
}
2492+
}
2493+
2494+
void DroppedVariableStats::runOnModule(const Module *M, bool Before) {
2495+
for (auto &F : *M)
2496+
runOnFunction(&F, Before);
2497+
}
2498+
2499+
void DroppedVariableStats::runAfterPass(StringRef PassID, Any IR,
2500+
const PreservedAnalyses &PA) {
2501+
assert(DebugVariablesBefore.back().second ==
2502+
DebugVariablesAfter.back().second);
2503+
unsigned DroppedCount = 0;
2504+
std::string PassLevel = "";
2505+
std::string FuncOrModName = "";
2506+
if (auto *M = unwrapIR<Module>(IR)) {
2507+
this->runOnModule(M, false);
2508+
PassLevel = "Module";
2509+
FuncOrModName = M->getName();
2510+
} else if (auto *F = unwrapIR<Function>(IR)) {
2511+
this->runOnFunction(F, false);
2512+
PassLevel = "Function";
2513+
FuncOrModName = F->getName();
2514+
} else {
2515+
return;
2516+
}
2517+
for (auto Var : DebugVariablesBefore.back().first)
2518+
if (!DebugVariablesAfter.back().first.contains(Var))
2519+
DroppedCount++;
2520+
if (DroppedCount > 0)
2521+
llvm::outs() << PassLevel << ", " << PassID << ", " << DroppedCount << ", "
2522+
<< FuncOrModName << "\n";
2523+
DebugVariablesBefore.pop_back();
2524+
DebugVariablesAfter.pop_back();
2525+
return;
2526+
}
2527+
24442528
StandardInstrumentations::StandardInstrumentations(
24452529
LLVMContext &Context, bool DebugLogging, bool VerifyEach,
24462530
PrintPassOptions PrintPassOpts)
@@ -2528,6 +2612,7 @@ void StandardInstrumentations::registerCallbacks(
25282612
WebsiteChangeReporter.registerCallbacks(PIC);
25292613
ChangeTester.registerCallbacks(PIC);
25302614
PrintCrashIR.registerCallbacks(PIC);
2615+
DroppedStats.registerCallbacks(PIC);
25312616
if (MAM)
25322617
PreservedCFGChecker.registerCallbacks(PIC, *MAM);
25332618

0 commit comments

Comments
 (0)