LLVM: lib/DebugInfo/LogicalView/Core/LVCompare.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
16#include
17
18using namespace llvm;
20
21#define DEBUG_TYPE "Compare"
22
23namespace {
24
25enum class LVCompareItem { Scope, Symbol, Type, Line, Total };
27using LVCompareEntry = std::tuple<const char *, unsigned, unsigned, unsigned>;
28using LVCompareInfo = std::map<LVCompareItem, LVCompareEntry>;
30 {LVCompareItem::Line, LVCompareEntry("Lines", 0, 0, 0)},
31 {LVCompareItem::Scope, LVCompareEntry("Scopes", 0, 0, 0)},
32 {LVCompareItem::Symbol, LVCompareEntry("Symbols", 0, 0, 0)},
33 {LVCompareItem::Type, LVCompareEntry("Types", 0, 0, 0)},
34 {LVCompareItem::Total, LVCompareEntry("Total", 0, 0, 0)}};
35static LVCompareInfo::iterator IterTotal = Results.end();
36
37constexpr unsigned getHeader() {
38 return static_cast<unsigned>(LVCompareIndex::Header);
39}
40constexpr unsigned getExpected() {
41 return static_cast<unsigned>(LVCompareIndex::Expected);
42}
43constexpr unsigned getMissing() {
44 return static_cast<unsigned>(LVCompareIndex::Missing);
45}
46constexpr unsigned getAdded() {
47 return static_cast<unsigned>(LVCompareIndex::Added);
48}
49
50LVCompare *CurrentComparator = nullptr;
51
52void zeroResults() {
53
54 for (LVCompareInfo::reference Entry : Results) {
55 std::get<getExpected()>(Entry.second) = 0;
56 std::get<getMissing()>(Entry.second) = 0;
57 std::get<getAdded()>(Entry.second) = 0;
58 }
59 IterTotal = Results.find(LVCompareItem::Total);
61}
62
63LVCompareInfo::iterator getResultsEntry(LVElement *Element) {
64 LVCompareItem Kind;
65 if (Element->getIsLine())
66 Kind = LVCompareItem::Line;
67 else if (Element->getIsScope())
68 Kind = LVCompareItem::Scope;
69 else if (Element->getIsSymbol())
70 Kind = LVCompareItem::Symbol;
71 else
72 Kind = LVCompareItem::Type;
73
74
75 LVCompareInfo::iterator Iter = Results.find(Kind);
77 return Iter;
78}
79
80void updateExpected(LVElement *Element) {
81 LVCompareInfo::iterator Iter = getResultsEntry(Element);
82
83 ++std::get<getExpected()>(IterTotal->second);
84
85 ++std::get<getExpected()>(Iter->second);
86}
87
89 LVCompareInfo::iterator Iter = getResultsEntry(Element);
91 ++std::get<getMissing()>(IterTotal->second);
92 ++std::get<getMissing()>(Iter->second);
93 } else {
94 ++std::get<getAdded()>(IterTotal->second);
95 ++std::get<getAdded()>(Iter->second);
96 }
97}
98
99}
100
103 return CurrentComparator ? *CurrentComparator : DefaultComparator;
104}
105
106void LVCompare::setInstance(LVCompare *Comparator) {
107 CurrentComparator = Comparator;
108}
109
111 PrintLines = options().getPrintLines();
112 PrintSymbols = options().getPrintSymbols();
113 PrintTypes = options().getPrintTypes();
114 PrintScopes =
115 options().getPrintScopes() || PrintLines || PrintSymbols || PrintTypes;
116}
117
119 setInstance(this);
120
121
123
126 dbgs() << "[Reference] " << LHS->getName() << "\n"
127 << "[Target] " << RHS->getName() << "\n";
128 });
129 OS << "\nReference: " << formattedName(LHS->getName()) << "\n"
130 << "Target: " << formattedName(RHS->getName()) << "\n";
131 };
132
133
134
135
136
137
140 ReferenceRoot->setIsInCompare();
141 TargetRoot->setIsInCompare();
142
143
144 zeroResults();
145
146 if (options().getCompareContext()) {
147
148
149
151 LHS->markMissingParents(RHS, true);
152 if (LHS->getIsMissingLink() && options().getReportAnyView()) {
153
154 options().setPrintFormatting();
155 OS << "\nMissing Tree:\n";
156 if (Error Err = LHS->doPrint(false, false,
157 true, OS))
158 return Err;
159 options().resetPrintFormatting();
160 }
161
163 };
164
165
166
167
168 options().resetPrintFormatting();
169
170 PrintHeader(ReferenceRoot, TargetRoot);
171 Reader = ReferenceReader;
172 if (Error Err = CompareViews(ReferenceRoot, TargetRoot))
173 return Err;
174 FirstMissing = true;
176
177 PrintHeader(TargetRoot, ReferenceRoot);
178 Reader = TargetReader;
179 if (Error Err = CompareViews(TargetRoot, ReferenceRoot))
180 return Err;
181 FirstMissing = true;
183
184 options().setPrintFormatting();
185
186
187 printSummary();
188 } else {
189
190
191
192
193
194 using LVScopeLink = std::map<LVScope *, LVScope *>;
195 LVScopeLink ScopeLinks;
198 auto FindMatch = [&](auto &References, auto &Targets,
199 const char *Category) -> Error {
202
203
204 if (Reference->getIncludeInPrint()) {
208 LVElement *CurrentTarget = nullptr;
210 CurrentTarget = Target;
212 })) {
214
215
216
217 ScopeLinks.emplace(static_cast<LVScope *>(CurrentTarget),
219 }
220 } else {
221
226
228 }
229 }
230 }
232
234 if (options().getReportList()) {
236 OS << "\n(" << Elements.size() << ") "
238 << Category << ":\n";
240 if (Error Err = Element->doPrint(false, false,
241 true, OS))
242 return Err;
243 }
244 }
245 }
246
248 };
249
250
251
252
253 if (options().getCompareScopes())
254 if (Error Err = FindMatch(LHS->getScopes(), RHS->getScopes(), "Scopes"))
255 return Err;
256 if (options().getCompareSymbols())
258 FindMatch(LHS->getSymbols(), RHS->getSymbols(), "Symbols"))
259 return Err;
260 if (options().getCompareTypes())
261 if (Error Err = FindMatch(LHS->getTypes(), RHS->getTypes(), "Types"))
262 return Err;
263 if (options().getCompareLines())
264 if (Error Err = FindMatch(LHS->getLines(), RHS->getLines(), "Lines"))
265 return Err;
266
268 };
269
270
271
272
273 options().resetPrintFormatting();
274
275 PrintHeader(ReferenceRoot, TargetRoot);
276
277 updateExpected(ReferenceRoot);
278
280 Reader = ReferenceReader;
281 if (Error Err = CompareReaders(ReferenceReader, TargetReader, ElementsToAdd,
283 return Err;
284 Reader = TargetReader;
285 if (Error Err = CompareReaders(TargetReader, ReferenceReader, ElementsToAdd,
287 return Err;
288
290 dbgs() << "\nReference/Target Scope links:\n";
291 for (LVScopeLink::const_reference Entry : ScopeLinks)
293 << "Destination: " << hexSquareString(Entry.second->getOffset())
294 << "\n";
295 dbgs() << "\n";
296 });
297
298
299
300 LVScope *Parent = nullptr;
301 for (LVElement *Element : ElementsToAdd) {
304 << ", Parent: "
305 << hexSquareString(Element->getParentScope()->getOffset())
306 << "\n";
307 });
308
309
310 if (Element->getHasMoved())
311 continue;
312
313
314 Parent = Element->getParentScope();
315 auto It = ScopeLinks.find(Parent);
316 if (It != ScopeLinks.end()) {
319 dbgs() << "Inserted at: "
321 });
322 if (Parent->removeElement(Element)) {
323
326 Element->updateLevel(InsertionPoint, true);
327 }
328 }
329 }
330
331 options().setPrintFormatting();
332
333
334 if (options().getReportAnyView())
336 return Err;
337
339 dbgs() << "\nModified Reference Reader";
341 return Err;
342 dbgs() << "\nModified Target Reader";
344 return Err;
345 });
346
347
348 printSummary();
349 }
350
352}
353
354void LVCompare::printCurrentStack() {
355 for (const LVScope *Scope : ScopeStack) {
356 Scope->printAttributes(OS);
357 OS << Scope->lineNumberAsString(true) << " " << Scope->kind()
358 << " " << formattedName(Scope->getName()) << "\n";
359 }
360}
361
363
364 updateExpected(Element);
365 updateMissingOrAdded(Element, Pass);
366
367
368 if (Element->getIsMissing())
370
371 if ((!PrintLines && Element->getIsLine()) ||
372 (!PrintScopes && Element->getIsScope()) ||
373 (!PrintSymbols && Element->getIsSymbol()) ||
374 (!PrintTypes && Element->getIsType()))
375 return;
376
377 if (Element->getIsMissing()) {
378 if (FirstMissing) {
379 OS << "\n";
380 FirstMissing = false;
381 }
382
390 OS << "\n";
391
392 if (options().getReportList()) {
393 printCurrentStack();
396 << Name << "\n";
397 }
398 }
399}
400
401void LVCompare::printSummary() const {
402 if (().getPrintSummary())
403 return;
404 std::string Separator = std::string(40, '-');
405 auto PrintSeparator = [&]() { OS << Separator << "\n"; };
406 auto PrintHeadingRow = [&](const char *T, const char *U, const char *V,
407 const char *W) {
408 OS << format("%-9s%9s %9s %9s\n", T, U, V, W);
409 };
410 auto PrintDataRow = [&](const char *T, unsigned U, unsigned V, unsigned W) {
411 OS << format("%-9s%9d %9d %9d\n", T, U, V, W);
412 };
413
414 OS << "\n";
415 PrintSeparator();
416 PrintHeadingRow("Element", "Expected", "Missing", "Added");
417 PrintSeparator();
418 for (LVCompareInfo::reference Entry : Results) {
419 if (Entry.first == LVCompareItem::Total)
420 PrintSeparator();
421 PrintDataRow(std::get<getHeader()>(Entry.second),
422 std::get<getExpected()>(Entry.second),
423 std::get<getMissing()>(Entry.second),
424 std::get<getAdded()>(Entry.second));
425 }
426}
427
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Function Alias Analysis Results
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Pass interface - Implemented by all 'passes'.
StringRef - Represent a constant reference to a string, i.e.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI void print(raw_ostream &OS) const
Definition LVCompare.cpp:428
LLVM_ABI void printItem(LVElement *Element, LVComparePass Pass)
Definition LVCompare.cpp:362
static LLVM_ABI LVCompare & getInstance()
Definition LVCompare.cpp:101
LLVM_ABI Error execute(LVReader *ReferenceReader, LVReader *TargetReader)
Definition LVCompare.cpp:118
void addPassEntry(LVReader *Reader, LVElement *Element, LVComparePass Pass)
StringRef getName() const override
StringRef getPathname() const
virtual const char * kind() const
void printAttributes(raw_ostream &OS, bool Full=true) const
virtual std::string lineNumberAsString(bool ShowZero=false) const
uint32_t getLineNumber() const
The logical reader owns of all the logical elements created during the debug information parsing.
static void setInstance(LVReader *Reader)
LVScopeRoot * getScopesRoot() const
void setCompileUnit(LVScope *Scope)
void report(LVComparePass Pass) override
This class implements an extremely fast bulk output stream that can only output to a stream.
SmallVector< LVElement *, 8 > LVElements
std::string hexSquareString(uint64_t Value)
std::string formattedName(StringRef Name)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.