LLVM: lib/CodeGen/AsmPrinter/AccelTable.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

26#include

27#include

28#include

29#include

30

31using namespace llvm;

32

42

44

46

49 return *A < *B;

50 });

51 E.second.Values.erase(llvm::unique(E.second.Values), E.second.Values.end());

52 }

53

54

55

56

57

59

60

64 Buckets[Bucket].push_back(&E.second);

65 E.second.Sym = Asm->createTempSymbol(Prefix);

66 }

67

68

69

70 for (auto &Bucket : Buckets)

72 return LHS->HashValue < RHS->HashValue;

73 });

74}

75

76namespace {

77

78

79class AccelTableWriter {

80protected:

81 AsmPrinter *const Asm;

83

84

85

86

87 const bool SkipIdenticalHashes;

88

89 void emitHashes() const;

90

91

92

94

95public:

97 bool SkipIdenticalHashes)

98 : Asm(Asm), Contents(Contents), SkipIdenticalHashes(SkipIdenticalHashes) {

99 }

100};

101

102class AppleAccelTableWriter : public AccelTableWriter {

103 using Atom = AppleAccelTableData::Atom;

104

105

106 struct Header {

107 uint32_t Magic = MagicHash;

110 uint32_t BucketCount;

111 uint32_t HashCount;

112 uint32_t HeaderDataLength;

113

114

115 static const uint32_t MagicHash = 0x48415348;

116

117 Header(uint32_t BucketCount, uint32_t UniqueHashCount, uint32_t DataLength)

118 : BucketCount(BucketCount), HashCount(UniqueHashCount),

119 HeaderDataLength(DataLength) {}

120

121 void emit(AsmPrinter *Asm) const;

122#ifndef NDEBUG

123 void print(raw_ostream &OS) const;

125#endif

126 };

127

128

129

130 struct HeaderData {

131

132

133 uint32_t DieOffsetBase;

134

136

138 : DieOffsetBase(Offset), Atoms(AtomList) {}

139

140 void emit(AsmPrinter *Asm) const;

141#ifndef NDEBUG

142 void print(raw_ostream &OS) const;

144#endif

145 };

146

147 Header Header;

148 HeaderData HeaderData;

150

151 void emitBuckets() const;

152 void emitData() const;

153

154public:

155 AppleAccelTableWriter(AsmPrinter *Asm, const AccelTableBase &Contents,

157 : AccelTableWriter(Asm, Contents, true),

158 Header(Contents.getBucketCount(), Contents.getUniqueHashCount(),

159 8 + (Atoms.size() * 4)),

160 HeaderData(Atoms), SecBegin(SecBegin) {}

161

162 void emit() const;

163

164#ifndef NDEBUG

165 void print(raw_ostream &OS) const;

167#endif

168};

169

170

171

172

173

174class Dwarf5AccelTableWriter : public AccelTableWriter {

175 struct Header {

178 uint32_t CompUnitCount;

179 uint32_t LocalTypeUnitCount = 0;

180 uint32_t ForeignTypeUnitCount = 0;

181 uint32_t BucketCount = 0;

182 uint32_t NameCount = 0;

183 uint32_t AbbrevTableSize = 0;

184 uint32_t AugmentationStringSize = sizeof(AugmentationString);

185 char AugmentationString[8] = {'L', 'L', 'V', 'M', '0', '7', '0', '0'};

186

187 Header(uint32_t CompUnitCount, uint32_t LocalTypeUnitCount,

188 uint32_t ForeignTypeUnitCount, uint32_t BucketCount,

189 uint32_t NameCount)

190 : CompUnitCount(CompUnitCount), LocalTypeUnitCount(LocalTypeUnitCount),

191 ForeignTypeUnitCount(ForeignTypeUnitCount), BucketCount(BucketCount),

192 NameCount(NameCount) {}

193

194 void emit(Dwarf5AccelTableWriter &Ctx);

195 };

196

197 Header Header;

198

199 FoldingSet AbbreviationsSet;

200

202

203

207 llvm::function_ref<std::optionalDWARF5AccelTable::UnitIndexAndEncoding(

208 const DWARF5AccelTableData &)>

209 getIndexForEntry;

210 MCSymbol *ContributionEnd = nullptr;

211 MCSymbol *AbbrevStart = Asm->createTempSymbol("names_abbrev_start");

212 MCSymbol *AbbrevEnd = Asm->createTempSymbol("names_abbrev_end");

213 MCSymbol *EntryPool = Asm->createTempSymbol("names_entries");

214

215 bool IsSplitDwarf = false;

216

217 DenseSet IndexedOffsets;

218

219 void populateAbbrevsMap();

220

221 void emitCUList() const;

222 void emitTUList() const;

223 void emitBuckets() const;

224 void emitStringOffsets() const;

225 void emitAbbrevs() const;

226 void emitEntry(

227 const DWARF5AccelTableData &Entry,

228 const DenseMap<OffsetAndUnitID, MCSymbol *> &DIEOffsetToAccelEntryLabel,

229 DenseSet<MCSymbol *> &EmittedAccelEntrySymbols);

230 void emitData();

231

232public:

233 Dwarf5AccelTableWriter(

234 AsmPrinter *Asm, const AccelTableBase &Contents,

235 ArrayRef<std::variant<MCSymbol *, uint64_t>> CompUnits,

236 ArrayRef<std::variant<MCSymbol *, uint64_t>> TypeUnits,

237 llvm::function_ref<std::optionalDWARF5AccelTable::UnitIndexAndEncoding(

238 const DWARF5AccelTableData &)>

239 getIndexForEntry,

240 bool IsSplitDwarf);

241 ~Dwarf5AccelTableWriter() {

242 for (DebugNamesAbbrev *Abbrev : AbbreviationsVector)

243 Abbrev->~DebugNamesAbbrev();

244 }

245 void emit();

246};

247}

