[CodeGen] Optimize AccelTable

Summary:
The class contained arrays of two structures (DataArray and HashData).
These structures were in 1:1 correspondence, and one of them contained
pointers to the other (and *both* contained a "Name" field). By merging
these two structures into one, we can save a bit of space without
negatively impacting much of anything.

Reviewers: JDevlieghere, aprantl

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D43073

llvm-svn: 324724
This commit is contained in:
Pavel Labath 2018-02-09 10:06:56 +00:00
parent ef1986baaf
commit 5f04d42483
2 changed files with 28 additions and 41 deletions

View File

@ -214,26 +214,19 @@ protected:
/// Apple-style accelerator table base class.
class AppleAccelTableBase {
protected:
struct DataArray {
DwarfStringPoolEntryRef Name;
std::vector<AppleAccelTableData *> Values;
};
friend struct HashData;
struct HashData {
StringRef Str;
DwarfStringPoolEntryRef Name;
uint32_t HashValue;
std::vector<AppleAccelTableData *> Values;
MCSymbol *Sym;
DataArray &Data;
HashData(StringRef S, DataArray &Data) : Str(S), Data(Data) {
HashValue = djbHash(S);
HashData(DwarfStringPoolEntryRef Name) : Name(Name) {
HashValue = djbHash(Name.getString());
}
#ifndef NDEBUG
void print(raw_ostream &OS);
void dump() { print(dbgs()); }
void print(raw_ostream &OS) const;
void dump() const { print(dbgs()); }
#endif
};
@ -243,9 +236,7 @@ protected:
/// Header containing both the header and header data.
AppleAccelTableHeader Header;
std::vector<HashData *> Data;
using StringEntries = StringMap<DataArray, BumpPtrAllocator &>;
using StringEntries = StringMap<HashData, BumpPtrAllocator &>;
StringEntries Entries;
using HashList = std::vector<HashData *>;
@ -323,13 +314,12 @@ template <typename AppleAccelTableDataT>
template <class... Types>
void AppleAccelTable<AppleAccelTableDataT>::addName(
DwarfStringPoolEntryRef Name, Types... Args) {
assert(Data.empty() && "Already finalized!");
assert(Buckets.empty() && "Already finalized!");
// If the string is in the list already then add this die to the list
// otherwise add a new one.
DataArray &DA = Entries[Name.getString()];
assert(!DA.Name || DA.Name == Name);
DA.Name = Name;
DA.Values.push_back(new (Allocator) AppleAccelTableDataT(Args...));
auto Iter = Entries.try_emplace(Name.getString(), Name).first;
assert(Iter->second.Name == Name);
Iter->second.Values.push_back(new (Allocator) AppleAccelTableDataT(Args...));
}
/// Accelerator table data implementation for simple accelerator tables with

View File

@ -138,11 +138,11 @@ void AppleAccelTableBase::emitData(AsmPrinter *Asm) {
Asm->EmitInt32(0);
// Remember to emit the label for our offset.
Asm->OutStreamer->EmitLabel(Hash->Sym);
Asm->OutStreamer->AddComment(Hash->Str);
Asm->emitDwarfStringOffset(Hash->Data.Name);
Asm->OutStreamer->AddComment(Hash->Name.getString());
Asm->emitDwarfStringOffset(Hash->Name);
Asm->OutStreamer->AddComment("Num DIEs");
Asm->EmitInt32(Hash->Data.Values.size());
for (const auto *V : Hash->Data.Values) {
Asm->EmitInt32(Hash->Values.size());
for (const auto *V : Hash->Values) {
V->emit(Asm);
}
PrevHash = Hash->HashValue;
@ -155,9 +155,10 @@ void AppleAccelTableBase::emitData(AsmPrinter *Asm) {
void AppleAccelTableBase::computeBucketCount() {
// First get the number of unique hashes.
std::vector<uint32_t> uniques(Data.size());
for (size_t i = 0, e = Data.size(); i < e; ++i)
uniques[i] = Data[i]->HashValue;
std::vector<uint32_t> uniques;
uniques.reserve(Entries.size());
for (const auto &E : Entries)
uniques.push_back(E.second.HashValue);
array_pod_sort(uniques.begin(), uniques.end());
std::vector<uint32_t>::iterator p =
std::unique(uniques.begin(), uniques.end());
@ -169,7 +170,6 @@ void AppleAccelTableBase::computeBucketCount() {
void AppleAccelTableBase::finalizeTable(AsmPrinter *Asm, StringRef Prefix) {
// Create the individual hash data outputs.
Data.reserve(Entries.size());
for (auto &E : Entries) {
// Unique the entries.
std::stable_sort(E.second.Values.begin(), E.second.Values.end(),
@ -178,9 +178,6 @@ void AppleAccelTableBase::finalizeTable(AsmPrinter *Asm, StringRef Prefix) {
E.second.Values.erase(
std::unique(E.second.Values.begin(), E.second.Values.end()),
E.second.Values.end());
HashData *Entry = new (Allocator) HashData(E.first(), E.second);
Data.push_back(Entry);
}
// Figure out how many buckets we need, then compute the bucket contents and
@ -192,10 +189,10 @@ void AppleAccelTableBase::finalizeTable(AsmPrinter *Asm, StringRef Prefix) {
// Compute bucket contents and final ordering.
Buckets.resize(Header.getBucketCount());
for (auto &D : Data) {
uint32_t bucket = D->HashValue % Header.getBucketCount();
Buckets[bucket].push_back(D);
D->Sym = Asm->createTempSymbol(Prefix);
for (auto &E : Entries) {
uint32_t bucket = E.second.HashValue % Header.getBucketCount();
Buckets[bucket].push_back(&E.second);
E.second.Sym = Asm->createTempSymbol(Prefix);
}
// Sort the contents of the buckets by hash value so that hash collisions end
@ -286,8 +283,8 @@ void AppleAccelTableHeader::print(raw_ostream &OS) const {
HeaderData.print(OS);
}
void AppleAccelTableBase::HashData::print(raw_ostream &OS) {
OS << "Name: " << Str << "\n";
void AppleAccelTableBase::HashData::print(raw_ostream &OS) const {
OS << "Name: " << Name.getString() << "\n";
OS << " Hash Value: " << format("0x%x", HashValue) << "\n";
OS << " Symbol: ";
if (Sym)
@ -295,7 +292,7 @@ void AppleAccelTableBase::HashData::print(raw_ostream &OS) {
else
OS << "<none>";
OS << "\n";
for (auto *Value : Data.Values)
for (auto *Value : Values)
Value->print(OS);
}
@ -317,8 +314,8 @@ void AppleAccelTableBase::print(raw_ostream &OS) const {
Hash->print(OS);
OS << "Data: \n";
for (auto &D : Data)
D->print(OS);
for (auto &E : Entries)
E.second.print(OS);
}
void AppleAccelTableOffsetData::print(raw_ostream &OS) const {