Skip to content

Commit 863c801

Browse files
Merge pull request #10019 from rastogishubham/MIRStatsStable
This patch adds support for dropped variable statistics in MIR. It cherry-picks: 8c5a048: This patch moved the class DroppedVariableStats code to it's own file and be extensible. It also introduced class DroppedVariableStatsIR that calculates dropped statistics to IR. 7cfb292: This patch moved the class DroppedVariableStatsIR code to it's own file. 0622cd2: This patch adds a PassID to the runOnFunction and runOnModule functions as an argument for easier debuggability. and 999a765: This patch adds class DroppedVariableStatsMIR to calculate dropped variable statistics in MIR. It also moves class DroppedVariableStats and class DroppedVariableStatsIR code to the llvm/IR lib
2 parents e9512bd + 999a765 commit 863c801

15 files changed

+1758
-302
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
///===- DroppedVariableStatsMIR.h - Opt Diagnostics -*- C++ -*-------------===//
2+
///
3+
/// Part of the LLVM Project, under the Apache License v2.0 with LLVM
4+
/// Exceptions. See https://llvm.org/LICENSE.txt for license information.
5+
/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
///
7+
///===---------------------------------------------------------------------===//
8+
/// \file
9+
/// Dropped Variable Statistics for Debug Information. Reports any number
10+
/// of DBG_VALUEs that get dropped due to an optimization pass.
11+
///
12+
///===---------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATSMIR_H
15+
#define LLVM_CODEGEN_DROPPEDVARIABLESTATSMIR_H
16+
17+
#include "llvm/CodeGen/MachineFunction.h"
18+
#include "llvm/IR/DroppedVariableStats.h"
19+
20+
namespace llvm {
21+
22+
/// A class to collect and print dropped debug information due to MIR
23+
/// optimization passes. After every MIR pass is run, it will print how many
24+
/// #DBG_VALUEs were dropped due to that pass.
25+
class DroppedVariableStatsMIR : public DroppedVariableStats {
26+
public:
27+
DroppedVariableStatsMIR() : DroppedVariableStats(false) {}
28+
29+
void runBeforePass(StringRef PassID, MachineFunction *MF);
30+
31+
void runAfterPass(StringRef PassID, MachineFunction *MF);
32+
33+
private:
34+
const MachineFunction *MFunc;
35+
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
36+
/// after a pass has run to facilitate dropped variable calculation for an
37+
/// llvm::MachineFunction.
38+
void runOnMachineFunction(const MachineFunction *MF, bool Before);
39+
/// Iterate over all Instructions in a MachineFunction and report any dropped
40+
/// debug information.
41+
void calculateDroppedVarStatsOnMachineFunction(const MachineFunction *MF,
42+
StringRef PassID,
43+
StringRef FuncOrModName);
44+
/// Override base class method to run on an llvm::MachineFunction
45+
/// specifically.
46+
virtual void
47+
visitEveryInstruction(unsigned &DroppedCount,
48+
DenseMap<VarID, DILocation *> &InlinedAtsMap,
49+
VarID Var) override;
50+
/// Override base class method to run on DBG_VALUEs specifically.
51+
virtual void visitEveryDebugRecord(
52+
DenseSet<VarID> &VarIDSet,
53+
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
54+
StringRef FuncName, bool Before) override;
55+
};
56+
57+
} // namespace llvm
58+
59+
#endif
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
///===- DroppedVariableStats.h - Opt Diagnostics -*- C++ -*----------------===//
2+
///
3+
/// Part of the LLVM Project, under the Apache License v2.0 with LLVM
4+
/// Exceptions. See https://llvm.org/LICENSE.txt for license information.
5+
/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
///
7+
///===---------------------------------------------------------------------===//
8+
/// \file
9+
/// Dropped Variable Statistics for Debug Information. Reports any number
10+
/// of #dbg_value that get dropped due to an optimization pass.
11+
///
12+
///===---------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
15+
#define LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
16+
17+
#include "llvm/ADT/DenseSet.h"
18+
#include "llvm/ADT/SmallVector.h"
19+
#include <tuple>
20+
21+
namespace llvm {
22+
23+
class DIScope;
24+
class DILocalVariable;
25+
class Function;
26+
class DILocation;
27+
class DebugLoc;
28+
class StringRef;
29+
30+
/// A unique key that represents a debug variable.
31+
/// First const DIScope *: Represents the scope of the debug variable.
32+
/// Second const DIScope *: Represents the InlinedAt scope of the debug
33+
/// variable. const DILocalVariable *: It is a pointer to the debug variable
34+
/// itself.
35+
using VarID =
36+
std::tuple<const DIScope *, const DIScope *, const DILocalVariable *>;
37+
38+
/// A base class to collect and print dropped debug information variable
39+
/// statistics.
40+
class DroppedVariableStats {
41+
public:
42+
DroppedVariableStats(bool DroppedVarStatsEnabled);
43+
44+
virtual ~DroppedVariableStats() {}
45+
46+
// We intend this to be unique per-compilation, thus no copies.
47+
DroppedVariableStats(const DroppedVariableStats &) = delete;
48+
void operator=(const DroppedVariableStats &) = delete;
49+
50+
bool getPassDroppedVariables() { return PassDroppedVariables; }
51+
52+
protected:
53+
void setup();
54+
55+
void cleanup();
56+
57+
bool DroppedVariableStatsEnabled = false;
58+
struct DebugVariables {
59+
/// DenseSet of VarIDs before an optimization pass has run.
60+
DenseSet<VarID> DebugVariablesBefore;
61+
/// DenseSet of VarIDs after an optimization pass has run.
62+
DenseSet<VarID> DebugVariablesAfter;
63+
};
64+
65+
/// A stack of a DenseMap, that maps DebugVariables for every pass to an
66+
/// llvm::Function. A stack is used because an optimization pass can call
67+
/// other passes.
68+
SmallVector<DenseMap<const Function *, DebugVariables>> DebugVariablesStack;
69+
70+
/// A DenseSet tracking whether a scope was visited before.
71+
DenseSet<const DIScope *> VisitedScope;
72+
/// A stack of DenseMaps, which map the name of an llvm::Function to a
73+
/// DenseMap of VarIDs and their inlinedAt locations before an optimization
74+
/// pass has run.
75+
SmallVector<DenseMap<StringRef, DenseMap<VarID, DILocation *>>> InlinedAts;
76+
/// Calculate the number of dropped variables in an llvm::Function or
77+
/// llvm::MachineFunction and print the relevant information to stdout.
78+
void calculateDroppedStatsAndPrint(DebugVariables &DbgVariables,
79+
StringRef FuncName, StringRef PassID,
80+
StringRef FuncOrModName,
81+
StringRef PassLevel, const Function *Func);
82+
83+
/// Check if a \p Var has been dropped or is a false positive. Also update the
84+
/// \p DroppedCount if a debug variable is dropped.
85+
bool updateDroppedCount(DILocation *DbgLoc, const DIScope *Scope,
86+
const DIScope *DbgValScope,
87+
DenseMap<VarID, DILocation *> &InlinedAtsMap,
88+
VarID Var, unsigned &DroppedCount);
89+
90+
/// Run code to populate relevant data structures over an llvm::Function or
91+
/// llvm::MachineFunction.
92+
void run(DebugVariables &DbgVariables, StringRef FuncName, bool Before);
93+
94+
/// Populate the VarIDSet and InlinedAtMap with the relevant information
95+
/// needed for before and after pass analysis to determine dropped variable
96+
/// status.
97+
void populateVarIDSetAndInlinedMap(
98+
const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,
99+
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
100+
StringRef FuncName, bool Before);
101+
102+
/// Visit every llvm::Instruction or llvm::MachineInstruction and check if the
103+
/// debug variable denoted by its ID \p Var may have been dropped by an
104+
/// optimization pass.
105+
virtual void
106+
visitEveryInstruction(unsigned &DroppedCount,
107+
DenseMap<VarID, DILocation *> &InlinedAtsMap,
108+
VarID Var) = 0;
109+
/// Visit every debug record in an llvm::Function or llvm::MachineFunction
110+
/// and call populateVarIDSetAndInlinedMap on it.
111+
virtual void visitEveryDebugRecord(
112+
DenseSet<VarID> &VarIDSet,
113+
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
114+
StringRef FuncName, bool Before) = 0;
115+
116+
private:
117+
/// Remove a dropped debug variable's VarID from all Sets in the
118+
/// DroppedVariablesBefore stack.
119+
void removeVarFromAllSets(VarID Var, const Function *F);
120+
121+
/// Return true if \p Scope is the same as \p DbgValScope or a child scope of
122+
/// \p DbgValScope, return false otherwise.
123+
bool isScopeChildOfOrEqualTo(const DIScope *Scope,
124+
const DIScope *DbgValScope);
125+
126+
/// Return true if \p InlinedAt is the same as \p DbgValInlinedAt or part of
127+
/// the InlinedAt chain, return false otherwise.
128+
bool isInlinedAtChildOfOrEqualTo(const DILocation *InlinedAt,
129+
const DILocation *DbgValInlinedAt);
130+
131+
bool PassDroppedVariables = false;
132+
};
133+
134+
} // namespace llvm
135+
136+
#endif
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
///===- DroppedVariableStatsIR.h - Opt Diagnostics -*- C++ -*--------------===//
2+
///
3+
/// Part of the LLVM Project, under the Apache License v2.0 with LLVM
4+
/// Exceptions. See https://llvm.org/LICENSE.txt for license information.
5+
/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
///
7+
///===---------------------------------------------------------------------===//
8+
/// \file
9+
/// Dropped Variable Statistics for Debug Information. Reports any number
10+
/// of #dbg_value that get dropped due to an optimization pass.
11+
///
12+
///===---------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATSIR_H
15+
#define LLVM_CODEGEN_DROPPEDVARIABLESTATSIR_H
16+
17+
#include "llvm/IR/DroppedVariableStats.h"
18+
19+
namespace llvm {
20+
21+
class Any;
22+
class StringRef;
23+
class PassInstrumentationCallbacks;
24+
class Function;
25+
class Module;
26+
class DILocation;
27+
28+
/// A class to collect and print dropped debug information due to LLVM IR
29+
/// optimization passes. After every LLVM IR pass is run, it will print how many
30+
/// #dbg_values were dropped due to that pass.
31+
class DroppedVariableStatsIR : public DroppedVariableStats {
32+
public:
33+
DroppedVariableStatsIR(bool DroppedVarStatsEnabled)
34+
: llvm::DroppedVariableStats(DroppedVarStatsEnabled) {}
35+
36+
void runBeforePass(StringRef P, Any IR);
37+
38+
void runAfterPass(StringRef P, Any IR);
39+
40+
void registerCallbacks(PassInstrumentationCallbacks &PIC);
41+
42+
private:
43+
const Function *Func;
44+
45+
void runAfterPassFunction(StringRef PassID, const Function *F);
46+
47+
void runAfterPassModule(StringRef PassID, const Module *M);
48+
49+
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
50+
/// after a pass has run to facilitate dropped variable calculation for an
51+
/// llvm::Function.
52+
void runOnFunction(StringRef PassID, const Function *F, bool Before);
53+
54+
/// Iterate over all Instructions in a Function and report any dropped debug
55+
/// information.
56+
void calculateDroppedVarStatsOnFunction(const Function *F, StringRef PassID,
57+
StringRef FuncOrModName,
58+
StringRef PassLevel);
59+
60+
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
61+
/// after a pass has run to facilitate dropped variable calculation for an
62+
/// llvm::Module. Calls runOnFunction on every Function in the Module.
63+
void runOnModule(StringRef PassID, const Module *M, bool Before);
64+
65+
/// Iterate over all Functions in a Module and report any dropped debug
66+
/// information. Will call calculateDroppedVarStatsOnFunction on every
67+
/// Function.
68+
void calculateDroppedVarStatsOnModule(const Module *M, StringRef PassID,
69+
StringRef FuncOrModName,
70+
StringRef PassLevel);
71+
72+
/// Override base class method to run on an llvm::Function specifically.
73+
virtual void
74+
visitEveryInstruction(unsigned &DroppedCount,
75+
DenseMap<VarID, DILocation *> &InlinedAtsMap,
76+
VarID Var) override;
77+
78+
/// Override base class method to run on #dbg_values specifically.
79+
virtual void visitEveryDebugRecord(
80+
DenseSet<VarID> &VarIDSet,
81+
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
82+
StringRef FuncName, bool Before) override;
83+
84+
template <typename IRUnitT> static const IRUnitT *unwrapIR(Any IR);
85+
};
86+
87+
} // namespace llvm
88+
89+
#endif