248

249void AccelTableWriter::emitHashes() const {

250 uint64_t PrevHash = std::numeric_limits<uint64_t>::max();

251 unsigned BucketIdx = 0;

252 for (const auto &Bucket : Contents.getBuckets()) {

253 for (const auto &Hash : Bucket) {

254 uint32_t HashValue = Hash->HashValue;

255 if (SkipIdenticalHashes && PrevHash == HashValue)

256 continue;

257 Asm->OutStreamer->AddComment("Hash in Bucket " + Twine(BucketIdx));

258 Asm->emitInt32(HashValue);

259 PrevHash = HashValue;

260 }

261 BucketIdx++;

262 }

263}

264

265void AccelTableWriter::emitOffsets(const MCSymbol *Base) const {

266 const auto &Buckets = Contents.getBuckets();

267 uint64_t PrevHash = std::numeric_limits<uint64_t>::max();

268 for (size_t i = 0, e = Buckets.size(); i < e; ++i) {

269 for (auto *Hash : Buckets[i]) {

270 uint32_t HashValue = Hash->HashValue;

271 if (SkipIdenticalHashes && PrevHash == HashValue)

272 continue;

273 PrevHash = HashValue;

274 Asm->OutStreamer->AddComment("Offset in Bucket " + Twine(i));

275 Asm->emitLabelDifference(Hash->Sym, Base, Asm->getDwarfOffsetByteSize());

276 }

277 }

278}

279

280void AppleAccelTableWriter::Header::emit(AsmPrinter *Asm) const {

281 Asm->OutStreamer->AddComment("Header Magic");

282 Asm->emitInt32(Magic);

283 Asm->OutStreamer->AddComment("Header Version");

285 Asm->OutStreamer->AddComment("Header Hash Function");

286 Asm->emitInt16(HashFunction);

287 Asm->OutStreamer->AddComment("Header Bucket Count");

288 Asm->emitInt32(BucketCount);

289 Asm->OutStreamer->AddComment("Header Hash Count");

290 Asm->emitInt32(HashCount);

291 Asm->OutStreamer->AddComment("Header Data Length");

292 Asm->emitInt32(HeaderDataLength);

293}

294

