summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DIE.cpp11
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DIE.h10
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp4
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp57
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h13
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp74
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h5
7 files changed, 133 insertions, 41 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
index 69444285f4e..c6b765a5f0a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -114,18 +114,19 @@ DIE::~DIE() {
/// Climb up the parent chain to get the compile unit DIE to which this DIE
/// belongs.
-const DIE *DIE::getCompileUnit() const {
- const DIE *Cu = getCompileUnitOrNull();
+const DIE *DIE::getUnit() const {
+ const DIE *Cu = getUnitOrNull();
assert(Cu && "We should not have orphaned DIEs.");
return Cu;
}
/// Climb up the parent chain to get the compile unit DIE this DIE belongs
/// to. Return NULL if DIE is not added to an owner yet.
-const DIE *DIE::getCompileUnitOrNull() const {
+const DIE *DIE::getUnitOrNull() const {
const DIE *p = this;
while (p) {
- if (p->getTag() == dwarf::DW_TAG_compile_unit)
+ if (p->getTag() == dwarf::DW_TAG_compile_unit ||
+ p->getTag() == dwarf::DW_TAG_type_unit)
return p;
p = p->getParent();
}
@@ -227,6 +228,7 @@ void DIEInteger::EmitValue(AsmPrinter *Asm, dwarf::Form Form) const {
case dwarf::DW_FORM_ref4: // Fall thru
case dwarf::DW_FORM_data4: Size = 4; break;
case dwarf::DW_FORM_ref8: // Fall thru
+ case dwarf::DW_FORM_ref_sig8: // Fall thru
case dwarf::DW_FORM_data8: Size = 8; break;
case dwarf::DW_FORM_GNU_str_index: Asm->EmitULEB128(Integer); return;
case dwarf::DW_FORM_GNU_addr_index: Asm->EmitULEB128(Integer); return;
@@ -253,6 +255,7 @@ unsigned DIEInteger::SizeOf(AsmPrinter *AP, dwarf::Form Form) const {
case dwarf::DW_FORM_ref4: // Fall thru
case dwarf::DW_FORM_data4: return sizeof(int32_t);
case dwarf::DW_FORM_ref8: // Fall thru
+ case dwarf::DW_FORM_ref_sig8: // Fall thru
case dwarf::DW_FORM_data8: return sizeof(int64_t);
case dwarf::DW_FORM_GNU_str_index: return MCAsmInfo::getULEB128Size(Integer);
case dwarf::DW_FORM_GNU_addr_index: return MCAsmInfo::getULEB128Size(Integer);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.h b/llvm/lib/CodeGen/AsmPrinter/DIE.h
index 28a2e8e38a0..0574a98536b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DIE.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DIE.h
@@ -146,12 +146,12 @@ namespace llvm {
const std::vector<DIE *> &getChildren() const { return Children; }
const SmallVectorImpl<DIEValue*> &getValues() const { return Values; }
DIE *getParent() const { return Parent; }
- /// Climb up the parent chain to get the compile unit DIE this DIE belongs
- /// to.
- const DIE *getCompileUnit() const;
- /// Similar to getCompileUnit, returns null when DIE is not added to an
+ /// Climb up the parent chain to get the compile or type unit DIE this DIE
+ /// belongs to.
+ const DIE *getUnit() const;
+ /// Similar to getUnit, returns null when DIE is not added to an
/// owner yet.
- const DIE *getCompileUnitOrNull() const;
+ const DIE *getUnitOrNull() const;
void setOffset(unsigned O) { Offset = O; }
void setSize(unsigned S) { Size = S; }
diff --git a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
index 95eca90ef04..d76af538041 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
@@ -92,10 +92,12 @@ void DIEHash::addParentContext(const DIE &Parent) {
// outermost such construct...
SmallVector<const DIE *, 1> Parents;
const DIE *Cur = &Parent;
- while (Cur->getTag() != dwarf::DW_TAG_compile_unit) {
+ while (Cur->getParent()) {
Parents.push_back(Cur);
Cur = Cur->getParent();
}
+ assert(Cur->getTag() == dwarf::DW_TAG_compile_unit ||
+ Cur->getTag() == dwarf::DW_TAG_type_unit);
// Reverse iterate over our list to go from the outermost construct to the
// innermost.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index fbd7ce82283..2489002f7fd 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -29,18 +29,30 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
+static cl::opt<bool> GenerateTypeUnits("generate-type-units", cl::Hidden,
+ cl::desc("Generate DWARF4 type units."),
+ cl::init(false));
+
/// CompileUnit - Compile unit constructor.
CompileUnit::CompileUnit(unsigned UID, DIE *D, DICompileUnit Node,
AsmPrinter *A, DwarfDebug *DW, DwarfUnits *DWU)
: UniqueID(UID), Node(Node), CUDie(D), Asm(A), DD(DW), DU(DWU),
- IndexTyDie(0), DebugInfoOffset(0) {
+ IndexTyDie(0), Language(Node.getLanguage()) {
DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
insertDIE(Node, D);
}
+CompileUnit::CompileUnit(unsigned UID, DIE *D, uint16_t Language, AsmPrinter *A,
+ DwarfDebug *DD, DwarfUnits *DU)
+ : UniqueID(UID), Node(NULL), CUDie(D), Asm(A), DD(DD), DU(DU),
+ IndexTyDie(0), Language(Language) {
+ DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
+}
+
/// ~CompileUnit - Destructor for compile unit.
CompileUnit::~CompileUnit() {
for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
@@ -102,7 +114,9 @@ int64_t CompileUnit::getDefaultLowerBound() const {
static bool isShareableAcrossCUs(DIDescriptor D) {
// When the MDNode can be part of the type system, the DIE can be
// shared across CUs.
- return D.isType() || (D.isSubprogram() && !DISubprogram(D).isDefinition());
+ return (D.isType() ||
+ (D.isSubprogram() && !DISubprogram(D).isDefinition())) &&
+ !GenerateTypeUnits;
}
/// getDIE - Returns the debug information entry map slot for the
@@ -281,8 +295,8 @@ void CompileUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute,
void CompileUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute,
DIEEntry *Entry) {
- const DIE *DieCU = Die->getCompileUnitOrNull();
- const DIE *EntryCU = Entry->getEntry()->getCompileUnitOrNull();
+ const DIE *DieCU = Die->getUnitOrNull();
+ const DIE *EntryCU = Entry->getEntry()->getUnitOrNull();
if (!DieCU)
// We assume that Die belongs to this CU, if it is not linked to any CU yet.
DieCU = getCUDie();
@@ -871,6 +885,22 @@ DIE *CompileUnit::getOrCreateContextDIE(DIScope Context) {
return getDIE(Context);
}
+DIE *CompileUnit::createTypeDIE(DICompositeType Ty) {
+ DIE *ContextDIE = getOrCreateContextDIE(resolve(Ty.getContext()));
+
+ DIE *TyDIE = getDIE(Ty);
+ if (TyDIE)
+ return TyDIE;
+
+ // Create new type.
+ TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty);
+
+ constructTypeDIEImpl(*TyDIE, Ty);
+
+ updateAcceleratorTables(Ty, TyDIE);
+ return TyDIE;
+}
+
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
/// given DIType.
DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
@@ -1112,6 +1142,9 @@ static bool isTypeUnitScoped(DIType Ty, const DwarfDebug *DD) {
/// Return true if the type should be split out into a type unit.
static bool shouldCreateTypeUnit(DICompositeType CTy, const DwarfDebug *DD) {
+ if (!GenerateTypeUnits)
+ return false;
+
uint16_t Tag = CTy.getTag();
switch (Tag) {
@@ -1130,7 +1163,16 @@ static bool shouldCreateTypeUnit(DICompositeType CTy, const DwarfDebug *DD) {
/// constructTypeDIE - Construct type DIE from DICompositeType.
void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
- // Get core information.
+ // If this is a type applicable to a type unit it then add it to the
+ // list of types we'll compute a hash for later.
+ if (shouldCreateTypeUnit(CTy, DD))
+ DD->addTypeUnitType(&Buffer, CTy);
+ else
+ constructTypeDIEImpl(Buffer, CTy);
+}
+
+void CompileUnit::constructTypeDIEImpl(DIE &Buffer, DICompositeType CTy) {
+ // Add name if not anonymous or intermediate type.
StringRef Name = CTy.getName();
uint64_t Size = CTy.getSizeInBits() >> 3;
@@ -1296,10 +1338,6 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,
RLang);
}
- // If this is a type applicable to a type unit it then add it to the
- // list of types we'll compute a hash for later.
- if (shouldCreateTypeUnit(CTy, DD))
- DD->addTypeUnitType(&Buffer);
}
/// constructTemplateTypeParameterDIE - Construct new DIE for the given
@@ -1510,7 +1548,6 @@ static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
/// createGlobalVariableDIE - create global variable DIE.
void CompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
-
// Check for pre-existence.
if (getDIE(GV))
return;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 02f4206e949..3a0c6be0acf 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -93,14 +93,18 @@ class CompileUnit {
// DIEIntegerOne - A preallocated DIEValue because 1 is used frequently.
DIEInteger *DIEIntegerOne;
+ uint16_t Language;
+
public:
CompileUnit(unsigned UID, DIE *D, DICompileUnit CU, AsmPrinter *A,
DwarfDebug *DW, DwarfUnits *DWU);
+ CompileUnit(unsigned UID, DIE *D, uint16_t Language, AsmPrinter *A,
+ DwarfDebug *DW, DwarfUnits *DWU);
~CompileUnit();
// Accessors.
unsigned getUniqueID() const { return UniqueID; }
- uint16_t getLanguage() const { return Node.getLanguage(); }
+ uint16_t getLanguage() const { return Language; }
DICompileUnit getNode() const { return Node; }
DIE *getCUDie() const { return CUDie.get(); }
const StringMap<DIE *> &getGlobalNames() const { return GlobalNames; }
@@ -311,6 +315,9 @@ public:
DIE *getOrCreateTypeDIE(const MDNode *N);
/// getOrCreateContextDIE - Get context owner's DIE.
+ DIE *createTypeDIE(DICompositeType Ty);
+
+ /// getOrCreateContextDIE - Get context owner's DIE.
DIE *getOrCreateContextDIE(DIScope Context);
/// createGlobalVariableDIE - create global variable DIE.
@@ -328,6 +335,10 @@ public:
DIE *createAndAddDIE(unsigned Tag, DIE &Parent,
DIDescriptor N = DIDescriptor());
+ /// constructTypeDIEImpl - Construct type DIE that is not a type unit
+ /// reference from a DICompositeType.
+ void constructTypeDIEImpl(DIE &Buffer, DICompositeType CTy);
+
/// Compute the size of a header for this unit, not including the initial
/// length field.
unsigned getHeaderSize() const {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 35f76047dba..dca2196214f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1051,22 +1051,6 @@ void DwarfDebug::finalizeModuleInfo() {
// Attach DW_AT_inline attribute with inlined subprogram DIEs.
computeInlinedDIEs();
- // Split out type units and conditionally add an ODR tag to the split
- // out type.
- // FIXME: Do type splitting.
- for (unsigned i = 0, e = TypeUnits.size(); i != e; ++i) {
- DIE *Die = TypeUnits[i];
- DIEHash Hash;
- // If we've requested ODR hashes and it's applicable for an ODR hash then
- // add the ODR signature now.
- // FIXME: This should be added onto the type unit, not the type, but this
- // works as an intermediate stage.
- if (GenerateODRHash && shouldAddODRHash(CUMap.begin()->second, Die))
- CUMap.begin()->second->addUInt(Die, dwarf::DW_AT_GNU_odr_signature,
- dwarf::DW_FORM_data8,
- Hash.computeDIEODRSignature(*Die));
- }
-
// Handle anything that needs to be done on a per-cu basis.
for (DenseMap<const MDNode *, CompileUnit *>::iterator CUI = CUMap.begin(),
CUE = CUMap.end();
@@ -2071,7 +2055,7 @@ void DwarfDebug::emitDIE(DIE *Die, ArrayRef<DIEAbbrev *> Abbrevs) {
// For DW_FORM_ref_addr, output the offset from beginning of debug info
// section. Origin->getOffset() returns the offset from start of the
// compile unit.
- CompileUnit *CU = CUDieMap.lookup(Origin->getCompileUnit());
+ CompileUnit *CU = CUDieMap.lookup(Origin->getUnit());
assert(CU && "CUDie should belong to a CU.");
Addr += CU->getDebugInfoOffset();
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
@@ -2083,7 +2067,7 @@ void DwarfDebug::emitDIE(DIE *Die, ArrayRef<DIEAbbrev *> Abbrevs) {
DIEEntry::getRefAddrSize(Asm));
} else {
// Make sure Origin belong to the same CU.
- assert(Die->getCompileUnit() == Origin->getCompileUnit() &&
+ assert(Die->getUnit() == Origin->getUnit() &&
"The referenced DIE should belong to the same CU in ref4");
Asm->EmitInt32(Addr);
}
@@ -3063,3 +3047,57 @@ void DwarfDebug::emitDebugStrDWO() {
InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),
OffSec, StrSym);
}
+
+void DwarfDebug::addTypeUnitType(DIE *RefDie, DICompositeType CTy) {
+ DenseMap<const MDNode*, std::pair<uint64_t, SmallVectorImpl<DIE*>* > >::iterator I = TypeUnits.find(CTy);
+ SmallVector<DIE *, 8> References;
+ References.push_back(RefDie);
+ if (I != TypeUnits.end()) {
+ if (I->second.second) {
+ I->second.second->push_back(RefDie);
+ return;
+ }
+ } else {
+ DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit);
+ CompileUnit *NewCU =
+ new CompileUnit(GlobalCUIndexCount++, UnitDie,
+ dwarf::DW_LANG_C_plus_plus, Asm, this, &InfoHolder);
+ CUDieMap.insert(std::make_pair(UnitDie, NewCU));
+ NewCU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
+ dwarf::DW_LANG_C_plus_plus);
+
+ // Register the type in the TypeUnits map with a vector of references to be
+ // populated whenever a reference is required.
+ I = TypeUnits.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 = NewCU->createTypeDIE(CTy);
+
+ if (GenerateODRHash && shouldAddODRHash(NewCU, Die))
+ NewCU->addUInt(UnitDie, dwarf::DW_AT_GNU_odr_signature,
+ dwarf::DW_FORM_data8,
+ DIEHash().computeDIEODRSignature(*Die));
+ // FIXME: This won't handle circularly referential structures, as the DIE
+ // may have references to other DIEs still under construction and missing
+ // their signature. Hashing should walk through the signatures to their
+ // referenced type, or possibly walk the precomputed hashes of related types
+ // at the end.
+ uint64_t Signature = DIEHash().computeTypeSignature(*Die);
+
+ // Remove the References vector and add the type hash.
+ I->second.first = Signature;
+ I->second.second = NULL;
+
+
+ InfoHolder.addUnit(NewCU);
+ }
+
+ // 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);
+ }
+}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index cebac39a19b..c3b12997317 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -37,6 +37,7 @@ class MachineFrameInfo;
class MachineModuleInfo;
class MachineOperand;
class MCAsmInfo;
+class MCObjectFileInfo;
class DIEAbbrev;
class DIE;
class DIEBlock;
@@ -443,7 +444,7 @@ class DwarfDebug {
ImportedEntityMap ScopesWithImportedEntities;
// Holder for types that are going to be extracted out into a type unit.
- std::vector<DIE *> TypeUnits;
+ DenseMap<const MDNode *, std::pair<uint64_t, SmallVectorImpl<DIE*>* > > TypeUnits;
// Whether to emit the pubnames/pubtypes sections.
bool HasDwarfPubSections;
@@ -695,7 +696,7 @@ public:
/// \brief Add a DIE to the set of types that we're going to pull into
/// type units.
- void addTypeUnitType(DIE *Die) { TypeUnits.push_back(Die); }
+ void addTypeUnitType(DIE *Die, DICompositeType CTy);
/// \brief Add a label so that arange data can be generated for it.
void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(SCU); }
OpenPOWER on IntegriCloud