23
23
24
24
namespace llvm {
25
25
26
- // / A class to collect and print dropped debug information variable statistics.
27
- // / After every LLVM IR pass is run, it will print how many #dbg_values were
28
- // / dropped due to that pass.
26
+ // / A unique key that represents a #dbg_value.
27
+ using VarID =
28
+ std::tuple<const DIScope *, const DIScope *, const DILocalVariable *>;
29
+
30
+ // / A base class to collect and print dropped debug information variable
31
+ // / statistics.
29
32
class DroppedVariableStats {
30
33
public:
31
34
DroppedVariableStats (bool DroppedVarStatsEnabled)
@@ -35,22 +38,32 @@ class DroppedVariableStats {
35
38
<< " Pass Level, Pass Name, Num of Dropped Variables, Func or "
36
39
" Module Name\n " ;
37
40
};
41
+
42
+ virtual ~DroppedVariableStats () = default ;
43
+
38
44
// We intend this to be unique per-compilation, thus no copies.
39
45
DroppedVariableStats (const DroppedVariableStats &) = delete ;
40
46
void operator =(const DroppedVariableStats &) = delete ;
41
47
42
- void registerCallbacks (PassInstrumentationCallbacks &PIC);
43
- void runBeforePass (StringRef PassID, Any IR);
44
- void runAfterPass (StringRef PassID, Any IR, const PreservedAnalyses &PA);
45
- void runAfterPassInvalidated (StringRef PassID, const PreservedAnalyses &PA);
46
48
bool getPassDroppedVariables () { return PassDroppedVariables; }
47
49
48
- private:
50
+ protected:
51
+ void setup () {
52
+ DebugVariablesStack.push_back (
53
+ {DenseMap<const Function *, DebugVariables>()});
54
+ InlinedAts.push_back (
55
+ {DenseMap<StringRef, DenseMap<VarID, DILocation *>>()});
56
+ return ;
57
+ }
58
+
59
+ void cleanup () {
60
+ DebugVariablesStack.pop_back ();
61
+ InlinedAts.pop_back ();
62
+ return ;
63
+ }
64
+
49
65
bool PassDroppedVariables = false ;
50
66
bool DroppedVariableStatsEnabled = false ;
51
- // / A unique key that represents a #dbg_value.
52
- using VarID =
53
- std::tuple<const DIScope *, const DIScope *, const DILocalVariable *>;
54
67
55
68
struct DebugVariables {
56
69
// / DenseSet of VarIDs before an optimization pass has run.
@@ -70,36 +83,131 @@ class DroppedVariableStats {
70
83
// / DenseMap of VarIDs and their inlinedAt locations before an optimization
71
84
// / pass has run.
72
85
SmallVector<DenseMap<StringRef, DenseMap<VarID, DILocation *>>> InlinedAts;
86
+ // / Remove a dropped #dbg_value VarID from all Sets in the
87
+ // / DroppedVariablesBefore stack.
88
+ void removeVarFromAllSets (VarID Var, const Function *F) {
89
+ // Do not remove Var from the last element, it will be popped from the
90
+ // stack.
91
+ for (auto &DebugVariablesMap : llvm::drop_end (DebugVariablesStack))
92
+ DebugVariablesMap[F].DebugVariablesBefore .erase (Var);
93
+ }
94
+ // / Return true if \p Scope is the same as \p DbgValScope or a child scope of
95
+ // / \p DbgValScope, return false otherwise.
96
+ bool isScopeChildOfOrEqualTo (const DIScope *Scope,
97
+ const DIScope *DbgValScope);
98
+ // / Return true if \p InlinedAt is the same as \p DbgValInlinedAt or part of
99
+ // / the InlinedAt chain, return false otherwise.
100
+ bool isInlinedAtChildOfOrEqualTo (const DILocation *InlinedAt,
101
+ const DILocation *DbgValInlinedAt);
73
102
74
- // / Iterate over all Functions in a Module and report any dropped debug
75
- // / information. Will call calculateDroppedVarStatsOnFunction on every
76
- // / Function.
77
- void calculateDroppedVarStatsOnModule (const Module *M, StringRef PassID,
78
- std::string FuncOrModName,
79
- std::string PassLevel);
80
- // / Iterate over all Instructions in a Function and report any dropped debug
81
- // / information.
82
- void calculateDroppedVarStatsOnFunction (const Function *F, StringRef PassID,
83
- std::string FuncOrModName,
84
- std::string PassLevel);
103
+ // / Calculate the number of dropped variables in an llvm::Function or
104
+ // / llvm::MachineFunction and print the relevant information to stdout.
105
+ void calculateDroppedStatsAndPrint (DebugVariables &DbgVariables,
106
+ StringRef FuncName, StringRef PassID,
107
+ StringRef FuncOrModName,
108
+ StringRef PassLevel);
109
+
110
+ // / Check if a \p Var has been dropped or is a false positive.
111
+ bool checkDroppedStatus (DILocation *DbgLoc, const DIScope *Scope,
112
+ const DIScope *DbgValScope,
113
+ DenseMap<VarID, DILocation *> &InlinedAtsMap,
114
+ VarID Var);
115
+ // / Run code to populate relevant data structures over an llvm::Function or
116
+ // / llvm::MachineFunction.
117
+ void run (DebugVariables &DbgVariables, StringRef FuncName, bool Before);
118
+ // / Populate the VarIDSet and InlinedAtMap with the relevant information
119
+ // / needed for before and after pass analysis to determine dropped variable
120
+ // / status.
121
+ void populateVarIDSetAndInlinedMap (
122
+ const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,
123
+ DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
124
+ StringRef FuncName, bool Before);
125
+ // / Visit every VarID in the \p DebugVariablesBeforeSet and check if it may
126
+ // / have been dropped by an optimization pass.
127
+ virtual void
128
+ visitEveryDebugVariable (unsigned &DroppedCount,
129
+ DenseSet<VarID> &DebugVariablesBeforeSet,
130
+ DenseSet<VarID> &DebugVariablesAfterSet,
131
+ DenseMap<VarID, DILocation *> &InlinedAtsMap) = 0 ;
132
+ // / Visit every debug intrinsic in an llvm::Function or llvm::MachineFunction
133
+ // / to populate relevant data structures to determine dropped variable status.
134
+ virtual void visitEveryDebugIntrinsic (
135
+ DenseSet<VarID> &VarIDSet,
136
+ DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
137
+ StringRef FuncName, bool Before) = 0;
138
+ };
139
+
140
+ // / A class to collect and print dropped debug information due to LLVM IR
141
+ // / optimization passes. After every LLVM IR pass is run, it will print how many
142
+ // / #dbg_values were dropped due to that pass.
143
+ class DroppedVariableStatsIR : public DroppedVariableStats {
144
+ public:
145
+ DroppedVariableStatsIR (bool DroppedVarStatsEnabled)
146
+ : llvm::DroppedVariableStats(DroppedVarStatsEnabled) {}
147
+
148
+ virtual ~DroppedVariableStatsIR () = default ;
149
+
150
+ void runBeforePass (Any IR) {
151
+ setup ();
152
+ if (const auto *M = unwrapIR<Module>(IR))
153
+ return this ->runOnModule (M, true );
154
+ if (const auto *F = unwrapIR<Function>(IR))
155
+ return this ->runOnFunction (F, true );
156
+ }
157
+
158
+ void runAfterPass (StringRef P, Any IR) {
159
+ if (const auto *M = unwrapIR<Module>(IR))
160
+ runAfterPassModule (P, M);
161
+ else if (const auto *F = unwrapIR<Function>(IR))
162
+ runAfterPassFunction (P, F);
163
+ return cleanup ();
164
+ }
165
+
166
+ void registerCallbacks (PassInstrumentationCallbacks &PIC);
167
+
168
+ private:
169
+ const Function *Func;
170
+
171
+ void runAfterPassFunction (StringRef PassID, const Function *F) {
172
+ runOnFunction (F, false );
173
+ calculateDroppedVarStatsOnFunction (F, PassID, F->getName ().str (),
174
+ " Function" );
175
+ }
176
+
177
+ void runAfterPassModule (StringRef PassID, const Module *M) {
178
+ runOnModule (M, false );
179
+ calculateDroppedVarStatsOnModule (M, PassID, M->getName ().str (), " Module" );
180
+ }
85
181
// / Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
86
182
// / after a pass has run to facilitate dropped variable calculation for an
87
183
// / llvm::Function.
88
184
void runOnFunction (const Function *F, bool Before);
185
+ // / Iterate over all Instructions in a Function and report any dropped debug
186
+ // / information.
187
+ void calculateDroppedVarStatsOnFunction (const Function *F, StringRef PassID,
188
+ StringRef FuncOrModName,
189
+ StringRef PassLevel);
89
190
// / Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
90
191
// / after a pass has run to facilitate dropped variable calculation for an
91
192
// / llvm::Module. Calls runOnFunction on every Function in the Module.
92
193
void runOnModule (const Module *M, bool Before);
93
- // / Remove a dropped #dbg_value VarID from all Sets in the
94
- // / DroppedVariablesBefore stack.
95
- void removeVarFromAllSets (VarID Var, const Function *F);
96
- // / Return true if \p Scope is the same as \p DbgValScope or a child scope of
97
- // / \p DbgValScope, return false otherwise.
98
- bool isScopeChildOfOrEqualTo (DIScope *Scope, const DIScope *DbgValScope);
99
- // / Return true if \p InlinedAt is the same as \p DbgValInlinedAt or part of
100
- // / the InlinedAt chain, return false otherwise.
101
- bool isInlinedAtChildOfOrEqualTo (const DILocation *InlinedAt,
102
- const DILocation *DbgValInlinedAt);
194
+ // / Iterate over all Functions in a Module and report any dropped debug
195
+ // / information. Will call calculateDroppedVarStatsOnFunction on every
196
+ // / Function.
197
+ void calculateDroppedVarStatsOnModule (const Module *M, StringRef PassID,
198
+ StringRef FuncOrModName,
199
+ StringRef PassLevel);
200
+ // / Override base class method to run on an llvm::Function specifically.
201
+ virtual void visitEveryDebugVariable (
202
+ unsigned &DroppedCount, DenseSet<VarID> &DebugVariablesBeforeSet,
203
+ DenseSet<VarID> &DebugVariablesAfterSet,
204
+ DenseMap<VarID, DILocation *> &InlinedAtsMap) override ;
205
+ // / Override base class method to run on #dbg_values specifically.
206
+ virtual void visitEveryDebugIntrinsic (
207
+ DenseSet<VarID> &VarIDSet,
208
+ DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
209
+ StringRef FuncName, bool Before) override ;
210
+
103
211
template <typename IRUnitT> static const IRUnitT *unwrapIR (Any IR) {
104
212
const IRUnitT **IRPtr = llvm::any_cast<const IRUnitT *>(&IR);
105
213
return IRPtr ? *IRPtr : nullptr ;
0 commit comments