295void AppleAccelTableWriter::HeaderData::emit(AsmPrinter *Asm) const {

296 Asm->OutStreamer->AddComment("HeaderData Die Offset Base");

297 Asm->emitInt32(DieOffsetBase);

298 Asm->OutStreamer->AddComment("HeaderData Atom Count");

299 Asm->emitInt32(Atoms.size());

300

301 for (const Atom &A : Atoms) {

303 Asm->emitInt16(A.Type);

305 Asm->emitInt16(A.Form);

306 }

307}

308

309void AppleAccelTableWriter::emitBuckets() const {

310 const auto &Buckets = Contents.getBuckets();

311 unsigned index = 0;

312 for (size_t i = 0, e = Buckets.size(); i < e; ++i) {

313 Asm->OutStreamer->AddComment("Bucket " + Twine(i));

314 if (!Buckets[i].empty())

315 Asm->emitInt32(index);

316 else

317 Asm->emitInt32(std::numeric_limits<uint32_t>::max());

318

319

320 uint64_t PrevHash = std::numeric_limits<uint64_t>::max();

321 for (auto *HD : Buckets[i]) {

322 uint32_t HashValue = HD->HashValue;

323 if (PrevHash != HashValue)

324 ++index;

325 PrevHash = HashValue;

326 }

327 }

328}

329

330void AppleAccelTableWriter::emitData() const {

331 const auto &Buckets = Contents.getBuckets();

333 uint64_t PrevHash = std::numeric_limits<uint64_t>::max();

334 for (const auto &Hash : Bucket) {

335

336

337 if (PrevHash != std::numeric_limits<uint64_t>::max() &&

338 PrevHash != Hash->HashValue)

339 Asm->emitInt32(0);

340

341 Asm->OutStreamer->emitLabel(Hash->Sym);

342 Asm->OutStreamer->AddComment(Hash->Name.getString());

343 Asm->emitDwarfStringOffset(Hash->Name);

344 Asm->OutStreamer->AddComment("Num DIEs");

345 Asm->emitInt32(Hash->Values.size());

347 V->emit(Asm);

348 PrevHash = Hash->HashValue;

349 }

350

351 if (!Bucket.empty())

352 Asm->emitInt32(0);

353 }

354}

355

356void AppleAccelTableWriter::emit() const {

357 Header.emit(Asm);

358 HeaderData.emit(Asm);

359 emitBuckets();

360 emitHashes();

361 emitOffsets(SecBegin);

362 emitData();

363}

364

370

371void Dwarf5AccelTableWriter::Header::emit(Dwarf5AccelTableWriter &Ctx) {

372 assert(CompUnitCount > 0 && "Index must have at least one CU.");

373

375 Ctx.ContributionEnd =

376 Asm->emitDwarfUnitLength("names", "Header: unit length");

377 Asm->OutStreamer->AddComment("Header: version");

379 Asm->OutStreamer->AddComment("Header: padding");

380 Asm->emitInt16(Padding);

381 Asm->OutStreamer->AddComment("Header: compilation unit count");

382 Asm->emitInt32(CompUnitCount);

383 Asm->OutStreamer->AddComment("Header: local type unit count");

384 Asm->emitInt32(LocalTypeUnitCount);

385 Asm->OutStreamer->AddComment("Header: foreign type unit count");

386 Asm->emitInt32(ForeignTypeUnitCount);

387 Asm->OutStreamer->AddComment("Header: bucket count");

388 Asm->emitInt32(BucketCount);

389 Asm->OutStreamer->AddComment("Header: name count");

390 Asm->emitInt32(NameCount);

391 Asm->OutStreamer->AddComment("Header: abbreviation table size");

392 Asm->emitLabelDifference(Ctx.AbbrevEnd, Ctx.AbbrevStart, sizeof(uint32_t));

393 Asm->OutStreamer->AddComment("Header: augmentation string size");

394 assert(AugmentationStringSize % 4 == 0);

395 Asm->emitInt32(AugmentationStringSize);

396 Asm->OutStreamer->AddComment("Header: augmentation string");

397 Asm->OutStreamer->emitBytes({AugmentationString, AugmentationStringSize});

398}

399

400std::optional<uint64_t>

402 if (auto *Parent = Die.getParent();

403 Parent && !Parent->findAttribute(dwarf::Attribute::DW_AT_declaration))

404 return Parent->getOffset();

