Skip to content

Commit 7cfb292

Browse files
[NFC] Move DroppedVariableStats to its own file (llvm#120711)
Move DroppedVariableStats code to its own file and change the class to have an extensible design so that we can use it to add dropped statistics to MIR passes and the instruction selector. Also moved class DroppedVariableStatsIR to its own file. Reland 2de7881 (cherry picked from commit 0b5b09b)
1 parent 8c5a048 commit 7cfb292

File tree

7 files changed

+279
-280
lines changed

7 files changed

+279
-280
lines changed

llvm/include/llvm/Passes/DroppedVariableStats.h

Lines changed: 84 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@
1414
#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
1515
#define LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
1616

17-
#include "llvm/CodeGen/MachinePassManager.h"
1817
#include "llvm/IR/DebugInfoMetadata.h"
1918
#include "llvm/IR/DiagnosticInfo.h"
2019
#include "llvm/IR/Function.h"
21-
#include "llvm/IR/Module.h"
2220
#include "llvm/IR/PassInstrumentation.h"
2321

2422
namespace llvm {
@@ -92,24 +90,75 @@ class DroppedVariableStats {
9290
void calculateDroppedStatsAndPrint(DebugVariables &DbgVariables,
9391
StringRef FuncName, StringRef PassID,
9492
StringRef FuncOrModName,
95-
StringRef PassLevel, const Function *Func);
93+
StringRef PassLevel,
94+
const Function *Func) {
95+
unsigned DroppedCount = 0;
96+
DenseSet<VarID> &DebugVariablesBeforeSet =
97+
DbgVariables.DebugVariablesBefore;
98+
DenseSet<VarID> &DebugVariablesAfterSet = DbgVariables.DebugVariablesAfter;
99+
DenseMap<VarID, DILocation *> &InlinedAtsMap = InlinedAts.back()[FuncName];
100+
// Find an Instruction that shares the same scope as the dropped #dbg_value
101+
// or has a scope that is the child of the scope of the #dbg_value, and has
102+
// an inlinedAt equal to the inlinedAt of the #dbg_value or it's inlinedAt
103+
// chain contains the inlinedAt of the #dbg_value, if such an Instruction is
104+
// found, debug information is dropped.
105+
for (VarID Var : DebugVariablesBeforeSet) {
106+
if (DebugVariablesAfterSet.contains(Var))
107+
continue;
108+
visitEveryInstruction(DroppedCount, InlinedAtsMap, Var);
109+
removeVarFromAllSets(Var, Func);
110+
}
111+
if (DroppedCount > 0) {
112+
llvm::outs() << PassLevel << ", " << PassID << ", " << DroppedCount
113+
<< ", " << FuncOrModName << "\n";
114+
PassDroppedVariables = true;
115+
} else
116+
PassDroppedVariables = false;
117+
}
96118

97119
/// Check if a \p Var has been dropped or is a false positive. Also update the
98120
/// \p DroppedCount if a debug variable is dropped.
99121
bool updateDroppedCount(DILocation *DbgLoc, const DIScope *Scope,
100122
const DIScope *DbgValScope,
101123
DenseMap<VarID, DILocation *> &InlinedAtsMap,
102-
VarID Var, unsigned &DroppedCount);
124+
VarID Var, unsigned &DroppedCount) {
125+
// If the Scope is a child of, or equal to the DbgValScope and is inlined at
126+
// the Var's InlinedAt location, return true to signify that the Var has
127+
// been dropped.
128+
if (isScopeChildOfOrEqualTo(Scope, DbgValScope))
129+
if (isInlinedAtChildOfOrEqualTo(DbgLoc->getInlinedAt(),
130+
InlinedAtsMap[Var])) {
131+
// Found another instruction in the variable's scope, so there exists a
132+
// break point at which the variable could be observed. Count it as
133+
// dropped.
134+
DroppedCount++;
135+
return true;
136+
}
137+
return false;
138+
}
103139
/// Run code to populate relevant data structures over an llvm::Function or
104140
/// llvm::MachineFunction.
105-
void run(DebugVariables &DbgVariables, StringRef FuncName, bool Before);
141+
void run(DebugVariables &DbgVariables, StringRef FuncName, bool Before) {
142+
auto &VarIDSet = (Before ? DbgVariables.DebugVariablesBefore
143+
: DbgVariables.DebugVariablesAfter);
144+
auto &InlinedAtsMap = InlinedAts.back();
145+
if (Before)
146+
InlinedAtsMap.try_emplace(FuncName, DenseMap<VarID, DILocation *>());
147+
VarIDSet = DenseSet<VarID>();
148+
visitEveryDebugRecord(VarIDSet, InlinedAtsMap, FuncName, Before);
149+
}
106150
/// Populate the VarIDSet and InlinedAtMap with the relevant information
107151
/// needed for before and after pass analysis to determine dropped variable
108152
/// status.
109153
void populateVarIDSetAndInlinedMap(
110154
const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,
111155
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
112-
StringRef FuncName, bool Before);
156+
StringRef FuncName, bool Before) {
157+
VarID Key{DbgVar->getScope(), DbgLoc->getInlinedAtScope(), DbgVar};
158+
VarIDSet.insert(Key);
159+
if (Before)
160+
InlinedAtsMap[FuncName].try_emplace(Key, DbgLoc.getInlinedAt());
161+
}
113162
/// Visit every llvm::Instruction or llvm::MachineInstruction and check if the
114163
/// debug variable denoted by its ID \p Var may have been dropped by an
115164
/// optimization pass.
@@ -136,87 +185,39 @@ class DroppedVariableStats {
136185
/// Return true if \p Scope is the same as \p DbgValScope or a child scope of
137186
/// \p DbgValScope, return false otherwise.
138187
bool isScopeChildOfOrEqualTo(const DIScope *Scope,
139-
const DIScope *DbgValScope);
188+
const DIScope *DbgValScope) {
189+
while (Scope != nullptr) {
190+
if (VisitedScope.find(Scope) == VisitedScope.end()) {
191+
VisitedScope.insert(Scope);
192+
if (Scope == DbgValScope) {
193+
VisitedScope.clear();
194+
return true;
195+
}
196+
Scope = Scope->getScope();
197+
} else {
198+
VisitedScope.clear();
199+
return false;
200+
}
201+
}
202+
return false;
203+
}
140204
/// Return true if \p InlinedAt is the same as \p DbgValInlinedAt or part of
141205
/// the InlinedAt chain, return false otherwise.
142206
bool isInlinedAtChildOfOrEqualTo(const DILocation *InlinedAt,
143-
const DILocation *DbgValInlinedAt);
144-
bool PassDroppedVariables = false;
145-
};
146-
147-
/// A class to collect and print dropped debug information due to LLVM IR
148-
/// optimization passes. After every LLVM IR pass is run, it will print how many
149-
/// #dbg_values were dropped due to that pass.
150-
class DroppedVariableStatsIR : public DroppedVariableStats {
151-
public:
152-
DroppedVariableStatsIR(bool DroppedVarStatsEnabled)
153-
: llvm::DroppedVariableStats(DroppedVarStatsEnabled) {}
154-
155-
void runBeforePass(Any IR) {
156-
setup();
157-
if (const auto *M = unwrapIR<Module>(IR))
158-
return this->runOnModule(M, true);
159-
if (const auto *F = unwrapIR<Function>(IR))
160-
return this->runOnFunction(F, true);
161-
}
162-
163-
void runAfterPass(StringRef P, Any IR) {
164-
if (const auto *M = unwrapIR<Module>(IR))
165-
runAfterPassModule(P, M);
166-
else if (const auto *F = unwrapIR<Function>(IR))
167-
runAfterPassFunction(P, F);
168-
cleanup();
169-
}
170-
171-
void registerCallbacks(PassInstrumentationCallbacks &PIC);
172-
173-
private:
174-
const Function *Func;
175-
176-
void runAfterPassFunction(StringRef PassID, const Function *F) {
177-
runOnFunction(F, false);
178-
calculateDroppedVarStatsOnFunction(F, PassID, F->getName().str(),
179-
"Function");
180-
}
181-
182-
void runAfterPassModule(StringRef PassID, const Module *M) {
183-
runOnModule(M, false);
184-
calculateDroppedVarStatsOnModule(M, PassID, M->getName().str(), "Module");
185-
}
186-
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
187-
/// after a pass has run to facilitate dropped variable calculation for an
188-
/// llvm::Function.
189-
void runOnFunction(const Function *F, bool Before);
190-
/// Iterate over all Instructions in a Function and report any dropped debug
191-
/// information.
192-
void calculateDroppedVarStatsOnFunction(const Function *F, StringRef PassID,
193-
StringRef FuncOrModName,
194-
StringRef PassLevel);
195-
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
196-
/// after a pass has run to facilitate dropped variable calculation for an
197-
/// llvm::Module. Calls runOnFunction on every Function in the Module.
198-
void runOnModule(const Module *M, bool Before);
199-
/// Iterate over all Functions in a Module and report any dropped debug
200-
/// information. Will call calculateDroppedVarStatsOnFunction on every
201-
/// Function.
202-
void calculateDroppedVarStatsOnModule(const Module *M, StringRef PassID,
203-
StringRef FuncOrModName,
204-
StringRef PassLevel);
205-
/// Override base class method to run on an llvm::Function specifically.
206-
virtual void
207-
visitEveryInstruction(unsigned &DroppedCount,
208-
DenseMap<VarID, DILocation *> &InlinedAtsMap,
209-
VarID Var) override;
210-
/// Override base class method to run on #dbg_values specifically.
211-
virtual void visitEveryDebugRecord(
212-
DenseSet<VarID> &VarIDSet,
213-
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
214-
StringRef FuncName, bool Before) override;
215-
216-
template <typename IRUnitT> static const IRUnitT *unwrapIR(Any IR) {
217-
const IRUnitT **IRPtr = llvm::any_cast<const IRUnitT *>(&IR);
218-
return IRPtr ? *IRPtr : nullptr;
207+
const DILocation *DbgValInlinedAt) {
208+
if (DbgValInlinedAt == InlinedAt)
209+
return true;
210+
if (!DbgValInlinedAt)
211+
return false;
212+
auto *IA = InlinedAt;
213+
while (IA) {
214+
if (IA == DbgValInlinedAt)
215+
return true;
216+
IA = IA->getInlinedAt();
217+
}
218+
return false;
219219
}
220+
bool PassDroppedVariables = false;
220221
};
221222

