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) {
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.