405 return {};

406}

407

408static std::optionaldwarf::Form

410 std::optional ParentOffset) {

411

412 if (!ParentOffset)

413 return std::nullopt;

414

415 if (IndexedOffsets.contains(*ParentOffset))

416 return dwarf::Form::DW_FORM_ref4;

417

418 return dwarf::Form::DW_FORM_flag_present;

419}

420

424 ID.AddInteger(Enc.Index);

425 ID.AddInteger(Enc.Form);

426 }

427}

428

429void Dwarf5AccelTableWriter::populateAbbrevsMap() {

430 for (auto &Bucket : Contents.getBuckets()) {

431 for (auto *Hash : Bucket) {

433 std::optionalDWARF5AccelTable::UnitIndexAndEncoding EntryRet =

434 getIndexForEntry(*Value);

436 IndexedOffsets, Value->getParentDieOffsetAndUnitID());

438 if (EntryRet)

439 Abbrev.addAttribute(EntryRet->Encoding);

440 Abbrev.addAttribute({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4});

441 if (MaybeParentForm)

442 Abbrev.addAttribute({dwarf::DW_IDX_parent, *MaybeParentForm});

444 Abbrev.Profile(ID);

445 void *InsertPos;

448 Value->setAbbrevNumber(Existing->getNumber());

449 continue;

450 }

453 AbbreviationsVector.push_back(NewAbbrev);

454 NewAbbrev->setNumber(AbbreviationsVector.size());

455 AbbreviationsSet.InsertNode(NewAbbrev, InsertPos);

457 }

458 }

459 }

460}

461

462void Dwarf5AccelTableWriter::emitCUList() const {

463 for (const auto &CU : enumerate(CompUnits)) {

464 Asm->OutStreamer->AddComment("Compilation unit " + Twine(CU.index()));

465 if (std::holds_alternative<MCSymbol *>(CU.value()))

466 Asm->emitDwarfSymbolReference(std::get<MCSymbol *>(CU.value()));

467 else

468 Asm->emitDwarfLengthOrOffset(std::get<uint64_t>(CU.value()));

469 }

470}

471

472void Dwarf5AccelTableWriter::emitTUList() const {

473 for (const auto &TU : enumerate(TypeUnits)) {

474 Asm->OutStreamer->AddComment("Type unit " + Twine(TU.index()));

475 if (std::holds_alternative<MCSymbol *>(TU.value()))

476 Asm->emitDwarfSymbolReference(std::get<MCSymbol *>(TU.value()));

477 else if (IsSplitDwarf)

478 Asm->emitInt64(std::get<uint64_t>(TU.value()));

479 else

480 Asm->emitDwarfLengthOrOffset(std::get<uint64_t>(TU.value()));

481 }

482}

483

484void Dwarf5AccelTableWriter::emitBuckets() const {

485 uint32_t Index = 1;

487 Asm->OutStreamer->AddComment("Bucket " + Twine(Bucket.index()));

488 Asm->emitInt32(Bucket.value().empty() ? 0 : Index);

489 Index += Bucket.value().size();

490 }

491}

492

493void Dwarf5AccelTableWriter::emitStringOffsets() const {

495 for (auto *Hash : Bucket.value()) {

497 Asm->OutStreamer->AddComment("String in Bucket " + Twine(Bucket.index()) +

498 ": " + String.getString());

499 Asm->emitDwarfStringOffset(String);

500 }

501 }

502}

503

504void Dwarf5AccelTableWriter::emitAbbrevs() const {

505 Asm->OutStreamer->emitLabel(AbbrevStart);

507 Asm->OutStreamer->AddComment("Abbrev code");

508 Asm->emitULEB128(Abbrev->getNumber());

510 Asm->emitULEB128(Abbrev->getDieTag());

512 Abbrev->getAttributes()) {

514 Asm->emitULEB128(AttrEnc.Form,

516 }

517 Asm->emitULEB128(0, "End of abbrev");

518 Asm->emitULEB128(0, "End of abbrev");

519 }

520 Asm->emitULEB128(0, "End of abbrev list");

521 Asm->OutStreamer->emitLabel(AbbrevEnd);

522}

523

