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