diff options
author | Eric Christopher <echristo@apple.com> | 2012-01-06 04:35:23 +0000 |
---|---|---|
committer | Eric Christopher <echristo@apple.com> | 2012-01-06 04:35:23 +0000 |
commit | 21bde87bf369a121a5111ea90983188694b6ae34 (patch) | |
tree | d56c979423f95a5678e2641809bf54047108e48f | |
parent | 4817cf72f68324ba1a0683fbe4e7973793c40b95 (diff) | |
download | bcm5719-llvm-21bde87bf369a121a5111ea90983188694b6ae34.tar.gz bcm5719-llvm-21bde87bf369a121a5111ea90983188694b6ae34.zip |
As part of the ongoing work in finalizing the accelerator tables, extend
the debug type accelerator tables to contain the tag and a flag
stating whether or not a compound type is a complete type.
rdar://10652330
llvm-svn: 147651
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp | 44 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h | 55 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 9 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 23 |
5 files changed, 110 insertions, 38 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp index 6c77a631a92..940592ed26b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp @@ -42,16 +42,22 @@ DwarfAccelTable::DwarfAccelTable(DwarfAccelTable::Atom atom) : HeaderData(atom) { } +// The length of the header data is always going to be 4 + 4 + 4*NumAtoms. +DwarfAccelTable::DwarfAccelTable(std::vector<DwarfAccelTable::Atom> &atomList) : + Header(8 + (atomList.size() * 4)), + HeaderData(atomList) { +} + DwarfAccelTable::~DwarfAccelTable() { - for (size_t i = 0, e = Data.size() ; i < e; ++i) + for (size_t i = 0, e = Data.size(); i < e; ++i) delete Data[i]; } -void DwarfAccelTable::AddName(StringRef Name, DIE* die) { +void DwarfAccelTable::AddName(StringRef Name, DIE* die, char Flags) { // If the string is in the list already then add this die to the list // otherwise add a new one. - DIEArray &DIEs = Entries[Name]; - DIEs.push_back(die); + DataArray &DIEs = Entries[Name]; + DIEs.push_back(new HashDataContents(die, Flags)); } void DwarfAccelTable::ComputeBucketCount(void) { @@ -76,15 +82,16 @@ void DwarfAccelTable::ComputeBucketCount(void) { namespace { // DIESorter - comparison predicate that sorts DIEs by their offset. struct DIESorter { - bool operator()(DIE *A, DIE *B) const { - return A->getOffset() < B->getOffset(); + bool operator()(const struct DwarfAccelTable::HashDataContents *A, + const struct DwarfAccelTable::HashDataContents *B) const { + return A->Die->getOffset() < B->Die->getOffset(); } }; } void DwarfAccelTable::FinalizeTable(AsmPrinter *Asm, const char *Prefix) { // Create the individual hash data outputs. - for (StringMap<DIEArray>::iterator + for (StringMap<DataArray>::iterator EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) { struct HashData *Entry = new HashData((*EI).getKeyData()); @@ -93,10 +100,10 @@ void DwarfAccelTable::FinalizeTable(AsmPrinter *Asm, const char *Prefix) { (*EI).second.erase(std::unique((*EI).second.begin(), (*EI).second.end()), (*EI).second.end()); - for (DIEArray::const_iterator DI = (*EI).second.begin(), + for (DataArray::const_iterator DI = (*EI).second.begin(), DE = (*EI).second.end(); DI != DE; ++DI) - Entry->addOffset((*DI)->getOffset()); + Entry->addData((*DI)); Data.push_back(Entry); } @@ -202,11 +209,18 @@ void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfDebug *D) { Asm->EmitSectionOffset(D->getStringPoolEntry((*HI)->Str), D->getStringPool()); Asm->OutStreamer.AddComment("Num DIEs"); - Asm->EmitInt32((*HI)->DIEOffsets.size()); - for (std::vector<uint32_t>::const_iterator - DI = (*HI)->DIEOffsets.begin(), DE = (*HI)->DIEOffsets.end(); + Asm->EmitInt32((*HI)->Data.size()); + for (std::vector<struct HashDataContents*>::const_iterator + DI = (*HI)->Data.begin(), DE = (*HI)->Data.end(); DI != DE; ++DI) { - Asm->EmitInt32((*DI)); + // Emit the DIE offset + Asm->EmitInt32((*DI)->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); + } } // Emit a 0 to terminate the data unless we have a hash collision. if (PrevHash != (*HI)->HashValue) @@ -242,10 +256,10 @@ void DwarfAccelTable::print(raw_ostream &O) { HeaderData.print(O); O << "Entries: \n"; - for (StringMap<DIEArray>::const_iterator + for (StringMap<DataArray>::const_iterator EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) { O << "Name: " << (*EI).getKeyData() << "\n"; - for (DIEArray::const_iterator DI = (*EI).second.begin(), + for (DataArray::const_iterator DI = (*EI).second.begin(), DE = (*EI).second.end(); DI != DE; ++DI) (*DI)->print(O); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h b/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h index 0c1e949c7f2..464ada48474 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h @@ -22,6 +22,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" +#include "DIE.h" #include <vector> #include <map> @@ -134,6 +135,14 @@ public: eAtomTypeTypeFlags = 5u // Flags from enum TypeFlags }; + enum TypeFlags { + eTypeFlagClassMask = 0x0000000fu, + + // Always set for C++, only set for ObjC if this is the + // @implementation for a class. + eTypeFlagClassIsImplementation = ( 1u << 1 ) + }; + // Make these public so that they can be used as a general interface to // the class. struct Atom { @@ -144,7 +153,7 @@ public: static const char * AtomTypeString(enum AtomType); #ifndef NDEBUG void print(raw_ostream &O) { - O << "Type: " << dwarf::TagString(type) << "\n" + O << "Type: " << AtomTypeString(type) << "\n" << "Form: " << dwarf::FormEncodingString(form) << "\n"; } void dump() { @@ -159,6 +168,13 @@ public: uint32_t die_offset_base; std::vector<Atom> Atoms; + TableHeaderData(std::vector<DwarfAccelTable::Atom> &AtomList, + uint32_t offset = 0) : + die_offset_base(offset) { + for (size_t i = 0, e = AtomList.size(); i != e; ++i) + Atoms.push_back(AtomList[i]); + } + TableHeaderData(DwarfAccelTable::Atom Atom, uint32_t offset = 0) : die_offset_base(offset) { Atoms.push_back(Atom); @@ -184,15 +200,32 @@ public: // uint32_t str_offset // uint32_t hash_data_count // HashData[hash_data_count] +public: + struct HashDataContents { + DIE *Die; // Offsets + char Flags; // Specific flags to output + + HashDataContents(DIE *D, char Flags) : + Die(D), + Flags(Flags) { }; + #ifndef NDEBUG + void print(raw_ostream &O) const { + O << " Offset: " << Die->getOffset() << "\n"; + O << " Tag: " << dwarf::TagString(Die->getTag()) << "\n"; + O << " Flags: " << Flags << "\n"; + } + #endif + }; +private: struct HashData { StringRef Str; uint32_t HashValue; MCSymbol *Sym; - std::vector<uint32_t> DIEOffsets; // offsets + std::vector<struct HashDataContents*> Data; // offsets HashData(StringRef S) : Str(S) { HashValue = DwarfAccelTable::HashDJB(S); } - void addOffset(uint32_t off) { DIEOffsets.push_back(off); } + void addData(struct HashDataContents *Datum) { Data.push_back(Datum); } #ifndef NDEBUG void print(raw_ostream &O) { O << "Name: " << Str << "\n"; @@ -201,8 +234,11 @@ public: if (Sym) Sym->print(O); else O << "<none>"; O << "\n"; - for (size_t i = 0; i < DIEOffsets.size(); i++) - O << " Offset: " << DIEOffsets[i] << "\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"; + } } void dump() { print(dbgs()); @@ -226,8 +262,8 @@ public: std::vector<HashData*> Data; // String Data - typedef std::vector<DIE*> DIEArray; - typedef StringMap<DIEArray> StringEntries; + typedef std::vector<struct HashDataContents*> DataArray; + typedef StringMap<DataArray> StringEntries; StringEntries Entries; // Buckets/Hashes/Offsets @@ -238,9 +274,10 @@ public: // Public Implementation public: - DwarfAccelTable(DwarfAccelTable::Atom Atom); + DwarfAccelTable(DwarfAccelTable::Atom); + DwarfAccelTable(std::vector<DwarfAccelTable::Atom> &); ~DwarfAccelTable(); - void AddName(StringRef, DIE*); + void AddName(StringRef, DIE*, char = 0); void FinalizeTable(AsmPrinter *, const char *); void Emit(AsmPrinter *, MCSymbol *, DwarfDebug *); #ifndef NDEBUG diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index f43a5bf8421..e499d2c8bfe 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -13,6 +13,7 @@ #define DEBUG_TYPE "dwarfdebug" +#include "DwarfAccelTable.h" #include "DwarfCompileUnit.h" #include "DwarfDebug.h" #include "llvm/Constants.h" @@ -608,8 +609,20 @@ DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) { } // If this is a named finished type then include it in the list of types // for the accelerator tables. - if (!Ty.getName().empty() && !Ty.isForwardDecl()) - addAccelType(Ty.getName(), TyDIE); + if (!Ty.getName().empty() && !Ty.isForwardDecl()) { + bool IsImplementation = 0; + if (Ty.isCompositeType()) { + DICompositeType CT(Ty); + IsImplementation = (CT.getRunTimeLang() == 0) || + CT.isObjcClassComplete();; + } + + addAccelType(Ty.getName(), + std::make_pair(TyDIE, + (IsImplementation ? + DwarfAccelTable::eTypeFlagClassIsImplementation : + 0))); + } addToContextOwner(TyDIE, Ty.getContext()); return TyDIE; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 07a772338ee..fe65927ff56 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -65,7 +65,7 @@ class CompileUnit { StringMap<std::vector<DIE*> > AccelNames; StringMap<std::vector<DIE*> > AccelObjC; StringMap<std::vector<DIE*> > AccelNamespace; - StringMap<std::vector<DIE*> > AccelTypes; + StringMap<std::vector<std::pair<DIE*, unsigned> > > AccelTypes; /// DIEBlocks - A list of all the DIEBlocks in use. std::vector<DIEBlock *> DIEBlocks; @@ -93,7 +93,8 @@ public: const StringMap<std::vector<DIE*> > &getAccelNamespace() const { return AccelNamespace; } - const StringMap<std::vector<DIE*> > &getAccelTypes() const { + const StringMap<std::vector<std::pair<DIE*, unsigned > > > + &getAccelTypes() const { return AccelTypes; } @@ -119,8 +120,8 @@ public: std::vector<DIE*> &DIEs = AccelNamespace[Name]; DIEs.push_back(Die); } - void addAccelType(StringRef Name, DIE *Die) { - std::vector<DIE*> &DIEs = AccelTypes[Name]; + void addAccelType(StringRef Name, std::pair<DIE *, unsigned> Die) { + std::vector<std::pair<DIE*, unsigned > > &DIEs = AccelTypes[Name]; DIEs.push_back(Die); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 94ce04a92d4..7e58c302730 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1844,19 +1844,26 @@ void DwarfDebug::emitAccelNamespaces() { /// emitAccelTypes() - Emit type dies into a hashed accelerator table. void DwarfDebug::emitAccelTypes() { - DwarfAccelTable AT(DwarfAccelTable::Atom(DwarfAccelTable::eAtomTypeDIEOffset, - dwarf::DW_FORM_data4)); + std::vector<DwarfAccelTable::Atom> Atoms; + Atoms.push_back(DwarfAccelTable::Atom(DwarfAccelTable::eAtomTypeDIEOffset, + dwarf::DW_FORM_data4)); + Atoms.push_back(DwarfAccelTable::Atom(DwarfAccelTable::eAtomTypeTag, + dwarf::DW_FORM_data2)); + Atoms.push_back(DwarfAccelTable::Atom(DwarfAccelTable::eAtomTypeTypeFlags, + dwarf::DW_FORM_data1)); + DwarfAccelTable AT(Atoms); for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) { CompileUnit *TheCU = I->second; - const StringMap<std::vector<DIE*> > &Names = TheCU->getAccelTypes(); - for (StringMap<std::vector<DIE*> >::const_iterator + const StringMap<std::vector<std::pair<DIE*, unsigned > > > &Names + = TheCU->getAccelTypes(); + for (StringMap<std::vector<std::pair<DIE*, unsigned> > >::const_iterator GI = Names.begin(), GE = Names.end(); GI != GE; ++GI) { const char *Name = GI->getKeyData(); - std::vector<DIE *> Entities = GI->second; - for (std::vector<DIE *>::const_iterator DI = Entities.begin(), - DE= Entities.end(); DI !=DE; ++DI) - AT.AddName(Name, (*DI)); + std::vector<std::pair<DIE *, unsigned> > Entities = GI->second; + for (std::vector<std::pair<DIE *, unsigned> >::const_iterator DI + = Entities.begin(), DE = Entities.end(); DI !=DE; ++DI) + AT.AddName(Name, (*DI).first, (*DI).second); } } |