524void Dwarf5AccelTableWriter::emitEntry(

528 unsigned AbbrevIndex = Entry.getAbbrevNumber() - 1;

529 assert(AbbrevIndex < AbbreviationsVector.size() &&

530 "Entry abbrev index is outside of abbreviations vector range.");

532 std::optionalDWARF5AccelTable::UnitIndexAndEncoding EntryRet =

533 getIndexForEntry(Entry);

534 std::optional MaybeParentOffset =

535 Entry.getParentDieOffsetAndUnitID();

536 auto EntrySymbolIt =

537 DIEOffsetToAccelEntryLabel.find(Entry.getDieOffsetAndUnitID());

538 assert(EntrySymbolIt != DIEOffsetToAccelEntryLabel.end());

539 MCSymbol *EntrySymbol = EntrySymbolIt->getSecond();

540

541

542

543

544 if (EmittedAccelEntrySymbols.insert(EntrySymbol).second)

545 Asm->OutStreamer->emitLabel(EntrySymbol);

546

547 Asm->emitULEB128(Entry.getAbbrevNumber(), "Abbreviation code");

548

552 switch (AttrEnc.Index) {

553 case dwarf::DW_IDX_compile_unit:

554 case dwarf::DW_IDX_type_unit: {

556 ID.emitValue(Asm, AttrEnc.Form);

557 break;

558 }

559 case dwarf::DW_IDX_die_offset:

560 assert(AttrEnc.Form == dwarf::DW_FORM_ref4);

561 Asm->emitInt32(Entry.getDieOffset());

562 break;

563 case dwarf::DW_IDX_parent: {

564 if (AttrEnc.Form == dwarf::Form::DW_FORM_flag_present)

565 break;

566 auto ParentSymbolIt = DIEOffsetToAccelEntryLabel.find(*MaybeParentOffset);

567 assert(ParentSymbolIt != DIEOffsetToAccelEntryLabel.end());

568 Asm->emitLabelDifference(ParentSymbolIt->getSecond(), EntryPool, 4);

569 break;

570 }

571 default:

573 }

574 }

575}

576

577void Dwarf5AccelTableWriter::emitData() {

579

581 DIEOffsetToAccelEntryLabel.insert({Offset, Asm->createTempSymbol("")});

582

583 Asm->OutStreamer->emitLabel(EntryPool);

585 for (auto &Bucket : Contents.getBuckets()) {

586 for (auto *Hash : Bucket) {

587

588 Asm->OutStreamer->emitLabel(Hash->Sym);

590 emitEntry(*Value, DIEOffsetToAccelEntryLabel, EmittedAccelEntrySymbols);

591 Asm->OutStreamer->AddComment("End of list: " + Hash->Name.getString());

592 Asm->emitInt8(0);

593 }

594 }

595}

596

597Dwarf5AccelTableWriter::Dwarf5AccelTableWriter(

599 ArrayRef<std::variant<MCSymbol *, uint64_t>> CompUnits,

600 ArrayRef<std::variant<MCSymbol *, uint64_t>> TypeUnits,

601 llvm::function_ref<std::optionalDWARF5AccelTable::UnitIndexAndEncoding(

603 getIndexForEntry,

604 bool IsSplitDwarf)

605 : AccelTableWriter(Asm, Contents, false),

606 Header(CompUnits.size(), IsSplitDwarf ? 0 : TypeUnits.size(),

607 IsSplitDwarf ? TypeUnits.size() : 0, Contents.getBucketCount(),

608 Contents.getUniqueNameCount()),

609 CompUnits(CompUnits), TypeUnits(TypeUnits),

610 getIndexForEntry(std::move(getIndexForEntry)),

611 IsSplitDwarf(IsSplitDwarf) {

612

613 for (auto &Bucket : Contents.getBuckets())

614 for (auto *Hash : Bucket)

615 for (auto *Value : Hash->getValues<DWARF5AccelTableData *>())

616 IndexedOffsets.insert(Value->getDieOffsetAndUnitID());

617

618 populateAbbrevsMap();

619}

620

621void Dwarf5AccelTableWriter::emit() {

622 Header.emit(*this);

623 emitCUList();

624 emitTUList();

625 emitBuckets();

626 emitHashes();

627 emitStringOffsets();

628 emitOffsets(EntryPool);

629 emitAbbrevs();

630 emitData();

631 Asm->OutStreamer->emitValueToAlignment(Align(4), 0);

632 Asm->OutStreamer->emitLabel(ContributionEnd);

633}

634

638 Contents.finalize(Asm, Prefix);

639 AppleAccelTableWriter(Asm, Contents, Atoms, SecBegin).emit();

640}

