2323
2424namespace llvm {
2525
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.
2932class DroppedVariableStats {
3033public:
3134 DroppedVariableStats (bool DroppedVarStatsEnabled)
@@ -35,22 +38,30 @@ class DroppedVariableStats {
3538 << " Pass Level, Pass Name, Num of Dropped Variables, Func or "
3639 " Module Name\n " ;
3740 };
41+
42+ virtual ~DroppedVariableStats () = default ;
43+
3844 // We intend this to be unique per-compilation, thus no copies.
3945 DroppedVariableStats (const DroppedVariableStats &) = delete ;
4046 void operator =(const DroppedVariableStats &) = delete ;
4147
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);
4648 bool getPassDroppedVariables () { return PassDroppedVariables; }
4749
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+
4963 bool PassDroppedVariables = false ;
5064 bool DroppedVariableStatsEnabled = false ;
51- // / A unique key that represents a #dbg_value.
52- using VarID =
53- std::tuple<const DIScope *, const DIScope *, const DILocalVariable *>;
5465
5566 struct DebugVariables {
5667 // / DenseSet of VarIDs before an optimization pass has run.
@@ -70,36 +81,130 @@ class DroppedVariableStats {
7081 // / DenseMap of VarIDs and their inlinedAt locations before an optimization
7182 // / pass has run.
7283 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);
73100
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+ }
85178 // / Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
86179 // / after a pass has run to facilitate dropped variable calculation for an
87180 // / llvm::Function.
88181 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);
89187 // / Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
90188 // / after a pass has run to facilitate dropped variable calculation for an
91189 // / llvm::Module. Calls runOnFunction on every Function in the Module.
92190 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+
103208 template <typename IRUnitT> static const IRUnitT *unwrapIR (Any IR) {
104209 const IRUnitT **IRPtr = llvm::any_cast<const IRUnitT *>(&IR);
105210 return IRPtr ? *IRPtr : nullptr ;
0 commit comments