LLVM 22.0.0git
DroppedVariableStats.cpp
Go to the documentation of this file.
1///===- DroppedVariableStats.cpp ----------------------------------------===//
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
17#include "llvm/IR/Function.h"
18
19using namespace llvm;
20
22 : DroppedVariableStatsEnabled(DroppedVarStatsEnabled) {
23 if (DroppedVarStatsEnabled)
24 llvm::outs() << "Pass Level, Pass Name, Num of Dropped Variables, Func or "
25 "Module Name\n";
26}
27
31}
32
34 assert(!DebugVariablesStack.empty() &&
35 "DebugVariablesStack shouldn't be empty!");
36 assert(!InlinedAts.empty() && "InlinedAts shouldn't be empty!");
37 DebugVariablesStack.pop_back();
38 InlinedAts.pop_back();
39}
40
42 DebugVariables &DbgVariables, StringRef FuncName, StringRef PassID,
43 StringRef FuncOrModName, StringRef PassLevel, const Function *Func) {
44 unsigned DroppedCount = 0;
45 DenseSet<VarID> &DebugVariablesBeforeSet = DbgVariables.DebugVariablesBefore;
46 DenseSet<VarID> &DebugVariablesAfterSet = DbgVariables.DebugVariablesAfter;
47 auto It = InlinedAts.back().find(FuncName);
48 if (It == InlinedAts.back().end())
49 return;
50 DenseMap<VarID, DILocation *> &InlinedAtsMap = It->second;
51 // Find an Instruction that shares the same scope as the dropped #dbg_value
52 // or has a scope that is the child of the scope of the #dbg_value, and has
53 // an inlinedAt equal to the inlinedAt of the #dbg_value or it's inlinedAt
54 // chain contains the inlinedAt of the #dbg_value, if such an Instruction is
55 // found, debug information is dropped.
56 for (VarID Var : DebugVariablesBeforeSet) {
57 if (DebugVariablesAfterSet.contains(Var))
58 continue;
59 visitEveryInstruction(DroppedCount, InlinedAtsMap, Var);
60 removeVarFromAllSets(Var, Func);
61 }
62 if (DroppedCount > 0) {
63 llvm::outs() << PassLevel << ", " << PassID << ", " << DroppedCount << ", "
64 << FuncOrModName << "\n";
65 PassDroppedVariables = true;
66 } else
67 PassDroppedVariables = false;
68}
69
71 DILocation *DbgLoc, const DIScope *Scope, const DIScope *DbgValScope,
72 DenseMap<VarID, DILocation *> &InlinedAtsMap, VarID Var,
73 unsigned &DroppedCount) {
74 // If the Scope is a child of, or equal to the DbgValScope and is inlined at
75 // the Var's InlinedAt location, return true to signify that the Var has
76 // been dropped.
77 if (isScopeChildOfOrEqualTo(Scope, DbgValScope))
78 if (isInlinedAtChildOfOrEqualTo(DbgLoc->getInlinedAt(),
79 InlinedAtsMap[Var])) {
80 // Found another instruction in the variable's scope, so there exists a
81 // break point at which the variable could be observed. Count it as
82 // dropped.
83 DroppedCount++;
84 return true;
85 }
86 return false;
87}
88
90 bool Before) {
91 auto &VarIDSet = (Before ? DbgVariables.DebugVariablesBefore
92 : DbgVariables.DebugVariablesAfter);
93 auto &InlinedAtsMap = InlinedAts.back();
94 if (Before)
95 InlinedAtsMap.try_emplace(FuncName, DenseMap<VarID, DILocation *>());
96 VarIDSet = DenseSet<VarID>();
97 visitEveryDebugRecord(VarIDSet, InlinedAtsMap, FuncName, Before);
98}
99
101 const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,
103 StringRef FuncName, bool Before) {
104 VarID Key{DbgVar->getScope(), DbgLoc->getInlinedAtScope(), DbgVar};
105 VarIDSet.insert(Key);
106 if (Before)
107 InlinedAtsMap[FuncName].try_emplace(Key, DbgLoc.getInlinedAt());
108}
109
110void DroppedVariableStats::removeVarFromAllSets(VarID Var, const Function *F) {
111 // Do not remove Var from the last element, it will be popped from the
112 // stack.
113 for (auto &DebugVariablesMap : llvm::drop_end(DebugVariablesStack))
114 DebugVariablesMap[F].DebugVariablesBefore.erase(Var);
115}
116
117bool DroppedVariableStats::isScopeChildOfOrEqualTo(const DIScope *Scope,
118 const DIScope *DbgValScope) {
119 while (Scope != nullptr) {
120 if (VisitedScope.insert(Scope).second) {
121 if (Scope == DbgValScope) {
122 VisitedScope.clear();
123 return true;
124 }
125 Scope = Scope->getScope();
126 } else {
127 VisitedScope.clear();
128 return false;
129 }
130 }
131 return false;
132}
133
134bool DroppedVariableStats::isInlinedAtChildOfOrEqualTo(
135 const DILocation *InlinedAt, const DILocation *DbgValInlinedAt) {
136 if (DbgValInlinedAt == InlinedAt)
137 return true;
138 if (!DbgValInlinedAt)
139 return false;
140 auto *IA = InlinedAt;
141 while (IA) {
142 if (IA == DbgValInlinedAt)
143 return true;
144 IA = IA->getInlinedAt();
145 }
146 return false;
147}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
===- DroppedVariableStats.h - Opt Diagnostics -*- C++ -*-------------—===//
#define F(x, y, z)
Definition: MD5.cpp:55
DILocalScope * getScope() const
Get the local scope for this variable.
Debug location.
Base class for scope-like contexts.
A debug info location.
Definition: DebugLoc.h:124
LLVM_ABI DILocation * getInlinedAt() const
Definition: DebugLoc.cpp:69
Implements a dense probed hash-table based set.
Definition: DenseSet.h:263
DenseSet< const DIScope * > VisitedScope
A DenseSet tracking whether a scope was visited before.
LLVM_ABI void calculateDroppedStatsAndPrint(DebugVariables &DbgVariables, StringRef FuncName, StringRef PassID, StringRef FuncOrModName, StringRef PassLevel, const Function *Func)
Calculate the number of dropped variables in an llvm::Function or llvm::MachineFunction and print the...
virtual void visitEveryInstruction(unsigned &DroppedCount, DenseMap< VarID, DILocation * > &InlinedAtsMap, VarID Var)=0
Visit every llvm::Instruction or llvm::MachineInstruction and check if the debug variable denoted by ...
SmallVector< DenseMap< StringRef, DenseMap< VarID, DILocation * > > > InlinedAts
A stack of DenseMaps, which map the name of an llvm::Function to a DenseMap of VarIDs and their inlin...
LLVM_ABI bool updateDroppedCount(DILocation *DbgLoc, const DIScope *Scope, const DIScope *DbgValScope, DenseMap< VarID, DILocation * > &InlinedAtsMap, VarID Var, unsigned &DroppedCount)
Check if a Var has been dropped or is a false positive.
virtual void visitEveryDebugRecord(DenseSet< VarID > &VarIDSet, DenseMap< StringRef, DenseMap< VarID, DILocation * > > &InlinedAtsMap, StringRef FuncName, bool Before)=0
Visit every debug record in an llvm::Function or llvm::MachineFunction and call populateVarIDSetAndIn...
LLVM_ABI void populateVarIDSetAndInlinedMap(const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet< VarID > &VarIDSet, DenseMap< StringRef, DenseMap< VarID, DILocation * > > &InlinedAtsMap, StringRef FuncName, bool Before)
Populate the VarIDSet and InlinedAtMap with the relevant information needed for before and after pass...
LLVM_ABI DroppedVariableStats(bool DroppedVarStatsEnabled)
SmallVector< DenseMap< const Function *, DebugVariables > > DebugVariablesStack
A stack of a DenseMap, that maps DebugVariables for every pass to an llvm::Function.
LLVM_ABI void run(DebugVariables &DbgVariables, StringRef FuncName, bool Before)
Run code to populate relevant data structures over an llvm::Function or llvm::MachineFunction.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:194
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:169
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
std::tuple< const DIScope *, const DIScope *, const DILocalVariable * > VarID
A unique key that represents a debug variable.
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
Definition: STLExtras.h:345
DenseSet< VarID > DebugVariablesAfter
DenseSet of VarIDs after an optimization pass has run.
DenseSet< VarID > DebugVariablesBefore
DenseSet of VarIDs before an optimization pass has run.