mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-27 13:30:05 +00:00
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:
parent
f07d462beb
commit
2cb3295a53
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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.
|
||||
//
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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; }
|
||||
|
Loading…
Reference in New Issue
Block a user