1414#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
1515#define LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
1616
17- #include " llvm/CodeGen/MachinePassManager.h"
1817#include " llvm/IR/DebugInfoMetadata.h"
1918#include " llvm/IR/DiagnosticInfo.h"
2019#include " llvm/IR/Function.h"
21- #include " llvm/IR/Module.h"
2220#include " llvm/IR/PassInstrumentation.h"
2321
2422namespace llvm {
@@ -92,24 +90,75 @@ class DroppedVariableStats {
9290 void calculateDroppedStatsAndPrint (DebugVariables &DbgVariables,
9391 StringRef FuncName, StringRef PassID,
9492 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+ }
96118
97119 // / Check if a \p Var has been dropped or is a false positive. Also update the
98120 // / \p DroppedCount if a debug variable is dropped.
99121 bool updateDroppedCount (DILocation *DbgLoc, const DIScope *Scope,
100122 const DIScope *DbgValScope,
101123 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+ }
103139 // / Run code to populate relevant data structures over an llvm::Function or
104140 // / 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+ }
106150 // / Populate the VarIDSet and InlinedAtMap with the relevant information
107151 // / needed for before and after pass analysis to determine dropped variable
108152 // / status.
109153 void populateVarIDSetAndInlinedMap (
110154 const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,
111155 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+ }
113162 // / Visit every llvm::Instruction or llvm::MachineInstruction and check if the
114163 // / debug variable denoted by its ID \p Var may have been dropped by an
115164 // / optimization pass.
@@ -136,87 +185,39 @@ class DroppedVariableStats {
136185 // / Return true if \p Scope is the same as \p DbgValScope or a child scope of
137186 // / \p DbgValScope, return false otherwise.
138187 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+ }
140204 // / Return true if \p InlinedAt is the same as \p DbgValInlinedAt or part of
141205 // / the InlinedAt chain, return false otherwise.
142206 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 ;
219219 }
220+ bool PassDroppedVariables = false ;
220221};
221222
222223} // namespace llvm
0 commit comments