30 : Header(8 + (atomList.
size() * 4)), HeaderData(atomList),
35 assert(Data.empty() &&
"Already finalized!");
38 DataArray &DIEs = Entries[Name.
getString()];
39 assert(!DIEs.Name || DIEs.Name == Name);
44 void DwarfAccelTable::ComputeBucketCount(
void) {
46 std::vector<uint32_t> uniques(Data.size());
47 for (
size_t i = 0, e = Data.size(); i < e; ++i)
48 uniques[i] = Data[i]->HashValue;
50 std::vector<uint32_t>::iterator p =
51 std::unique(uniques.begin(), uniques.end());
52 uint32_t num = std::distance(uniques.begin(), p);
56 Header.bucket_count = num / 4;
58 Header.bucket_count = num / 2;
60 Header.bucket_count = num > 0 ? num : 1;
62 Header.hashes_count = num;
73 Data.reserve(Entries.
size());
78 std::stable_sort(EI->second.Values.begin(), EI->second.Values.end(),
compareDIEs);
79 EI->second.Values.erase(
80 std::unique(EI->second.Values.begin(), EI->second.Values.end()),
81 EI->second.Values.end());
84 Data.push_back(Entry);
95 Buckets.resize(Header.bucket_count);
96 for (
size_t i = 0, e = Data.size(); i < e; ++i) {
97 uint32_t bucket = Data[i]->HashValue % Header.bucket_count;
98 Buckets[bucket].push_back(Data[i]);
105 for (
size_t i = 0; i < Buckets.size(); ++i)
106 std::stable_sort(Buckets[i].
begin(), Buckets[i].end(),
108 return LHS->HashValue < RHS->HashValue;
118 Asm->
OutStreamer->AddComment(
"Header Hash Function");
120 Asm->
OutStreamer->AddComment(
"Header Bucket Count");
124 Asm->
OutStreamer->AddComment(
"Header Data Length");
126 Asm->
OutStreamer->AddComment(
"HeaderData Die Offset Base");
127 Asm->
EmitInt32(HeaderData.die_offset_base);
128 Asm->
OutStreamer->AddComment(
"HeaderData Atom Count");
130 for (
size_t i = 0; i < HeaderData.Atoms.size(); i++) {
131 Atom
A = HeaderData.Atoms[i];
141 void DwarfAccelTable::EmitBuckets(
AsmPrinter *Asm) {
143 for (
size_t i = 0, e = Buckets.size(); i < e; ++i) {
145 if (Buckets[i].
size() != 0)
151 uint64_t PrevHash = UINT64_MAX;
152 for (
auto *HD : Buckets[i]) {
153 uint32_t HashValue = HD->HashValue;
154 if (PrevHash != HashValue)
156 PrevHash = HashValue;
163 void DwarfAccelTable::EmitHashes(
AsmPrinter *Asm) {
164 uint64_t PrevHash = UINT64_MAX;
165 for (
size_t i = 0, e = Buckets.size(); i < e; ++i) {
166 for (HashList::const_iterator
HI = Buckets[i].
begin(),
167 HE = Buckets[i].end();
169 uint32_t HashValue = (*HI)->HashValue;
170 if (PrevHash == HashValue)
174 PrevHash = HashValue;
184 uint64_t PrevHash = UINT64_MAX;
185 for (
size_t i = 0, e = Buckets.size(); i < e; ++i) {
186 for (HashList::const_iterator
HI = Buckets[i].
begin(),
187 HE = Buckets[i].end();
189 uint32_t HashValue = (*HI)->HashValue;
190 if (PrevHash == HashValue)
192 PrevHash = HashValue;
198 Asm->
OutStreamer->EmitValue(Sub,
sizeof(uint32_t));
207 for (
size_t i = 0, e = Buckets.size(); i < e; ++i) {
208 uint64_t PrevHash = UINT64_MAX;
209 for (HashList::const_iterator
HI = Buckets[i].
begin(),
210 HE = Buckets[i].end();
214 if (PrevHash != UINT64_MAX && PrevHash != (*HI)->HashValue)
221 Asm->
EmitInt32((*HI)->Data.Values.size());
222 for (HashDataContents *HD : (*HI)->Data.Values) {
225 assert(CU &&
"Accelerated DIE should belong to a CU.");
229 if (HeaderData.Atoms.size() > 1) {
234 PrevHash = (*HI)->HashValue;
237 if (!Buckets[i].empty())
255 emitOffsets(Asm, SecBegin);
271 O <<
"Name: " << EI->getKeyData() <<
"\n";
276 O <<
"Buckets and Hashes: \n";
277 for (
size_t i = 0, e = Buckets.size(); i < e; ++i)
278 for (HashList::const_iterator
HI = Buckets[i].
begin(),
279 HE = Buckets[i].end();
284 for (std::vector<HashData *>::const_iterator
DI = Data.begin(),
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void EmitInt8(int Value) const
Emit a byte directive and value.
void print(raw_ostream &O) const
Collects and handles dwarf debug information.
void emit(AsmPrinter *, const MCSymbol *, DwarfDebug *)
const_iterator begin(StringRef path)
Get begin iterator over path.
void EmitInt32(int Value) const
Emit a long directive and value.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
String pool entry reference.
Base class for the full range of assembler expressions which are needed for parsing.
Context object for machine code objects.
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
void FinalizeTable(AsmPrinter *, StringRef)
void EmitInt16(int Value) const
Emit a short directive and value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
void AddName(DwarfStringPoolEntryRef Name, const DIE *Die, char Flags=0)
const char * AtomTypeString(unsigned Atom)
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
DIE - A structured debug information entry.
This class is intended to be used as a driving class for all asm writers.
static bool compareDIEs(const DwarfAccelTable::HashDataContents *A, const DwarfAccelTable::HashDataContents *B)
unsigned getDebugInfoOffset() const
unsigned getOffset() const
DwarfCompileUnit * lookupUnit(const DIE *CU) const
Find the DwarfCompileUnit for the given CU Die.
StringRef getString() const
void print(raw_ostream &O)
MCSymbol * createTempSymbol(const Twine &Name) const
const char * FormEncodingString(unsigned Encoding)
void emitDwarfStringOffset(DwarfStringPoolEntryRef S) const
Emit the 4-byte offset of a string from the start of its section.
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.