641

644 ArrayRef<std::unique_ptr> CUs) {

646 std::vector<std::variant<MCSymbol *, uint64_t>> CompUnits;

647 std::vector<std::variant<MCSymbol *, uint64_t>> TypeUnits;

650 int CUCount = 0;

651 int TUCount = 0;

653 switch (CU.value()->getCUNode()->getNameTableKind()) {

656 break;

657 default:

658 continue;

659 }

660 CUIndex[CU.index()] = CUCount++;

661 assert(CU.index() == CU.value()->getUniqueID());

663 DD.useSplitDwarf() ? CU.value()->getSkeleton() : CU.value().get();

665 }

666

667 for (const auto &TU : TUSymbols) {

668 TUIndex[TU.UniqueID] = TUCount++;

670 TypeUnits.push_back(std::get<uint64_t>(TU.LabelOrSignature));

671 else

672 TypeUnits.push_back(std::get<MCSymbol *>(TU.LabelOrSignature));

673 }

674

675 if (CompUnits.empty())

676 return;

677

678 Asm->OutStreamer->switchSection(

679 Asm->getObjFileLowering().getDwarfDebugNamesSection());

680

681 Contents.finalize(Asm, "names");

686 Dwarf5AccelTableWriter(

687 Asm, Contents, CompUnits, TypeUnits,

689 -> std::optionalDWARF5AccelTable::UnitIndexAndEncoding {

690 if (Entry.isTU())

691 return {{TUIndex[Entry.getUnitID()],

692 {dwarf::DW_IDX_type_unit, TUIndexForm}}};

693 if (CUIndex.size() > 1)

694 return {{CUIndex[Entry.getUnitID()],

695 {dwarf::DW_IDX_compile_unit, CUIndexForm}}};

696 return std::nullopt;

697 },

699 .emit();

700}

701

703 TUSymbolsOrHashes.push_back({U.getLabelBegin(), U.getUniqueID()});

704}

705

707 TUSymbolsOrHashes.push_back({U.getTypeSignature(), U.getUniqueID()});

708}

709

712 ArrayRef<std::variant<MCSymbol *, uint64_t>> CUs,

713 llvm::function_ref<std::optionalDWARF5AccelTable::UnitIndexAndEncoding(

715 getIndexForEntry) {

716 std::vector<std::variant<MCSymbol *, uint64_t>> TypeUnits;

717 Contents.finalize(Asm, "names");

718 Dwarf5AccelTableWriter(Asm, Contents, CUs, TypeUnits, getIndexForEntry, false)

719 .emit();

720}

721

723 assert(Die.getDebugSectionOffset() <= UINT32_MAX &&

724 "The section offset exceeds the limit.");

725 Asm->emitInt32(Die.getDebugSectionOffset());

726}

727

729 assert(Die.getDebugSectionOffset() <= UINT32_MAX &&

730 "The section offset exceeds the limit.");

731 Asm->emitInt32(Die.getDebugSectionOffset());

732 Asm->emitInt16(Die.getTag());

733 Asm->emitInt8(0);

734}

735

737 Asm->emitInt32(Offset);

738}

739

741 Asm->emitInt32(Offset);

742 Asm->emitInt16(Tag);

744 : 0);

746}

747

748#ifndef NDEBUG

749void AppleAccelTableWriter::Header::print(raw_ostream &OS) const {

750 OS << "Magic: " << format("0x%x", Magic) << "\n"

751 << "Version: " << Version << "\n"

752 << "Hash Function: " << HashFunction << "\n"

753 << "Bucket Count: " << BucketCount << "\n"

754 << "Header Data Length: " << HeaderDataLength << "\n";

755}

