Skip to content

Commit 92f916f

Browse files
Add a pass to collect dropped var statistics for MIR (llvm#126686)
This patch attempts to reland llvm#120780 while addressing the issues that caused the patch to be reverted. Namely: 1. The patch had included code from the llvm/Passes directory in the llvm/CodeGen directory. 2. The patch increased the backend compile time by 2% due to adding a very expensive include in MachineFunctionPass.h The patch has been re-structured so that there is no dependency between the llvm/Passes and llvm/CodeGen directory, by moving the base class, `class DroppedVariableStats` to the llvm/IR directory. The expensive include in MachineFunctionPass.h has been changed to contain forward declarations instead of other header includes which was pulling a ton of code into MachineFunctionPass.h and should resolve any issues when it comes to compile time increase.
1 parent 65ed4fa commit 92f916f

13 files changed

+1488
-154
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
///===- DroppedVariableStatsMIR.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_VALUEs that get dropped due to an optimization pass.
11+
///
12+
///===---------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATSMIR_H
15+
#define LLVM_CODEGEN_DROPPEDVARIABLESTATSMIR_H
16+
17+
#include "llvm/CodeGen/MachineFunction.h"
18+
#include "llvm/IR/DroppedVariableStats.h"
19+
20+
namespace llvm {
21+
22+
/// A class to collect and print dropped debug information due to MIR
23+
/// optimization passes. After every MIR pass is run, it will print how many
24+
/// #DBG_VALUEs were dropped due to that pass.
25+
class DroppedVariableStatsMIR : public DroppedVariableStats {
26+
public:
27+
DroppedVariableStatsMIR() : DroppedVariableStats(false) {}
28+
29+
void runBeforePass(StringRef PassID, MachineFunction *MF);
30+
31+
void runAfterPass(StringRef PassID, MachineFunction *MF);
32+
33+
private:
34+
const MachineFunction *MFunc;
35+
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
36+
/// after a pass has run to facilitate dropped variable calculation for an
37+
/// llvm::MachineFunction.
38+
void runOnMachineFunction(const MachineFunction *MF, bool Before);
39+
/// Iterate over all Instructions in a MachineFunction and report any dropped
40+
/// debug information.
41+
void calculateDroppedVarStatsOnMachineFunction(const MachineFunction *MF,
42+
StringRef PassID,
43+
StringRef FuncOrModName);
44+
/// Override base class method to run on an llvm::MachineFunction
45+
/// specifically.
46+
virtual void
47+
visitEveryInstruction(unsigned &DroppedCount,
48+
DenseMap<VarID, DILocation *> &InlinedAtsMap,
49+
VarID Var) override;
50+
/// Override base class method to run on DBG_VALUEs specifically.
51+
virtual void visitEveryDebugRecord(
52+
DenseSet<VarID> &VarIDSet,
53+
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
54+
StringRef FuncName, bool Before) override;
55+
};
56+
57+
} // namespace llvm
58+
59+
#endif

llvm/include/llvm/Passes/DroppedVariableStats.h renamed to llvm/include/llvm/IR/DroppedVariableStats.h

Lines changed: 27 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@
1414
#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
1515
#define LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
1616

17-
#include "llvm/IR/DebugInfoMetadata.h"
18-
#include "llvm/IR/DiagnosticInfo.h"
19-
#include "llvm/IR/Function.h"
20-
#include "llvm/IR/PassInstrumentation.h"
17+
#include "llvm/ADT/DenseSet.h"
18+
#include "llvm/ADT/SmallVector.h"
19+
#include <tuple>
2120

2221
namespace llvm {
2322

23+
class DIScope;
24+
class DILocalVariable;
25+
class Function;
26+
class DILocation;
27+
class DebugLoc;
28+
class StringRef;
29+
2430
/// A unique key that represents a debug variable.
2531
/// First const DIScope *: Represents the scope of the debug variable.
2632
/// Second const DIScope *: Represents the InlinedAt scope of the debug
@@ -33,13 +39,7 @@ using VarID =
3339
/// statistics.
3440
class DroppedVariableStats {
3541
public:
36-
DroppedVariableStats(bool DroppedVarStatsEnabled)
37-
: DroppedVariableStatsEnabled(DroppedVarStatsEnabled) {
38-
if (DroppedVarStatsEnabled)
39-
llvm::outs()
40-
<< "Pass Level, Pass Name, Num of Dropped Variables, Func or "
41-
"Module Name\n";
42-
};
42+
DroppedVariableStats(bool DroppedVarStatsEnabled);
4343

4444
virtual ~DroppedVariableStats() {}
4545

@@ -50,20 +50,9 @@ class DroppedVariableStats {
5050
bool getPassDroppedVariables() { return PassDroppedVariables; }
5151

5252
protected:
53-
void setup() {
54-
DebugVariablesStack.push_back(
55-
{DenseMap<const Function *, DebugVariables>()});
56-
InlinedAts.push_back(
57-
{DenseMap<StringRef, DenseMap<VarID, DILocation *>>()});
58-
}
59-
60-
void cleanup() {
61-
assert(!DebugVariablesStack.empty() &&
62-
"DebugVariablesStack shouldn't be empty!");
63-
assert(!InlinedAts.empty() && "InlinedAts shouldn't be empty!");
64-
DebugVariablesStack.pop_back();
65-
InlinedAts.pop_back();
66-
}
53+
void setup();
54+
55+
void cleanup();
6756

6857
bool DroppedVariableStatsEnabled = false;
6958
struct DebugVariables {
@@ -73,7 +62,6 @@ class DroppedVariableStats {
7362
DenseSet<VarID> DebugVariablesAfter;
7463
};
7564

76-
protected:
7765
/// A stack of a DenseMap, that maps DebugVariables for every pass to an
7866
/// llvm::Function. A stack is used because an optimization pass can call
7967
/// other passes.
@@ -90,78 +78,27 @@ class DroppedVariableStats {
9078
void calculateDroppedStatsAndPrint(DebugVariables &DbgVariables,
9179
StringRef FuncName, StringRef PassID,
9280
StringRef FuncOrModName,
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-
auto It = InlinedAts.back().find(FuncName);
100-
if (It == InlinedAts.back().end())
101-
return;
102-
DenseMap<VarID, DILocation *> &InlinedAtsMap = It->second;
103-
// Find an Instruction that shares the same scope as the dropped #dbg_value
104-
// or has a scope that is the child of the scope of the #dbg_value, and has
105-
// an inlinedAt equal to the inlinedAt of the #dbg_value or it's inlinedAt
106-
// chain contains the inlinedAt of the #dbg_value, if such an Instruction is
107-
// found, debug information is dropped.
108-
for (VarID Var : DebugVariablesBeforeSet) {
109-
if (DebugVariablesAfterSet.contains(Var))
110-
continue;
111-
visitEveryInstruction(DroppedCount, InlinedAtsMap, Var);
112-
removeVarFromAllSets(Var, Func);
113-
}
114-
if (DroppedCount > 0) {
115-
llvm::outs() << PassLevel << ", " << PassID << ", " << DroppedCount
116-
<< ", " << FuncOrModName << "\n";
117-
PassDroppedVariables = true;
118-
} else
119-
PassDroppedVariables = false;
120-
}
81+
StringRef PassLevel, const Function *Func);
12182

12283
/// Check if a \p Var has been dropped or is a false positive. Also update the
12384
/// \p DroppedCount if a debug variable is dropped.
12485
bool updateDroppedCount(DILocation *DbgLoc, const DIScope *Scope,
12586
const DIScope *DbgValScope,
12687
DenseMap<VarID, DILocation *> &InlinedAtsMap,
127-
VarID Var, unsigned &DroppedCount) {
128-
// If the Scope is a child of, or equal to the DbgValScope and is inlined at
129-
// the Var's InlinedAt location, return true to signify that the Var has
130-
// been dropped.
131-
if (isScopeChildOfOrEqualTo(Scope, DbgValScope))
132-
if (isInlinedAtChildOfOrEqualTo(DbgLoc->getInlinedAt(),
133-
InlinedAtsMap[Var])) {
134-
// Found another instruction in the variable's scope, so there exists a
135-
// break point at which the variable could be observed. Count it as
136-
// dropped.
137-
DroppedCount++;
138-
return true;
139-
}
140-
return false;
141-
}
88+
VarID Var, unsigned &DroppedCount);
89+
14290
/// Run code to populate relevant data structures over an llvm::Function or
14391
/// llvm::MachineFunction.
144-
void run(DebugVariables &DbgVariables, StringRef FuncName, bool Before) {
145-
auto &VarIDSet = (Before ? DbgVariables.DebugVariablesBefore
146-
: DbgVariables.DebugVariablesAfter);
147-
auto &InlinedAtsMap = InlinedAts.back();
148-
if (Before)
149-
InlinedAtsMap.try_emplace(FuncName, DenseMap<VarID, DILocation *>());
150-
VarIDSet = DenseSet<VarID>();
151-
visitEveryDebugRecord(VarIDSet, InlinedAtsMap, FuncName, Before);
152-
}
92+
void run(DebugVariables &DbgVariables, StringRef FuncName, bool Before);
93+
15394
/// Populate the VarIDSet and InlinedAtMap with the relevant information
15495
/// needed for before and after pass analysis to determine dropped variable
15596
/// status.
15697
void populateVarIDSetAndInlinedMap(
15798
const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,
15899
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
159-
StringRef FuncName, bool Before) {
160-
VarID Key{DbgVar->getScope(), DbgLoc->getInlinedAtScope(), DbgVar};
161-
VarIDSet.insert(Key);
162-
if (Before)
163-
InlinedAtsMap[FuncName].try_emplace(Key, DbgLoc.getInlinedAt());
164-
}
100+
StringRef FuncName, bool Before);
101+
165102
/// Visit every llvm::Instruction or llvm::MachineInstruction and check if the
166103
/// debug variable denoted by its ID \p Var may have been dropped by an
167104
/// optimization pass.
@@ -179,47 +116,18 @@ class DroppedVariableStats {
179116
private:
180117
/// Remove a dropped debug variable's VarID from all Sets in the
181118
/// DroppedVariablesBefore stack.
182-
void removeVarFromAllSets(VarID Var, const Function *F) {
183-
// Do not remove Var from the last element, it will be popped from the
184-
// stack.
185-
for (auto &DebugVariablesMap : llvm::drop_end(DebugVariablesStack))
186-
DebugVariablesMap[F].DebugVariablesBefore.erase(Var);
187-
}
119+
void removeVarFromAllSets(VarID Var, const Function *F);
120+
188121
/// Return true if \p Scope is the same as \p DbgValScope or a child scope of
189122
/// \p DbgValScope, return false otherwise.
190123
bool isScopeChildOfOrEqualTo(const DIScope *Scope,
191-
const DIScope *DbgValScope) {
192-
while (Scope != nullptr) {
193-
if (VisitedScope.find(Scope) == VisitedScope.end()) {
194-
VisitedScope.insert(Scope);
195-
if (Scope == DbgValScope) {
196-
VisitedScope.clear();
197-
return true;
198-
}
199-
Scope = Scope->getScope();
200-
} else {
201-
VisitedScope.clear();
202-
return false;
203-
}
204-
}
205-
return false;
206-
}
124+
const DIScope *DbgValScope);
125+
207126
/// Return true if \p InlinedAt is the same as \p DbgValInlinedAt or part of
208127
/// the InlinedAt chain, return false otherwise.
209128
bool isInlinedAtChildOfOrEqualTo(const DILocation *InlinedAt,
210-
const DILocation *DbgValInlinedAt) {
211-
if (DbgValInlinedAt == InlinedAt)
212-
return true;
213-
if (!DbgValInlinedAt)
214-
return false;
215-
auto *IA = InlinedAt;
216-
while (IA) {
217-
if (IA == DbgValInlinedAt)
218-
return true;
219-
IA = IA->getInlinedAt();
220-
}
221-
return false;
222-
}
129+
const DILocation *DbgValInlinedAt);
130+
223131
bool PassDroppedVariables = false;
224132
};
225133

llvm/include/llvm/Passes/DroppedVariableStatsIR.h renamed to llvm/include/llvm/IR/DroppedVariableStatsIR.h

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@
1414
#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATSIR_H
1515
#define LLVM_CODEGEN_DROPPEDVARIABLESTATSIR_H
1616

17-
#include "llvm/IR/InstIterator.h"
18-
#include "llvm/IR/Module.h"
19-
#include "llvm/Passes/DroppedVariableStats.h"
17+
#include "llvm/IR/DroppedVariableStats.h"
2018

2119
namespace llvm {
2220

21+
class Any;
22+
class StringRef;
23+
class PassInstrumentationCallbacks;
24+
class Function;
25+
class Module;
26+
class DILocation;
27+
2328
/// A class to collect and print dropped debug information due to LLVM IR
2429
/// optimization passes. After every LLVM IR pass is run, it will print how many
2530
/// #dbg_values were dropped due to that pass.
@@ -28,56 +33,42 @@ class DroppedVariableStatsIR : public DroppedVariableStats {
2833
DroppedVariableStatsIR(bool DroppedVarStatsEnabled)
2934
: llvm::DroppedVariableStats(DroppedVarStatsEnabled) {}
3035

31-
void runBeforePass(StringRef P, Any IR) {
32-
setup();
33-
if (const auto *M = unwrapIR<Module>(IR))
34-
return this->runOnModule(P, M, true);
35-
if (const auto *F = unwrapIR<Function>(IR))
36-
return this->runOnFunction(P, 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-
}
36+
void runBeforePass(StringRef P, Any IR);
37+
38+
void runAfterPass(StringRef P, Any IR);
4639

4740
void registerCallbacks(PassInstrumentationCallbacks &PIC);
4841

4942
private:
5043
const Function *Func;
5144

52-
void runAfterPassFunction(StringRef PassID, const Function *F) {
53-
runOnFunction(PassID, F, false);
54-
calculateDroppedVarStatsOnFunction(F, PassID, F->getName().str(),
55-
"Function");
56-
}
45+
void runAfterPassFunction(StringRef PassID, const Function *F);
46+
47+
void runAfterPassModule(StringRef PassID, const Module *M);
5748

58-
void runAfterPassModule(StringRef PassID, const Module *M) {
59-
runOnModule(PassID, M, false);
60-
calculateDroppedVarStatsOnModule(M, PassID, M->getName().str(), "Module");
61-
}
6249
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
6350
/// after a pass has run to facilitate dropped variable calculation for an
6451
/// llvm::Function.
6552
void runOnFunction(StringRef PassID, const Function *F, bool Before);
53+
6654
/// Iterate over all Instructions in a Function and report any dropped debug
6755
/// information.
6856
void calculateDroppedVarStatsOnFunction(const Function *F, StringRef PassID,
6957
StringRef FuncOrModName,
7058
StringRef PassLevel);
59+
7160
/// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
7261
/// after a pass has run to facilitate dropped variable calculation for an
7362
/// llvm::Module. Calls runOnFunction on every Function in the Module.
7463
void runOnModule(StringRef PassID, const Module *M, bool Before);
64+
7565
/// Iterate over all Functions in a Module and report any dropped debug
7666
/// information. Will call calculateDroppedVarStatsOnFunction on every
7767
/// Function.
7868
void calculateDroppedVarStatsOnModule(const Module *M, StringRef PassID,
7969
StringRef FuncOrModName,
8070
StringRef PassLevel);
71+
8172
/// Override base class method to run on an llvm::Function specifically.
8273
virtual void
8374
visitEveryInstruction(unsigned &DroppedCount,
@@ -90,10 +81,7 @@ class DroppedVariableStatsIR : public DroppedVariableStats {
9081
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
9182
StringRef FuncName, bool Before) override;
9283

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-
}
84+
template <typename IRUnitT> static const IRUnitT *unwrapIR(Any IR);
9785
};
9886

9987
} // namespace llvm

llvm/include/llvm/Passes/StandardInstrumentations.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
#include "llvm/CodeGen/MachineBasicBlock.h"
2323
#include "llvm/IR/BasicBlock.h"
2424
#include "llvm/IR/DebugInfoMetadata.h"
25+
#include "llvm/IR/DroppedVariableStatsIR.h"
2526
#include "llvm/IR/OptBisect.h"
2627
#include "llvm/IR/PassTimingInfo.h"
2728
#include "llvm/IR/ValueHandle.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/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ add_llvm_component_library(LLVMCodeGen
5050
DeadMachineInstructionElim.cpp
5151
DetectDeadLanes.cpp
5252
DFAPacketizer.cpp
53+
DroppedVariableStatsMIR.cpp
5354
DwarfEHPrepare.cpp
5455
EarlyIfConversion.cpp
5556
EdgeBundles.cpp

0 commit comments

Comments
 (0)