21#define DEBUG_TYPE "Compare"
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();
37constexpr unsigned getHeader() {
38 return static_cast<unsigned>(LVCompareIndex::Header);
40constexpr unsigned getExpected() {
41 return static_cast<unsigned>(LVCompareIndex::Expected);
43constexpr unsigned getMissing() {
44 return static_cast<unsigned>(LVCompareIndex::Missing);
46constexpr unsigned getAdded() {
47 return static_cast<unsigned>(LVCompareIndex::Added);
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;
59 IterTotal =
Results.find(LVCompareItem::Total);
63LVCompareInfo::iterator getResultsEntry(
LVElement *Element) {
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;
72 Kind = LVCompareItem::Type;
75 LVCompareInfo::iterator Iter =
Results.find(Kind);
81 LVCompareInfo::iterator Iter = getResultsEntry(Element);
83 ++std::get<getExpected()>(IterTotal->second);
85 ++std::get<getExpected()>(Iter->second);
89 LVCompareInfo::iterator Iter = getResultsEntry(Element);
90 if (
Pass == LVComparePass::Missing) {
91 ++std::get<getMissing()>(IterTotal->second);
92 ++std::get<getMissing()>(Iter->second);
94 ++std::get<getAdded()>(IterTotal->second);
95 ++std::get<getAdded()>(Iter->second);
103 return CurrentComparator ? *CurrentComparator : DefaultComparator;
106void LVCompare::setInstance(
LVCompare *Comparator) {
107 CurrentComparator = Comparator;
111 PrintLines =
options().getPrintLines();
112 PrintSymbols =
options().getPrintSymbols();
113 PrintTypes =
options().getPrintTypes();
115 options().getPrintScopes() || PrintLines || PrintSymbols || PrintTypes;
140 ReferenceRoot->setIsInCompare();
141 TargetRoot->setIsInCompare();
146 if (
options().getCompareContext()) {
151 LHS->markMissingParents(
RHS,
true);
152 if (
LHS->getIsMissingLink() &&
options().getReportAnyView()) {
154 options().setPrintFormatting();
155 OS <<
"\nMissing Tree:\n";
156 if (
Error Err =
LHS->doPrint(
false,
false,
159 options().resetPrintFormatting();
168 options().resetPrintFormatting();
170 PrintHeader(ReferenceRoot, TargetRoot);
171 Reader = ReferenceReader;
172 if (
Error Err = CompareViews(ReferenceRoot, TargetRoot))
177 PrintHeader(TargetRoot, ReferenceRoot);
178 Reader = TargetReader;
179 if (
Error Err = CompareViews(TargetRoot, ReferenceRoot))
184 options().setPrintFormatting();
194 using LVScopeLink = std::map<LVScope *, LVScope *>;
195 LVScopeLink ScopeLinks;
198 auto FindMatch = [&](
auto &References,
auto &Targets,
199 const char *Category) ->
Error {
217 ScopeLinks.emplace(
static_cast<LVScope *
>(CurrentTarget),
234 if (
options().getReportList()) {
236 OS <<
"\n(" <<
Elements.size() <<
") "
238 << Category <<
":\n";
240 if (
Error Err = Element->doPrint(
false,
false,
253 if (
options().getCompareScopes())
254 if (
Error Err = FindMatch(
LHS->getScopes(),
RHS->getScopes(),
"Scopes"))
256 if (
options().getCompareSymbols())
258 FindMatch(
LHS->getSymbols(),
RHS->getSymbols(),
"Symbols"))
260 if (
options().getCompareTypes())
261 if (
Error Err = FindMatch(
LHS->getTypes(),
RHS->getTypes(),
"Types"))
263 if (
options().getCompareLines())
264 if (
Error Err = FindMatch(
LHS->getLines(),
RHS->getLines(),
"Lines"))
273 options().resetPrintFormatting();
275 PrintHeader(ReferenceRoot, TargetRoot);
277 updateExpected(ReferenceRoot);
280 Reader = ReferenceReader;
281 if (
Error Err = CompareReaders(ReferenceReader, TargetReader, ElementsToAdd,
284 Reader = TargetReader;
285 if (
Error Err = CompareReaders(TargetReader, ReferenceReader, ElementsToAdd,
290 dbgs() <<
"\nReference/Target Scope links:\n";
291 for (LVScopeLink::const_reference Entry : ScopeLinks)
301 for (
LVElement *Element : ElementsToAdd) {
310 if (Element->getHasMoved())
314 Parent = Element->getParentScope();
315 if (ScopeLinks.find(Parent) != ScopeLinks.end()) {
316 LVScope *InsertionPoint = ScopeLinks[Parent];
318 dbgs() <<
"Inserted at: "
321 if (Parent->removeElement(Element)) {
325 Element->updateLevel(InsertionPoint,
true);
330 options().setPrintFormatting();
333 if (
options().getReportAnyView())
338 dbgs() <<
"\nModified Reference Reader";
341 dbgs() <<
"\nModified Target Reader";
353void LVCompare::printCurrentStack() {
354 for (
const LVScope *Scope : ScopeStack) {
355 Scope->printAttributes(OS);
356 OS << Scope->lineNumberAsString(
true) <<
" " << Scope->kind()
363 updateExpected(Element);
364 updateMissingOrAdded(Element,
Pass);
367 if (Element->getIsMissing())
370 if ((!PrintLines && Element->getIsLine()) ||
371 (!PrintScopes && Element->getIsScope()) ||
372 (!PrintSymbols && Element->getIsSymbol()) ||
373 (!PrintTypes && Element->getIsType()))
376 if (Element->getIsMissing()) {
379 FirstMissing =
false;
391 if (
options().getReportList()) {
400void LVCompare::printSummary()
const {
401 if (!
options().getPrintSummary())
403 std::string Separator = std::string(40,
'-');
404 auto PrintSeparator = [&]() { OS << Separator <<
"\n"; };
405 auto PrintHeadingRow = [&](
const char *
T,
const char *U,
const char *V,
407 OS <<
format(
"%-9s%9s %9s %9s\n",
T, U, V, W);
409 auto PrintDataRow = [&](
const char *
T,
unsigned U,
unsigned V,
unsigned W) {
410 OS <<
format(
"%-9s%9d %9d %9d\n",
T, U, V, W);
415 PrintHeadingRow(
"Element",
"Expected",
"Missing",
"Added");
417 for (LVCompareInfo::reference Entry :
Results) {
418 if (
Entry.first == LVCompareItem::Total)
420 PrintDataRow(std::get<getHeader()>(
Entry.second),
421 std::get<getExpected()>(
Entry.second),
422 std::get<getMissing()>(
Entry.second),
423 std::get<getAdded()>(
Entry.second));
Function Alias Analysis Results
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
StringRef getName() const
Return a constant reference to the value's name.
void print(raw_ostream &OS) const
void printItem(LVElement *Element, LVComparePass Pass)
static LVCompare & getInstance()
Error execute(LVReader *ReferenceReader, LVReader *TargetReader)
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
LVOffset getOffset() 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 addElement(LVElement *Element)
void report(LVComparePass Pass) override
LVScope * getCompileUnitParent() const override
This class implements an extremely fast bulk output stream that can only output to a stream.
std::string hexSquareString(uint64_t Value)
std::string formattedName(StringRef Name)
This is an optimization pass for GlobalISel generic memory operations.
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
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.