756

761

762void AppleAccelTableWriter::HeaderData::print(raw_ostream &OS) const {

763 OS << "DIE Offset Base: " << DieOffsetBase << "\n";

764 for (auto Atom : Atoms)

766}

767

768void AppleAccelTableWriter::print(raw_ostream &OS) const {

769 Header.print(OS);

770 HeaderData.print(OS);

771 Contents.print(OS);

772 SecBegin->print(OS, nullptr);

773}

774

776 OS << "Name: " << Name.getString() << "\n";

777 OS << " Hash Value: " << format("0x%x", HashValue) << "\n";

778 OS << " Symbol: ";

780 OS << *Sym;

781 else

782 OS << "";

783 OS << "\n";

786}

787

789

790 OS << "Entries: \n";

791 for (const auto &[Name, Data] : Entries) {

792 OS << "Name: " << Name << "\n";

793 for (auto *V : Data.Values)

794 V->print(OS);

795 }

796

797 OS << "Buckets and Hashes: \n";

798 for (const auto &Bucket : Buckets)

799 for (const auto &Hash : Bucket)

800 Hash->print(OS);

801

802 OS << "Data: \n";

803 for (const auto &E : Entries)

804 E.second.print(OS);

805}

806

811

813 OS << " Offset: " << Die.getOffset() << "\n";

814}

815

817 OS << " Offset: " << Die.getOffset() << "\n";

819}

820

822 OS << " Static Offset: " << Offset << "\n";

823}

824

826 OS << " Static Offset: " << Offset << "\n";

829 OS << " ObjCClassIsImplementation: "

831 OS << "\n";

832}

833#endif

for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))

static std::optional< unsigned > getTag(const TargetRegisterInfo *TRI, const MachineInstr &MI, const LoadInfo &LI)

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

AMDGPU Prepare AGPR Alloc

static std::optional< dwarf::Form > getFormForIdxParent(const DenseSet< OffsetAndUnitID > &IndexedOffsets, std::optional< OffsetAndUnitID > ParentOffset)

Definition AccelTable.cpp:409

This file contains support for writing accelerator tables.

Function Alias Analysis false

static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

This file defines the DenseSet and SmallDenseSet classes.

This file contains constants used for implementing Dwarf debug support.

A base class holding non-template-dependant functionality of the AccelTable class.

std::vector< HashData * > HashList

LLVM_ABI void computeBucketCount()

Definition AccelTable.cpp:33

LLVM_ABI void finalize(AsmPrinter *Asm, StringRef Prefix)

Definition AccelTable.cpp:43

void print(raw_ostream &OS) const

Definition AccelTable.cpp:788

ArrayRef< HashList > getBuckets() const

Interface which the different types of accelerator table data have to conform.

A base class for different implementations of Data classes for Apple Accelerator Tables.

void emit(AsmPrinter *Asm) const override

Definition AccelTable.cpp:722

void print(raw_ostream &OS) const override

Definition AccelTable.cpp:812

void emit(AsmPrinter *Asm) const override

Definition AccelTable.cpp:736

void print(raw_ostream &OS) const override

Definition AccelTable.cpp:821

uint32_t QualifiedNameHash

void emit(AsmPrinter *Asm) const override

Definition AccelTable.cpp:740

void print(raw_ostream &OS) const override

Definition AccelTable.cpp:825

bool ObjCClassIsImplementation

void print(raw_ostream &OS) const override

Definition AccelTable.cpp:816

void emit(AsmPrinter *Asm) const override

Definition AccelTable.cpp:728

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

This class is intended to be used as a driving class for all asm writers.

static dwarf::Form BestForm(bool IsSigned, uint64_t Int)

Choose the best form for integer.

A structured debug information entry.

LLVM_ABI DIEValue findAttribute(dwarf::Attribute Attribute) const

Find a value in the DIE with the attribute given.

LLVM_ABI DIE * getParent() const

The Data class implementation for DWARF v5 accelerator table.

void print(raw_ostream &OS) const override

Definition AccelTable.cpp:807

unsigned getDieTag() const

std::variant< const DIE *, uint64_t > OffsetVal