222223
} // namespace llvm
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
///===- DroppedVariableStatsIR.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_DROPPEDVARIABLESTATSIR_H
15+
#define LLVM_CODEGEN_DROPPEDVARIABLESTATSIR_H
16+
17+
#include "llvm/IR/InstIterator.h"
18+
#include "llvm/IR/Module.h"
19+
#include "llvm/Passes/DroppedVariableStats.h"
20+
21+
namespace llvm {
22+
23+
/// A class to collect and print dropped debug information due to LLVM IR
24+
/// optimization passes. After every LLVM IR pass is run, it will print how many
25+
/// #dbg_values were dropped due to that pass.
26+
class DroppedVariableStatsIR : public DroppedVariableStats {
27+
public:
28+
DroppedVariableStatsIR(bool DroppedVarStatsEnabled)
29+
: llvm::DroppedVariableStats(DroppedVarStatsEnabled) {}
30+
31+
void runBeforePass(Any IR) {
32+
setup();
33+
if (const auto *M = unwrapIR<Module>(IR))
34+
return this->runOnModule(M, true);
35+
if (const auto *F = unwrapIR<Function>(IR))
36+
return this->runOnFunction(F, true);
37+
}
38+
39+
void runAfterPass(StringRef P, Any IR) {
40+
if (const auto *M = unwrapIR<Module>(IR))
41+
runAfterPassModule(P, M);
42+
else if (const auto *F = unwrapIR<Function>(IR))
43+
runAfterPassFunction(P, F);
44+
cleanup();
45+
}
46+
47+
void registerCallbacks(PassInstrumentationCallbacks &PIC);
48+
49+
private:
50+
const Function *Func;
51+
52+
void runAfterPassFunction(StringRef PassID, const Function *F) {
53+
runOnFunction(F, false);
54+
calculateDroppedVarStatsOnFunction(F, PassID, F->getName().str(),
55+
"Function");
56+
}
57+
58+
void runAfterPassModule(StringRef PassID, const Module *M) {
59+
runOnModule(M, false);
60+
calculateDroppedVarStatsOnModule(M, PassID, M->getName().str(), "Module");
61+
}
62+
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
63+
/// after a pass has run to facilitate dropped variable calculation for an
64+
/// llvm::Function.
65+
void runOnFunction(const Function *F, bool Before);
66+
/// Iterate over all Instructions in a Function and report any dropped debug
67+
/// information.
68+
void calculateDroppedVarStatsOnFunction(const Function *F, StringRef PassID,
69+
StringRef FuncOrModName,
70+
StringRef PassLevel);
71+
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
72+
/// after a pass has run to facilitate dropped variable calculation for an
73+
/// llvm::Module. Calls runOnFunction on every Function in the Module.
74+
void runOnModule(const Module *M, bool Before);
75+
/// Iterate over all Functions in a Module and report any dropped debug
76+
/// information. Will call calculateDroppedVarStatsOnFunction on every
77+
/// Function.
78+
void calculateDroppedVarStatsOnModule(const Module *M, StringRef PassID,
79+
StringRef FuncOrModName,
80+
StringRef PassLevel);
81+
/// Override base class method to run on an llvm::Function specifically.
82+
virtual void
83+
visitEveryInstruction(unsigned &DroppedCount,
84+
DenseMap<VarID, DILocation *> &InlinedAtsMap,
85+
VarID Var) override;
86+
87+
/// Override base class method to run on #dbg_values specifically.
88+
virtual void visitEveryDebugRecord(
89+
DenseSet<VarID> &VarIDSet,
90+
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
91+
StringRef FuncName, bool Before) override;
92+
93+
template <typename IRUnitT> static const IRUnitT *unwrapIR(Any IR) {
94+
const IRUnitT **IRPtr = llvm::any_cast<const IRUnitT *>(&IR);
95+
return IRPtr ? *IRPtr : nullptr;
96+
}
97+
};
98+
99+
} // namespace llvm
100+
101+
#endif

llvm/include/llvm/Passes/StandardInstrumentations.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "llvm/IR/OptBisect.h"
2626
#include "llvm/IR/PassTimingInfo.h"
2727
#include "llvm/IR/ValueHandle.h"
28-
#include "llvm/Passes/DroppedVariableStats.h"
28+
#include "llvm/Passes/DroppedVariableStatsIR.h"
2929
#include "llvm/Support/CommandLine.h"
3030
#include "llvm/Support/TimeProfiler.h"
3131
#include "llvm/Transforms/IPO/SampleProfileProbe.h"

llvm/lib/Passes/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
add_llvm_component_library(LLVMPasses
22
CodeGenPassBuilder.cpp
3-
DroppedVariableStats.cpp
3+
DroppedVariableStatsIR.cpp
44
OptimizationLevel.cpp
55
PassBuilder.cpp
66
PassBuilderBindings.cpp

0 commit comments

Comments
 (0)