llvm/include/llvm/Passes/StandardInstrumentations.h

Lines changed: 2 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/CodeGen/MachineBasicBlock.h"
2323
#include "llvm/IR/BasicBlock.h"
2424
#include "llvm/IR/DebugInfoMetadata.h"
25+
#include "llvm/IR/DroppedVariableStatsIR.h"
2526
#include "llvm/IR/OptBisect.h"
2627
#include "llvm/IR/PassTimingInfo.h"
2728
#include "llvm/IR/ValueHandle.h"
@@ -579,83 +580,6 @@ class PrintCrashIRInstrumentation {
579580
static void SignalHandler(void *);
580581
};
581582

582-
/// A class to collect and print dropped debug information variable statistics.
583-
/// After every LLVM IR pass is run, it will print how many #dbg_values were
584-
/// dropped due to that pass.
585-
class DroppedVariableStats {
586-
public:
587-
DroppedVariableStats(bool DroppedVarStatsEnabled) {
588-
if (DroppedVarStatsEnabled)
589-
llvm::outs()
590-
<< "Pass Level, Pass Name, Num of Dropped Variables, Func or "
591-
"Module Name\n";
592-
};
593-
// We intend this to be unique per-compilation, thus no copies.
594-
DroppedVariableStats(const DroppedVariableStats &) = delete;
595-
void operator=(const DroppedVariableStats &) = delete;
596-
597-
void registerCallbacks(PassInstrumentationCallbacks &PIC);
598-
void runBeforePass(StringRef PassID, Any IR);
599-
void runAfterPass(StringRef PassID, Any IR, const PreservedAnalyses &PA);
600-
void runAfterPassInvalidated(StringRef PassID, const PreservedAnalyses &PA);
601-
bool getPassDroppedVariables() { return PassDroppedVariables; }
602-
603-
private:
604-
bool PassDroppedVariables = false;
605-
/// A unique key that represents a #dbg_value.
606-
using VarID =
607-
std::tuple<const DIScope *, const DIScope *, const DILocalVariable *>;
608-
609-
struct DebugVariables {
610-
/// DenseSet of VarIDs before an optimization pass has run.
611-
DenseSet<VarID> DebugVariablesBefore;
612-
/// DenseSet of VarIDs after an optimization pass has run.
613-
DenseSet<VarID> DebugVariablesAfter;
614-
};
615-
616-
/// A stack of a DenseMap, that maps DebugVariables for every pass to an
617-
/// llvm::Function. A stack is used because an optimization pass can call
618-
/// other passes.
619-
SmallVector<DenseMap<const Function *, DebugVariables>> DebugVariablesStack;
620-
621-
/// A DenseSet tracking whether a scope was visited before.
622-
DenseSet<const DIScope *> VisitedScope;
623-
/// A stack of DenseMaps, which map the name of an llvm::Function to a
624-
/// DenseMap of VarIDs and their inlinedAt locations before an optimization
625-
/// pass has run.
626-
SmallVector<DenseMap<StringRef, DenseMap<VarID, DILocation *>>> InlinedAts;
627-
628-
/// Iterate over all Functions in a Module and report any dropped debug
629-
/// information. Will call calculateDroppedVarStatsOnFunction on every
630-
/// Function.
631-
void calculateDroppedVarStatsOnModule(const Module *M, StringRef PassID,
632-
std::string FuncOrModName,
633-
std::string PassLevel);
634-
/// Iterate over all Instructions in a Function and report any dropped debug
635-
/// information.
636-
void calculateDroppedVarStatsOnFunction(const Function *F, StringRef PassID,
637-
std::string FuncOrModName,
638-
std::string PassLevel);
639-
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
640-
/// after a pass has run to facilitate dropped variable calculation for an
641-
/// llvm::Function.
642-
void runOnFunction(const Function *F, bool Before);
643-
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
644-
/// after a pass has run to facilitate dropped variable calculation for an
645-
/// llvm::Module. Calls runOnFunction on every Function in the Module.
646-
void runOnModule(const Module *M, bool Before);
647-
/// Remove a dropped #dbg_value VarID from all Sets in the
648-
/// DroppedVariablesBefore stack.
649-
void removeVarFromAllSets(VarID Var, const Function *F);
650-
/// Return true if \p Scope is the same as \p DbgValScope or a child scope of
651-
/// \p DbgValScope, return false otherwise.
652-
bool isScopeChildOfOrEqualTo(DIScope *Scope, const DIScope *DbgValScope);
653-
/// Return true if \p InlinedAt is the same as \p DbgValInlinedAt or part of
654-
/// the InlinedAt chain, return false otherwise.
655-
bool isInlinedAtChildOfOrEqualTo(const DILocation *InlinedAt,
656-
const DILocation *DbgValInlinedAt);
657-
};
658-
659583
/// This class provides an interface to register all the standard pass
660584
/// instrumentations and manages their state (if any).
661585
class StandardInstrumentations {
@@ -673,7 +597,7 @@ class StandardInstrumentations {
673597
PrintCrashIRInstrumentation PrintCrashIR;
674598
IRChangedTester ChangeTester;
675599
VerifyInstrumentation Verify;
676-
DroppedVariableStats DroppedStats;
600+
DroppedVariableStatsIR DroppedStatsIR;
677601

678602
bool VerifyEach;
679603

llvm/lib/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ add_llvm_component_library(LLVMCodeGen
5050
DeadMachineInstructionElim.cpp
5151
DetectDeadLanes.cpp
5252
DFAPacketizer.cpp
53+
DroppedVariableStatsMIR.cpp
5354
DwarfEHPrepare.cpp
5455
EarlyIfConversion.cpp
5556
EdgeBundles.cpp

0 commit comments

Comments
 (0)