LLVM_ABI DWARF5AccelTableData(const DIE &Die, const uint32_t UnitID, const bool IsTU)

Definition AccelTable.cpp:365

static LLVM_ABI std::optional< uint64_t > getDefiningParentDieOffset(const DIE &Die)

If Die has a non-null parent and the parent is not a declaration, return its offset.

Definition AccelTable.cpp:401

uint64_t getDieOffset() const

LLVM_ABI void addTypeUnitSignature(DwarfTypeUnit &U)

Add a type unit Signature.

Definition AccelTable.cpp:706

const TUVectorTy & getTypeUnitsSymbols()

Returns type units that were constructed.

LLVM_ABI void addTypeUnitSymbol(DwarfTypeUnit &U)

Add a type unit start symbol.

Definition AccelTable.cpp:702

void setNumber(uint32_t AbbrevNumber)

Set abbreviation tag index.

const SmallVector< AttributeEncoding, 1 > & getAttributes() const

Returns attributes for an abbreviation.

LLVM_ABI void Profile(FoldingSetNodeID &ID) const

Used to gather unique data for the abbreviation folding set.

Definition AccelTable.cpp:421

uint32_t getNumber() const

Get abbreviation tag index.

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

Implements a dense probed hash-table based set.

Collects and handles dwarf debug information.

bool useSplitDwarf() const

Returns whether or not to change the current debug info for the split dwarf proposal support.

DwarfStringPoolEntryRef: Dwarf string pool entry reference.

MCSymbol * getLabelBegin() const

Get the the symbol for start of the section for this unit.

void InsertNode(T *N, void *InsertPos)

InsertNode - Insert the specified node into the folding set, knowing that it is not already in the fo...

T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)

FindNodeOrInsertPos - Look up the node specified by ID.

FoldingSetNodeID - This class is used to gather all the unique data bits of a node.

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const

print - Print the value to the stream OS.

void reserve(size_type N)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM Value Representation.

LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const

Implement operator<< on Value.

std::pair< iterator, bool > insert(const ValueT &V)

bool contains(const_arg_type_t< ValueT > V) const

Check if the set contains the given element.

An efficient, type-erasing, non-owning reference to a callable.

This class implements an extremely fast bulk output stream that can only output to a stream.

LLVM_ABI StringRef FormEncodingString(unsigned Encoding)

LLVM_ABI StringRef IndexString(unsigned Idx)

LLVM_ABI StringRef AtomTypeString(unsigned Atom)

LLVM_ABI StringRef TagString(unsigned Tag)

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

uint32_t getDebugNamesBucketCount(uint32_t UniqueHashCount)

@ DW_FLAG_type_implementation

This is an optimization pass for GlobalISel generic memory operations.

void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)

FunctionAddr VTableAddr Value

void stable_sort(R &&Range)

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

auto enumerate(FirstRange &&First, RestRanges &&...Rest)

Given two or more input ranges, returns a new range whose values are tuples (A, B,...

SmallVector< TypeUnitMetaInfo, 1 > TUVectorTy

auto unique(Range &&R, Predicate P)

LLVM_ABI void emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents, StringRef Prefix, const MCSymbol *SecBegin, ArrayRef< AppleAccelTableData::Atom > Atoms)

Definition AccelTable.cpp:635

FunctionAddr VTableAddr uintptr_t uintptr_t Version

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

ArrayRef(const T &OneElt) -> ArrayRef< T >

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)

Definition AccelTable.cpp:642

BumpPtrAllocatorImpl<> BumpPtrAllocator

The standard BumpPtrAllocator which just uses the default template parameters.

Represents a group of entries with identical name (and hence, hash value).

void print(raw_ostream &OS) const

Definition AccelTable.cpp:775

DwarfStringPoolEntryRef Name

std::vector< AccelTableData * > Values

This struct is a compact representation of a valid (non-zero power of two) alignment.

An Atom defines the form of the data in an Apple accelerator table.

const uint16_t Form

DWARF Form.

void print(raw_ostream &OS) const

Definition AccelTable.cpp:757

const uint16_t Type

Atom Type.

Helper class to identify an entry in DWARF5AccelTable based on their DIE offset and UnitID.