LLVM 24.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
33 assert(!DebugVariablesStack.empty() &&
34 "DebugVariablesStack shouldn't be empty!");
35 DebugVariablesStack.pop_back();
36}
37
39 DebugVariables &DbgVariables, StringRef PassID, StringRef FuncOrModName,
40 StringRef PassLevel, const Function *Func) {
41 unsigned DroppedCount = 0;
42 DenseSet<VarID> &DebugVariablesBeforeSet = DbgVariables.DebugVariablesBefore;
43 DenseSet<VarID> &DebugVariablesAfterSet = DbgVariables.DebugVariablesAfter;
44 // A variable is considered dropped if an instruction remains at which a
45 // debugger could observe it.
46 for (VarID Var : DebugVariablesBeforeSet) {
47 if (DebugVariablesAfterSet.contains(Var))
48 continue;
49 visitEveryInstruction(DroppedCount, Var);
50 removeVarFromAllSets(Var, Func);
51 }
52 if (DroppedCount > 0) {
53 llvm::outs() << PassLevel << ", " << PassID << ", " << DroppedCount << ", "
54 << FuncOrModName << "\n";
55 PassDroppedVariables = true;
56 } else
57 PassDroppedVariables = false;
58}
59
61 VarID Var,
62 unsigned &DroppedCount) {
63 if (!isVarInScopeAt(DbgLoc, Var))
64 return false;
65 // Found another instruction in the variable's scope, so there exists a break
66 // point at which the variable could be observed. Count it as dropped.
67 DroppedCount++;
68 return true;
69}
70
71void DroppedVariableStats::run(DebugVariables &DbgVariables, bool Before) {
72 auto &VarIDSet = (Before ? DbgVariables.DebugVariablesBefore
73 : DbgVariables.DebugVariablesAfter);
74 VarIDSet = DenseSet<VarID>();
75 visitEveryDebugRecord(VarIDSet);
76}
77
79 DebugLoc DbgLoc,
80 DenseSet<VarID> &VarIDSet) {
82 DebugVariable(DbgVar, std::nullopt, DbgLoc.getInlinedAt())));
83}
84
85void DroppedVariableStats::removeVarFromAllSets(VarID Var, const Function *F) {
86 // Do not remove Var from the last element, it will be popped from the
87 // stack.
88 for (auto &DebugVariablesMap : llvm::drop_end(DebugVariablesStack))
89 DebugVariablesMap[F].DebugVariablesBefore.erase(Var);
90}
91
92bool DroppedVariableStats::isScopeChildOfOrEqualTo(const DIScope *Scope,
93 const DIScope *VarScope) {
94 while (Scope != nullptr) {
95 if (Scope == VarScope)
96 return true;
97 Scope = Scope->getScope();
98 }
99 return false;
100}
101
102bool DroppedVariableStats::isVarInScopeAt(const DILocation *Loc, VarID Var) {
103 // Loc and the call sites in its inlinedAt chain are the frames a debugger
104 // stopped at Loc can see. Var can only be in the frame of its own
105 // inlined instance.
106 for (const DILocation *Frame = Loc; Frame; Frame = Frame->getInlinedAt())
107 if (Frame->getInlinedAt() == Var.getInlinedAt())
108 return isScopeChildOfOrEqualTo(Frame->getScope(),
109 Var.getVariable()->getScope());
110 return false;
111}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
===- DroppedVariableStats.h - Opt Diagnostics -*- C++ -*-------------—===//
#define F(x, y, z)
Definition MD5.cpp:54
DILocalScope * getScope() const
Get the local scope for this variable.
Base class for scope-like contexts.
A debug info location.
Definition DebugLoc.h:126
LLVM_ABI DILocation * getInlinedAt() const
Definition DebugLoc.cpp:58
Identifies a unique instance of a whole variable (discards/ignores fragment information).
Identifies a unique instance of a variable.
const DILocation * getInlinedAt() const
const DILocalVariable * getVariable() const
Implements a dense probed hash-table based set.
Definition DenseSet.h:283
LLVM_ABI void populateVarIDSet(const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet< VarID > &VarIDSet)
Add the VarID of the debug record of DbgVar at DbgLoc to VarIDSet.
virtual void visitEveryInstruction(unsigned &DroppedCount, VarID Var)=0
Visit every llvm::Instruction or llvm::MachineInstruction and check if the debug variable denoted by ...
virtual void visitEveryDebugRecord(DenseSet< VarID > &VarIDSet)=0
Visit every debug record in an llvm::Function or llvm::MachineFunction and call populateVarIDSet on i...
LLVM_ABI void run(DebugVariables &DbgVariables, bool Before)
Run code to populate relevant data structures over an llvm::Function or llvm::MachineFunction.
LLVM_ABI DroppedVariableStats(bool DroppedVarStatsEnabled)
LLVM_ABI void calculateDroppedStatsAndPrint(DebugVariables &DbgVariables, 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...
SmallVector< DenseMap< const Function *, DebugVariables > > DebugVariablesStack
A stack of a DenseMap, that maps DebugVariables for every pass to an llvm::Function.
LLVM_ABI bool updateDroppedCount(const DILocation *DbgLoc, VarID Var, unsigned &DroppedCount)
Check if a Var has been dropped or is a false positive.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:210
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:183
This is an optimization pass for GlobalISel generic memory operations.
DebugVariableAggregate VarID
A unique key that represents one instance of a debug variable.
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
Definition STLExtras.h:323
DenseSet< VarID > DebugVariablesAfter
DenseSet of VarIDs after an optimization pass has run.
DenseSet< VarID > DebugVariablesBefore
DenseSet of VarIDs before an optimization pass has run.