xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/DroppedVariableStats.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 ///===- DroppedVariableStats.h - Opt Diagnostics -*- C++ -*----------------===//
2 ///
3 /// Part of the LLVM Project, under the Apache License v2.0 with LLVM
4 /// Exceptions. See https://llvm.org/LICENSE.txt for license information.
5 /// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 ///
7 ///===---------------------------------------------------------------------===//
8 /// \file
9 /// Dropped Variable Statistics for Debug Information. Reports any number
10 /// of #dbg_value that get dropped due to an optimization pass.
11 ///
12 ///===---------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
15 #define LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
16 
17 #include "llvm/ADT/DenseSet.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/Support/Compiler.h"
20 #include <tuple>
21 
22 namespace llvm {
23 
24 class DIScope;
25 class DILocalVariable;
26 class Function;
27 class DILocation;
28 class DebugLoc;
29 class StringRef;
30 
31 /// A unique key that represents a debug variable.
32 /// First const DIScope *: Represents the scope of the debug variable.
33 /// Second const DIScope *: Represents the InlinedAt scope of the debug
34 /// variable. const DILocalVariable *: It is a pointer to the debug variable
35 /// itself.
36 using VarID =
37     std::tuple<const DIScope *, const DIScope *, const DILocalVariable *>;
38 
39 /// A base class to collect and print dropped debug information variable
40 /// statistics.
41 class DroppedVariableStats {
42 public:
43   LLVM_ABI DroppedVariableStats(bool DroppedVarStatsEnabled);
44 
~DroppedVariableStats()45   virtual ~DroppedVariableStats() {}
46 
47   // We intend this to be unique per-compilation, thus no copies.
48   DroppedVariableStats(const DroppedVariableStats &) = delete;
49   void operator=(const DroppedVariableStats &) = delete;
50 
getPassDroppedVariables()51   bool getPassDroppedVariables() { return PassDroppedVariables; }
52 
53 protected:
54   LLVM_ABI void setup();
55 
56   LLVM_ABI void cleanup();
57 
58   bool DroppedVariableStatsEnabled = false;
59   struct DebugVariables {
60     /// DenseSet of VarIDs before an optimization pass has run.
61     DenseSet<VarID> DebugVariablesBefore;
62     /// DenseSet of VarIDs after an optimization pass has run.
63     DenseSet<VarID> DebugVariablesAfter;
64   };
65 
66   /// A stack of a DenseMap, that maps DebugVariables for every pass to an
67   /// llvm::Function. A stack is used because an optimization pass can call
68   /// other passes.
69   SmallVector<DenseMap<const Function *, DebugVariables>> DebugVariablesStack;
70 
71   /// A DenseSet tracking whether a scope was visited before.
72   DenseSet<const DIScope *> VisitedScope;
73   /// A stack of DenseMaps, which map the name of an llvm::Function to a
74   /// DenseMap of VarIDs and their inlinedAt locations before an optimization
75   /// pass has run.
76   SmallVector<DenseMap<StringRef, DenseMap<VarID, DILocation *>>> InlinedAts;
77   /// Calculate the number of dropped variables in an llvm::Function or
78   /// llvm::MachineFunction and print the relevant information to stdout.
79   LLVM_ABI void calculateDroppedStatsAndPrint(
80       DebugVariables &DbgVariables, StringRef FuncName, StringRef PassID,
81       StringRef FuncOrModName, StringRef PassLevel, const Function *Func);
82 
83   /// Check if a \p Var has been dropped or is a false positive. Also update the
84   /// \p DroppedCount if a debug variable is dropped.
85   LLVM_ABI bool updateDroppedCount(DILocation *DbgLoc, const DIScope *Scope,
86                                    const DIScope *DbgValScope,
87                                    DenseMap<VarID, DILocation *> &InlinedAtsMap,
88                                    VarID Var, unsigned &DroppedCount);
89 
90   /// Run code to populate relevant data structures over an llvm::Function or
91   /// llvm::MachineFunction.
92   LLVM_ABI void run(DebugVariables &DbgVariables, StringRef FuncName,
93                     bool Before);
94 
95   /// Populate the VarIDSet and InlinedAtMap with the relevant information
96   /// needed for before and after pass analysis to determine dropped variable
97   /// status.
98   LLVM_ABI void populateVarIDSetAndInlinedMap(
99       const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,
100       DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
101       StringRef FuncName, bool Before);
102 
103   /// Visit every llvm::Instruction or llvm::MachineInstruction and check if the
104   /// debug variable denoted by its ID \p Var may have been dropped by an
105   /// optimization pass.
106   virtual void
107   visitEveryInstruction(unsigned &DroppedCount,
108                         DenseMap<VarID, DILocation *> &InlinedAtsMap,
109                         VarID Var) = 0;
110   /// Visit every debug record in an llvm::Function or llvm::MachineFunction
111   /// and call populateVarIDSetAndInlinedMap on it.
112   virtual void visitEveryDebugRecord(
113       DenseSet<VarID> &VarIDSet,
114       DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
115       StringRef FuncName, bool Before) = 0;
116 
117 private:
118   /// Remove a dropped debug variable's VarID from all Sets in the
119   /// DroppedVariablesBefore stack.
120   void removeVarFromAllSets(VarID Var, const Function *F);
121 
122   /// Return true if \p Scope is the same as \p DbgValScope or a child scope of
123   /// \p DbgValScope, return false otherwise.
124   bool isScopeChildOfOrEqualTo(const DIScope *Scope,
125                                const DIScope *DbgValScope);
126 
127   /// Return true if \p InlinedAt is the same as \p DbgValInlinedAt or part of
128   /// the InlinedAt chain, return false otherwise.
129   bool isInlinedAtChildOfOrEqualTo(const DILocation *InlinedAt,
130                                    const DILocation *DbgValInlinedAt);
131 
132   bool PassDroppedVariables = false;
133 };
134 
135 } // namespace llvm
136 
137 #endif
138