DwarfAccelTable: Store the string symbol in the accelerator table to avoid duplicate lookup.

This also avoids the need for subtly side-effecting calls to manifest
strings in the string table at the point where items are added to the
accelerator tables.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207281 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie 2014-04-25 22:21:35 +00:00
parent 817f5e2fa1
commit 82a35bf01a
3 changed files with 39 additions and 35 deletions

View File

@ -29,12 +29,15 @@ DwarfAccelTable::DwarfAccelTable(ArrayRef<DwarfAccelTable::Atom> atomList)
: Header(8 + (atomList.size() * 4)), HeaderData(atomList),
Entries(Allocator) {}
void DwarfAccelTable::AddName(StringRef Name, const DIE *die, char Flags) {
void DwarfAccelTable::AddName(StringRef Name, MCSymbol *StrSym, const DIE *die,
char Flags) {
assert(Data.empty() && "Already finalized!");
// If the string is in the list already then add this die to the list
// otherwise add a new one.
DataArray &DIEs = Entries[Name];
DIEs.push_back(new (Allocator) HashDataContents(die, Flags));
assert(!DIEs.StrSym || DIEs.StrSym == StrSym);
DIEs.StrSym = StrSym;
DIEs.Values.push_back(new (Allocator) HashDataContents(die, Flags));
}
void DwarfAccelTable::ComputeBucketCount(void) {
@ -70,9 +73,10 @@ void DwarfAccelTable::FinalizeTable(AsmPrinter *Asm, StringRef Prefix) {
EI != EE; ++EI) {
// Unique the entries.
std::stable_sort(EI->second.begin(), EI->second.end(), compareDIEs);
EI->second.erase(std::unique(EI->second.begin(), EI->second.end()),
EI->second.end());
std::stable_sort(EI->second.Values.begin(), EI->second.Values.end(), compareDIEs);
EI->second.Values.erase(
std::unique(EI->second.Values.begin(), EI->second.Values.end()),
EI->second.Values.end());
HashData *Entry = new (Allocator) HashData(EI->getKey(), EI->second);
Data.push_back(Entry);
@ -179,21 +183,18 @@ void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfFile *D) {
// Remember to emit the label for our offset.
Asm->OutStreamer.EmitLabel((*HI)->Sym);
Asm->OutStreamer.AddComment((*HI)->Str);
Asm->EmitSectionOffset(D->getStringPool().getSymbol(*Asm, (*HI)->Str),
Asm->EmitSectionOffset((*HI)->Data.StrSym,
D->getStringPool().getSectionSymbol());
Asm->OutStreamer.AddComment("Num DIEs");
Asm->EmitInt32((*HI)->Data.size());
for (ArrayRef<HashDataContents *>::const_iterator
DI = (*HI)->Data.begin(),
DE = (*HI)->Data.end();
DI != DE; ++DI) {
Asm->EmitInt32((*HI)->Data.Values.size());
for (HashDataContents *HD : (*HI)->Data.Values) {
// Emit the DIE offset
Asm->EmitInt32((*DI)->Die->getOffset());
Asm->EmitInt32(HD->Die->getOffset());
// If we have multiple Atoms emit that info too.
// FIXME: A bit of a hack, we either emit only one atom or all info.
if (HeaderData.Atoms.size() > 1) {
Asm->EmitInt16((*DI)->Die->getTag());
Asm->EmitInt8((*DI)->Flags);
Asm->EmitInt16(HD->Die->getTag());
Asm->EmitInt8(HD->Flags);
}
}
// Emit a 0 to terminate the data unless we have a hash collision.
@ -233,10 +234,8 @@ void DwarfAccelTable::print(raw_ostream &O) {
EE = Entries.end();
EI != EE; ++EI) {
O << "Name: " << EI->getKeyData() << "\n";
for (DataArray::const_iterator DI = EI->second.begin(),
DE = EI->second.end();
DI != DE; ++DI)
(*DI)->print(O);
for (HashDataContents *HD : EI->second.Values)
HD->print(O);
}
O << "Buckets and Hashes: \n";

View File

@ -179,12 +179,18 @@ public:
};
private:
// String Data
struct DataArray {
MCSymbol *StrSym;
std::vector<HashDataContents *> Values;
};
friend struct HashData;
struct HashData {
StringRef Str;
uint32_t HashValue;
MCSymbol *Sym;
ArrayRef<HashDataContents *> Data; // offsets
HashData(StringRef S, ArrayRef<HashDataContents *> Data)
DwarfAccelTable::DataArray &Data; // offsets
HashData(StringRef S, DwarfAccelTable::DataArray &Data)
: Str(S), Data(Data) {
HashValue = DwarfAccelTable::HashDJB(S);
}
@ -198,10 +204,10 @@ private:
else
O << "<none>";
O << "\n";
for (size_t i = 0; i < Data.size(); i++) {
O << " Offset: " << Data[i]->Die->getOffset() << "\n";
O << " Tag: " << dwarf::TagString(Data[i]->Die->getTag()) << "\n";
O << " Flags: " << Data[i]->Flags << "\n";
for (HashDataContents *C : Data.Values) {
O << " Offset: " << C->Die->getOffset() << "\n";
O << " Tag: " << dwarf::TagString(C->Die->getTag()) << "\n";
O << " Flags: " << C->Flags << "\n";
}
}
void dump() { print(dbgs()); }
@ -226,8 +232,6 @@ private:
TableHeaderData HeaderData;
std::vector<HashData *> Data;
// String Data
typedef std::vector<HashDataContents *> DataArray;
typedef StringMap<DataArray, BumpPtrAllocator &> StringEntries;
StringEntries Entries;
@ -240,7 +244,8 @@ private:
// Public Implementation
public:
DwarfAccelTable(ArrayRef<DwarfAccelTable::Atom>);
void AddName(StringRef, const DIE *, char = 0);
void AddName(StringRef Name, MCSymbol *StrSym, const DIE *Die,
char Flags = 0);
void FinalizeTable(AsmPrinter *, StringRef);
void Emit(AsmPrinter *, MCSymbol *, DwarfFile *);
#ifndef NDEBUG

View File

@ -2545,27 +2545,27 @@ void DwarfDebug::attachLowHighPC(DwarfCompileUnit &Unit, DIE &D,
void DwarfDebug::addAccelName(StringRef Name, const DIE &Die) {
if (!useDwarfAccelTables())
return;
InfoHolder.getStringPool().getSymbol(*Asm, Name);
AccelNames.AddName(Name, &Die);
AccelNames.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name),
&Die);
}
void DwarfDebug::addAccelObjC(StringRef Name, const DIE &Die) {
if (!useDwarfAccelTables())
return;
InfoHolder.getStringPool().getSymbol(*Asm, Name);
AccelObjC.AddName(Name, &Die);
AccelObjC.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name),
&Die);
}
void DwarfDebug::addAccelNamespace(StringRef Name, const DIE &Die) {
if (!useDwarfAccelTables())
return;
InfoHolder.getStringPool().getSymbol(*Asm, Name);
AccelNamespace.AddName(Name, &Die);
AccelNamespace.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name),
&Die);
}
void DwarfDebug::addAccelType(StringRef Name, const DIE &Die, char Flags) {
if (!useDwarfAccelTables())
return;
InfoHolder.getStringPool().getSymbol(*Asm, Name);
AccelTypes.AddName(Name, &Die, Flags);
AccelTypes.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name),
&Die);
}