Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/IR/DroppedVariableStats.cpp
213766 views
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
14
#include "llvm/IR/DroppedVariableStats.h"
15
#include "llvm/IR/DebugInfoMetadata.h"
16
#include "llvm/IR/DiagnosticInfo.h"
17
#include "llvm/IR/Function.h"
18
19
using namespace llvm;
20
21
DroppedVariableStats::DroppedVariableStats(bool DroppedVarStatsEnabled)
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
28
void DroppedVariableStats::setup() {
29
DebugVariablesStack.push_back({DenseMap<const Function *, DebugVariables>()});
30
InlinedAts.push_back({DenseMap<StringRef, DenseMap<VarID, DILocation *>>()});
31
}
32
33
void DroppedVariableStats::cleanup() {
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
41
void DroppedVariableStats::calculateDroppedStatsAndPrint(
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
70
bool DroppedVariableStats::updateDroppedCount(
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
89
void DroppedVariableStats::run(DebugVariables &DbgVariables, StringRef FuncName,
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
100
void DroppedVariableStats::populateVarIDSetAndInlinedMap(
101
const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,
102
DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
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
110
void 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
117
bool 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
134
bool 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
}
148
149