DebugInfo: Introduce new DIValue, DIETypeSignature to encode references to type units via their signatures

This simplifies type unit and type unit reference creation as well as
setting the stage for inter-type hashing across type unit boundaries.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197539 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie 2013-12-17 23:32:35 +00:00
parent f07d462beb
commit 2cb3295a53
6 changed files with 61 additions and 36 deletions

View File

@ -13,6 +13,7 @@
#include "DIE.h"
#include "DwarfDebug.h"
#include "DwarfUnit.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/IR/DataLayout.h"
@ -403,6 +404,22 @@ void DIEEntry::print(raw_ostream &O) const {
}
#endif
//===----------------------------------------------------------------------===//
// DIETypeSignature Implementation
//===----------------------------------------------------------------------===//
void DIETypeSignature::EmitValue(AsmPrinter *Asm, dwarf::Form Form) const {
assert(Form == dwarf::DW_FORM_ref_sig8);
Asm->OutStreamer.EmitIntValue(Unit.getTypeSignature(), 8);
}
#ifndef NDEBUG
void DIETypeSignature::print(raw_ostream &O) const {
O << format("Type Unit: 0x%lx", Unit.getTypeSignature());
}
void DIETypeSignature::dump() const { print(dbgs()); }
#endif
//===----------------------------------------------------------------------===//
// DIEBlock Implementation
//===----------------------------------------------------------------------===//

View File

@ -26,6 +26,7 @@ namespace llvm {
class MCSymbol;
class MCSymbolRefExpr;
class raw_ostream;
class DwarfTypeUnit;
//===--------------------------------------------------------------------===//
/// DIEAbbrevData - Dwarf abbreviation data, describes one attribute of a
@ -195,6 +196,7 @@ namespace llvm {
isLabel,
isDelta,
isEntry,
isTypeSignature,
isBlock
};
protected:
@ -411,6 +413,33 @@ namespace llvm {
#endif
};
//===--------------------------------------------------------------------===//
/// \brief A signature reference to a type unit.
class DIETypeSignature : public DIEValue {
const DwarfTypeUnit &Unit;
public:
explicit DIETypeSignature(const DwarfTypeUnit &Unit)
: DIEValue(isTypeSignature), Unit(Unit) {}
/// \brief Emit type unit signature.
virtual void EmitValue(AsmPrinter *Asm, dwarf::Form Form) const;
/// Returns size of a ref_sig8 entry.
virtual unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const {
assert(Form == dwarf::DW_FORM_ref_sig8);
return 8;
}
// \brief Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) {
return E->getType() == isTypeSignature;
}
#ifndef NDEBUG
virtual void print(raw_ostream &O) const;
void dump() const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEBlock - A block of values. Primarily used for location expressions.
//

View File

@ -3015,35 +3015,18 @@ void DwarfDebug::emitDebugStrDWO() {
void DwarfDebug::addDwarfTypeUnitType(uint16_t Language, DIE *RefDie,
DICompositeType CTy) {
DenseMap<const MDNode *,
std::pair<uint64_t, SmallVectorImpl<DIE *> *> >::iterator I =
DwarfTypeUnits.find(CTy);
SmallVector<DIE *, 8> References;
References.push_back(RefDie);
if (I != DwarfTypeUnits.end()) {
if (I->second.second) {
I->second.second->push_back(RefDie);
return;
}
} else {
const DwarfTypeUnit *&TU = DwarfTypeUnits[CTy];
if (!TU) {
DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit);
DwarfTypeUnit *NewTU =
new DwarfTypeUnit(InfoHolder.getUnits().size(), UnitDie, Language, Asm,
this, &InfoHolder);
TU = NewTU;
InfoHolder.addUnit(NewTU);
NewTU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
Language);
// Register the type in the DwarfTypeUnits map with a vector of references
// to be
// populated whenever a reference is required.
I = DwarfTypeUnits.insert(std::make_pair(
CTy, std::make_pair(0, &References))).first;
// Construct the type, this may, recursively, require more type units that
// may in turn require this type again - in which case they will add DIEs to
// the References vector.
DIE *Die = NewTU->createTypeDIE(CTy);
if (GenerateODRHash && shouldAddODRHash(NewTU, Die))
@ -3059,19 +3042,11 @@ void DwarfDebug::addDwarfTypeUnitType(uint16_t Language, DIE *RefDie,
NewTU->setTypeSignature(Signature);
NewTU->setType(Die);
// Remove the References vector and add the type hash.
I->second.first = Signature;
I->second.second = NULL;
NewTU->initSection(
useSplitDwarf()
? Asm->getObjFileLowering().getDwarfTypesDWOSection(Signature)
: Asm->getObjFileLowering().getDwarfTypesSection(Signature));
}
// Populate all the signatures.
for (unsigned i = 0, e = References.size(); i != e; ++i) {
CUMap.begin()->second->addUInt(References[i], dwarf::DW_AT_signature,
dwarf::DW_FORM_ref_sig8, I->second.first);
}
CUMap.begin()->second->addDIETypeSignature(RefDie, *TU);
}

View File

@ -450,13 +450,9 @@ class DwarfDebug : public AsmPrinterHandler {
ImportedEntityMap;
ImportedEntityMap ScopesWithImportedEntities;
// Map from type MDNodes to a pair used as a union. If the pointer is
// non-null, proxy DIEs in CUs meant to reference this type should be stored
// in the vector. The hash will be added to these DIEs once it is computed. If
// the pointer is null, the hash is immediately available in the uint64_t and
// should be directly used for proxy DIEs.
DenseMap<const MDNode *, std::pair<uint64_t, SmallVectorImpl<DIE *> *> >
DwarfTypeUnits;
// Map from MDNodes for user-defined types to the type units that describe
// them.
DenseMap<const MDNode *, const DwarfTypeUnit *> DwarfTypeUnits;
// Whether to emit the pubnames/pubtypes sections.
bool HasDwarfPubSections;

View File

@ -322,6 +322,11 @@ void DwarfUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIE *Entry) {
addDIEEntry(Die, Attribute, createDIEEntry(Entry));
}
void DwarfUnit::addDIETypeSignature(DIE *Die, const DwarfTypeUnit &Type) {
Die->addValue(dwarf::DW_AT_signature, dwarf::DW_FORM_ref_sig8,
new (DIEValueAllocator) DIETypeSignature(Type));
}
void DwarfUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute,
DIEEntry *Entry) {
const DIE *DieCU = Die->getUnitOrNull();

View File

@ -319,6 +319,8 @@ public:
/// addDIEEntry - Add a DIE attribute data and value.
void addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIEEntry *Entry);
void addDIETypeSignature(DIE *Die, const DwarfTypeUnit &Type);
/// addBlock - Add block data.
void addBlock(DIE *Die, dwarf::Attribute Attribute, DIEBlock *Block);
@ -524,6 +526,7 @@ public:
virtual ~DwarfTypeUnit() LLVM_OVERRIDE;
void setTypeSignature(uint64_t Signature) { TypeSignature = Signature; }
uint64_t getTypeSignature() const { return TypeSignature; }
void setType(const DIE *Ty) { this->Ty = Ty; }
uint16_t getLanguage() const LLVM_OVERRIDE { return Language; }