14
14
#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
15
15
#define LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
16
16
17
- #include " llvm/CodeGen/MachinePassManager.h"
18
17
#include " llvm/IR/DebugInfoMetadata.h"
19
18
#include " llvm/IR/DiagnosticInfo.h"
20
19
#include " llvm/IR/Function.h"
21
- #include " llvm/IR/Module.h"
22
20
#include " llvm/IR/PassInstrumentation.h"
23
21
24
22
namespace llvm {
@@ -92,24 +90,75 @@ class DroppedVariableStats {
92
90
void calculateDroppedStatsAndPrint (DebugVariables &DbgVariables,
93
91
StringRef FuncName, StringRef PassID,
94
92
StringRef FuncOrModName,
95
- StringRef PassLevel, const Function *Func);
93
+ StringRef PassLevel,
94
+ const Function *Func) {
95
+ unsigned DroppedCount = 0 ;
96
+ DenseSet<VarID> &DebugVariablesBeforeSet =
97
+ DbgVariables.DebugVariablesBefore ;
98
+ DenseSet<VarID> &DebugVariablesAfterSet = DbgVariables.DebugVariablesAfter ;
99
+ DenseMap<VarID, DILocation *> &InlinedAtsMap = InlinedAts.back ()[FuncName];
100
+ // Find an Instruction that shares the same scope as the dropped #dbg_value
101
+ // or has a scope that is the child of the scope of the #dbg_value, and has
102
+ // an inlinedAt equal to the inlinedAt of the #dbg_value or it's inlinedAt
103
+ // chain contains the inlinedAt of the #dbg_value, if such an Instruction is
104
+ // found, debug information is dropped.
105
+ for (VarID Var : DebugVariablesBeforeSet) {
106
+ if (DebugVariablesAfterSet.contains (Var))
107
+ continue ;
108
+ visitEveryInstruction (DroppedCount, InlinedAtsMap, Var);
109
+ removeVarFromAllSets (Var, Func);
110
+ }
111
+ if (DroppedCount > 0 ) {
112
+ llvm::outs () << PassLevel << " , " << PassID << " , " << DroppedCount
113
+ << " , " << FuncOrModName << " \n " ;
114
+ PassDroppedVariables = true ;
115
+ } else
116
+ PassDroppedVariables = false ;
117
+ }
96
118
97
119
// / Check if a \p Var has been dropped or is a false positive. Also update the
98
120
// / \p DroppedCount if a debug variable is dropped.
99
121
bool updateDroppedCount (DILocation *DbgLoc, const DIScope *Scope,
100
122
const DIScope *DbgValScope,
101
123
DenseMap<VarID, DILocation *> &InlinedAtsMap,
102
- VarID Var, unsigned &DroppedCount);
124
+ VarID Var, unsigned &DroppedCount) {
125
+ // If the Scope is a child of, or equal to the DbgValScope and is inlined at
126
+ // the Var's InlinedAt location, return true to signify that the Var has
127
+ // been dropped.
128
+ if (isScopeChildOfOrEqualTo (Scope, DbgValScope))
129
+ if (isInlinedAtChildOfOrEqualTo (DbgLoc->getInlinedAt (),
130
+ InlinedAtsMap[Var])) {
131
+ // Found another instruction in the variable's scope, so there exists a
132
+ // break point at which the variable could be observed. Count it as
133
+ // dropped.
134
+ DroppedCount++;
135
+ return true ;
136
+ }
137
+ return false ;
138
+ }
103
139
// / Run code to populate relevant data structures over an llvm::Function or
104
140
// / llvm::MachineFunction.
105
- void run (DebugVariables &DbgVariables, StringRef FuncName, bool Before);
141
+ void run (DebugVariables &DbgVariables, StringRef FuncName, bool Before) {
142
+ auto &VarIDSet = (Before ? DbgVariables.DebugVariablesBefore
143
+ : DbgVariables.DebugVariablesAfter );
144
+ auto &InlinedAtsMap = InlinedAts.back ();
145
+ if (Before)
146
+ InlinedAtsMap.try_emplace (FuncName, DenseMap<VarID, DILocation *>());
147
+ VarIDSet = DenseSet<VarID>();
148
+ visitEveryDebugRecord (VarIDSet, InlinedAtsMap, FuncName, Before);
149
+ }
106
150
// / Populate the VarIDSet and InlinedAtMap with the relevant information
107
151
// / needed for before and after pass analysis to determine dropped variable
108
152
// / status.
109
153
void populateVarIDSetAndInlinedMap (
110
154
const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,
111
155
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
112
- StringRef FuncName, bool Before);
156
+ StringRef FuncName, bool Before) {
157
+ VarID Key{DbgVar->getScope (), DbgLoc->getInlinedAtScope (), DbgVar};
158
+ VarIDSet.insert (Key);
159
+ if (Before)
160
+ InlinedAtsMap[FuncName].try_emplace (Key, DbgLoc.getInlinedAt ());
161
+ }
113
162
// / Visit every llvm::Instruction or llvm::MachineInstruction and check if the
114
163
// / debug variable denoted by its ID \p Var may have been dropped by an
115
164
// / optimization pass.
@@ -136,87 +185,39 @@ class DroppedVariableStats {
136
185
// / Return true if \p Scope is the same as \p DbgValScope or a child scope of
137
186
// / \p DbgValScope, return false otherwise.
138
187
bool isScopeChildOfOrEqualTo (const DIScope *Scope,
139
- const DIScope *DbgValScope);
188
+ const DIScope *DbgValScope) {
189
+ while (Scope != nullptr ) {
190
+ if (VisitedScope.find (Scope) == VisitedScope.end ()) {
191
+ VisitedScope.insert (Scope);
192
+ if (Scope == DbgValScope) {
193
+ VisitedScope.clear ();
194
+ return true ;
195
+ }
196
+ Scope = Scope->getScope ();
197
+ } else {
198
+ VisitedScope.clear ();
199
+ return false ;
200
+ }
201
+ }
202
+ return false ;
203
+ }
140
204
// / Return true if \p InlinedAt is the same as \p DbgValInlinedAt or part of
141
205
// / the InlinedAt chain, return false otherwise.
142
206
bool isInlinedAtChildOfOrEqualTo (const DILocation *InlinedAt,
143
- const DILocation *DbgValInlinedAt);
144
- bool PassDroppedVariables = false ;
145
- };
146
-
147
- // / A class to collect and print dropped debug information due to LLVM IR
148
- // / optimization passes. After every LLVM IR pass is run, it will print how many
149
- // / #dbg_values were dropped due to that pass.
150
- class DroppedVariableStatsIR : public DroppedVariableStats {
151
- public:
152
- DroppedVariableStatsIR (bool DroppedVarStatsEnabled)
153
- : llvm::DroppedVariableStats(DroppedVarStatsEnabled) {}
154
-
155
- void runBeforePass (Any IR) {
156
- setup ();
157
- if (const auto *M = unwrapIR<Module>(IR))
158
- return this ->runOnModule (M, true );
159
- if (const auto *F = unwrapIR<Function>(IR))
160
- return this ->runOnFunction (F, true );
161
- }
162
-
163
- void runAfterPass (StringRef P, Any IR) {
164
- if (const auto *M = unwrapIR<Module>(IR))
165
- runAfterPassModule (P, M);
166
- else if (const auto *F = unwrapIR<Function>(IR))
167
- runAfterPassFunction (P, F);
168
- cleanup ();
169
- }
170
-
171
- void registerCallbacks (PassInstrumentationCallbacks &PIC);
172
-
173
- private:
174
- const Function *Func;
175
-
176
- void runAfterPassFunction (StringRef PassID, const Function *F) {
177
- runOnFunction (F, false );
178
- calculateDroppedVarStatsOnFunction (F, PassID, F->getName ().str (),
179
- " Function" );
180
- }
181
-
182
- void runAfterPassModule (StringRef PassID, const Module *M) {
183
- runOnModule (M, false );
184
- calculateDroppedVarStatsOnModule (M, PassID, M->getName ().str (), " Module" );
185
- }
186
- // / Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
187
- // / after a pass has run to facilitate dropped variable calculation for an
188
- // / llvm::Function.
189
- void runOnFunction (const Function *F, bool Before);
190
- // / Iterate over all Instructions in a Function and report any dropped debug
191
- // / information.
192
- void calculateDroppedVarStatsOnFunction (const Function *F, StringRef PassID,
193
- StringRef FuncOrModName,
194
- StringRef PassLevel);
195
- // / Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
196
- // / after a pass has run to facilitate dropped variable calculation for an
197
- // / llvm::Module. Calls runOnFunction on every Function in the Module.
198
- void runOnModule (const Module *M, bool Before);
199
- // / Iterate over all Functions in a Module and report any dropped debug
200
- // / information. Will call calculateDroppedVarStatsOnFunction on every
201
- // / Function.
202
- void calculateDroppedVarStatsOnModule (const Module *M, StringRef PassID,
203
- StringRef FuncOrModName,
204
- StringRef PassLevel);
205
- // / Override base class method to run on an llvm::Function specifically.
206
- virtual void
207
- visitEveryInstruction (unsigned &DroppedCount,
208
- DenseMap<VarID, DILocation *> &InlinedAtsMap,
209
- VarID Var) override ;
210
- // / Override base class method to run on #dbg_values specifically.
211
- virtual void visitEveryDebugRecord (
212
- DenseSet<VarID> &VarIDSet,
213
- DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
214
- StringRef FuncName, bool Before) override ;
215
-
216
- template <typename IRUnitT> static const IRUnitT *unwrapIR (Any IR) {
217
- const IRUnitT **IRPtr = llvm::any_cast<const IRUnitT *>(&IR);
218
- return IRPtr ? *IRPtr : nullptr ;
207
+ const DILocation *DbgValInlinedAt) {
208
+ if (DbgValInlinedAt == InlinedAt)
209
+ return true ;
210
+ if (!DbgValInlinedAt)
211
+ return false ;
212
+ auto *IA = InlinedAt;
213
+ while (IA) {
214
+ if (IA == DbgValInlinedAt)
215
+ return true ;
216
+ IA = IA->getInlinedAt ();
217
+ }
218
+ return false ;
219
219
}
220
+ bool PassDroppedVariables = false ;
220
221
};
221
222
222
223
} // namespace llvm
0 commit comments