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,32 @@ 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+ return ;
57+ }
58+
59+ void cleanup () {
60+ DebugVariablesStack.pop_back ();
61+ InlinedAts.pop_back ();
62+ return ;
63+ }
64+
4965 bool PassDroppedVariables = false ;
5066 bool DroppedVariableStatsEnabled = false ;
51- // / A unique key that represents a #dbg_value.
52- using VarID =
53- std::tuple<const DIScope *, const DIScope *, const DILocalVariable *>;
5467
5568 struct DebugVariables {
5669 // / DenseSet of VarIDs before an optimization pass has run.
@@ -70,36 +83,131 @@ class DroppedVariableStats {
7083 // / DenseMap of VarIDs and their inlinedAt locations before an optimization
7184 // / pass has run.
7285 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);
73102
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+ }
85181 // / Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
86182 // / after a pass has run to facilitate dropped variable calculation for an
87183 // / llvm::Function.
88184 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);
89190 // / Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
90191 // / after a pass has run to facilitate dropped variable calculation for an
91192 // / llvm::Module. Calls runOnFunction on every Function in the Module.
92193 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+
103211 template <typename IRUnitT> static const IRUnitT *unwrapIR (Any IR) {
104212 const IRUnitT **IRPtr = llvm::any_cast<const IRUnitT *>(&IR);
105213 return IRPtr ? *IRPtr : nullptr ;
0 commit comments