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 (options().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.