X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfCompileUnit.cpp;h=73d0a839a7bc936c7c0271aebfc77443edb2870c;hb=b88831b204bcc1645097dafee64efa2b6a91df2d;hp=175febddf258322350abab3ae464a55b7e6d5cc0;hpb=aedaa723c26c33d4f9497a79d9d74a3c197fa262;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 175febddf25..73d0a839a7b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -29,16 +29,28 @@ #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 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, const MDNode *N, AsmPrinter *A, - DwarfDebug *DW, DwarfUnits *DWU) - : UniqueID(UID), Node(N), CUDie(D), Asm(A), DD(DW), DU(DWU), IndexTyDie(0), - DebugInfoOffset(0) { +CompileUnit::CompileUnit(unsigned UID, DIE *D, DICompileUnit Node, + AsmPrinter *A, DwarfDebug *DW, DwarfUnits *DWU) + : UniqueID(UID), Node(Node), Language(Node.getLanguage()), CUDie(D), + DebugInfoOffset(0), Asm(A), DD(DW), DU(DWU), IndexTyDie(0) { + 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), Language(Language), CUDie(D), + DebugInfoOffset(0), Asm(A), DD(DD), DU(DU), IndexTyDie(0) { DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1); - insertDIE(DIDescriptor(N), D); } /// ~CompileUnit - Destructor for compile unit. @@ -100,10 +112,16 @@ int64_t CompileUnit::getDefaultLowerBound() const { /// Check whether the DIE for this MDNode can be shared across CUs. 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()); + // When the MDNode can be part of the type system, the DIE can be shared + // across CUs. + // Combining type units and cross-CU DIE sharing is lower value (since + // cross-CU DIE sharing is used in LTO and removes type redundancy at that + // level already) but may be implementable for some value in projects + // building multiple independent libraries with LTO and then linking those + // together. + return (D.isType() || + (D.isSubprogram() && !DISubprogram(D).isDefinition())) && + !GenerateTypeUnits; } /// getDIE - Returns the debug information entry map slot for the @@ -227,6 +245,26 @@ void CompileUnit::addLabel(DIEBlock *Die, dwarf::Form Form, addLabel(Die, (dwarf::Attribute)0, Form, Label); } +/// addSectionLabel - Add a Dwarf section label attribute data and value. +/// +void CompileUnit::addSectionLabel(DIE *Die, dwarf::Attribute Attribute, + const MCSymbol *Label) { + if (DD->getDwarfVersion() >= 4) + addLabel(Die, Attribute, dwarf::DW_FORM_sec_offset, Label); + else + addLabel(Die, Attribute, dwarf::DW_FORM_data4, Label); +} + +/// addSectionOffset - Add an offset into a section attribute data and value. +/// +void CompileUnit::addSectionOffset(DIE *Die, dwarf::Attribute Attribute, + uint64_t Integer) { + if (DD->getDwarfVersion() >= 4) + addUInt(Die, Attribute, dwarf::DW_FORM_sec_offset, Integer); + else + addUInt(Die, Attribute, dwarf::DW_FORM_data4, Integer); +} + /// addLabelAddress - Add a dwarf label attribute data and value using /// DW_FORM_addr or DW_FORM_GNU_addr_index. /// @@ -264,13 +302,15 @@ void CompileUnit::addOpAddress(DIEBlock *Die, const MCSymbol *Sym) { } } -/// addDelta - Add a label delta attribute data and value. +/// addSectionDelta - Add a section label delta attribute data and value. /// -void CompileUnit::addDelta(DIE *Die, dwarf::Attribute Attribute, - dwarf::Form Form, const MCSymbol *Hi, - const MCSymbol *Lo) { +void CompileUnit::addSectionDelta(DIE *Die, dwarf::Attribute Attribute, + const MCSymbol *Hi, const MCSymbol *Lo) { DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo); - Die->addValue(Attribute, Form, Value); + if (DD->getDwarfVersion() >= 4) + Die->addValue(Attribute, dwarf::DW_FORM_sec_offset, Value); + else + Die->addValue(Attribute, dwarf::DW_FORM_data4, Value); } /// addDIEEntry - Add a DIE attribute data and value. @@ -282,8 +322,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(); @@ -296,11 +336,11 @@ void CompileUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute, /// Create a DIE with the given Tag, add the DIE to its parent, and /// call insertDIE if MD is not null. -DIE *CompileUnit::createAndAddDIE(unsigned Tag, DIE &Parent, const MDNode *MD) { +DIE *CompileUnit::createAndAddDIE(unsigned Tag, DIE &Parent, DIDescriptor N) { DIE *Die = new DIE(Tag); Parent.addChild(Die); - if (MD) - insertDIE(DIDescriptor(MD), Die); + if (N) + insertDIE(N, Die); return Die; } @@ -592,33 +632,31 @@ void CompileUnit::addBlockByrefAddress(const DbgVariable &DV, DIE *Die, StringRef varName = DV.getName(); if (Tag == dwarf::DW_TAG_pointer_type) { - DIDerivedType DTy = DIDerivedType(Ty); + DIDerivedType DTy(Ty); TmpTy = resolve(DTy.getTypeDerivedFrom()); isPointer = true; } - DICompositeType blockStruct = DICompositeType(TmpTy); + DICompositeType blockStruct(TmpTy); // Find the __forwarding field and the variable field in the __Block_byref // struct. DIArray Fields = blockStruct.getTypeArray(); - DIDescriptor varField = DIDescriptor(); - DIDescriptor forwardingField = DIDescriptor(); + DIDerivedType varField; + DIDerivedType forwardingField; for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) { - DIDescriptor Element = Fields.getElement(i); - DIDerivedType DT = DIDerivedType(Element); + DIDerivedType DT(Fields.getElement(i)); StringRef fieldName = DT.getName(); if (fieldName == "__forwarding") - forwardingField = Element; + forwardingField = DT; else if (fieldName == varName) - varField = Element; + varField = DT; } // Get the offsets for the forwarding field and the variable field. - unsigned forwardingFieldOffset = - DIDerivedType(forwardingField).getOffsetInBits() >> 3; - unsigned varFieldOffset = DIDerivedType(varField).getOffsetInBits() >> 3; + unsigned forwardingFieldOffset = forwardingField.getOffsetInBits() >> 3; + unsigned varFieldOffset = varField.getOffsetInBits() >> 2; // Decode the original location, and use that as the start of the byref // variable's location. @@ -874,6 +912,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) { @@ -903,8 +957,13 @@ DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) { assert(Ty.isDerivedType() && "Unknown kind of DIType"); constructTypeDIE(*TyDIE, DIDerivedType(Ty)); } - // If this is a named finished type then include it in the list of types - // for the accelerator tables. + + updateAcceleratorTables(Ty, TyDIE); + + return TyDIE; +} + +void CompileUnit::updateAcceleratorTables(DIType Ty, const DIE *TyDIE) { if (!Ty.getName().empty() && !Ty.isForwardDecl()) { bool IsImplementation = 0; if (Ty.isCompositeType()) { @@ -916,8 +975,6 @@ DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) { unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0; addAccelType(Ty.getName(), std::make_pair(TyDIE, Flags)); } - - return TyDIE; } /// addType - Add a new type attribute to the specified entity. @@ -949,27 +1006,28 @@ void CompileUnit::addType(DIE *Entity, DIType Ty, dwarf::Attribute Attribute) { // DIE to the proper table while ensuring that the name that we're going // to reference is in the string table. We do this since the names we // add may not only be identical to the names in the DIE. -void CompileUnit::addAccelName(StringRef Name, DIE *Die) { +void CompileUnit::addAccelName(StringRef Name, const DIE *Die) { DU->getStringPoolEntry(Name); - std::vector &DIEs = AccelNames[Name]; + std::vector &DIEs = AccelNames[Name]; DIEs.push_back(Die); } -void CompileUnit::addAccelObjC(StringRef Name, DIE *Die) { +void CompileUnit::addAccelObjC(StringRef Name, const DIE *Die) { DU->getStringPoolEntry(Name); - std::vector &DIEs = AccelObjC[Name]; + std::vector &DIEs = AccelObjC[Name]; DIEs.push_back(Die); } -void CompileUnit::addAccelNamespace(StringRef Name, DIE *Die) { +void CompileUnit::addAccelNamespace(StringRef Name, const DIE *Die) { DU->getStringPoolEntry(Name); - std::vector &DIEs = AccelNamespace[Name]; + std::vector &DIEs = AccelNamespace[Name]; DIEs.push_back(Die); } -void CompileUnit::addAccelType(StringRef Name, std::pair Die) { +void CompileUnit::addAccelType(StringRef Name, + std::pair Die) { DU->getStringPoolEntry(Name); - std::vector > &DIEs = AccelTypes[Name]; + std::vector > &DIEs = AccelTypes[Name]; DIEs.push_back(Die); } @@ -1111,6 +1169,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) { @@ -1129,7 +1190,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; @@ -1145,9 +1215,9 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { case dwarf::DW_TAG_subroutine_type: { // Add return type. A void return won't have a type. DIArray Elements = CTy.getTypeArray(); - DIDescriptor RTy = Elements.getElement(0); + DIType RTy(Elements.getElement(0)); if (RTy) - addType(&Buffer, DIType(RTy)); + addType(&Buffer, RTy); bool isPrototyped = true; // Add arguments. @@ -1181,7 +1251,7 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { DIE *ElemDie = NULL; if (Element.isSubprogram()) { DISubprogram SP(Element); - ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element)); + ElemDie = getOrCreateSubprogramDIE(SP); if (SP.isProtected()) addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, dwarf::DW_ACCESS_protected); @@ -1247,9 +1317,9 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { addFlag(&Buffer, dwarf::DW_AT_APPLE_block); DICompositeType ContainingType(resolve(CTy.getContainingType())); - if (DIDescriptor(ContainingType).isCompositeType()) + if (ContainingType) addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, - getOrCreateTypeDIE(DIType(ContainingType))); + getOrCreateTypeDIE(ContainingType)); if (CTy.isObjcClassComplete()) addFlag(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type); @@ -1295,10 +1365,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 @@ -1457,7 +1523,7 @@ DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) { // be handled while processing variables. for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { DIE *Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie); - DIType ATy = DIType(Args.getElement(i)); + DIType ATy(Args.getElement(i)); addType(Arg, ATy); if (ATy.isArtificial()) addFlag(Arg, dwarf::DW_AT_artificial); @@ -1508,9 +1574,7 @@ static const ConstantExpr *getMergedGlobalExpr(const Value *V) { } /// createGlobalVariableDIE - create global variable DIE. -void CompileUnit::createGlobalVariableDIE(const MDNode *N) { - DIGlobalVariable GV(N); - +void CompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) { // Check for pre-existence. if (getDIE(GV)) return; @@ -1541,7 +1605,7 @@ void CompileUnit::createGlobalVariableDIE(const MDNode *N) { DIE *ContextDIE = getOrCreateContextDIE(GVContext); // Add to map. - VariableDIE = createAndAddDIE(GV.getTag(), *ContextDIE, N); + VariableDIE = createAndAddDIE(GV.getTag(), *ContextDIE, GV); // Add name and type. addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName()); @@ -1591,7 +1655,7 @@ void CompileUnit::createGlobalVariableDIE(const MDNode *N) { if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() && !GVContext.isFile() && !DD->isSubprogramContext(GVContext)) { // Create specification DIE. - VariableSpecDIE = createAndAddDIE(dwarf::DW_TAG_variable, *CUDie.get()); + VariableSpecDIE = createAndAddDIE(dwarf::DW_TAG_variable, *CUDie); addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification, VariableDIE); addBlock(VariableSpecDIE, dwarf::DW_AT_location, Block); // A static member's declaration is already flagged as such. @@ -1617,7 +1681,7 @@ void CompileUnit::createGlobalVariableDIE(const MDNode *N) { // it is not a static member. if (!IsStaticMember) addConstantValue(VariableDIE, CI, isUnsignedDIType(DD, GTy)); - } else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) { + } else if (const ConstantExpr *CE = getMergedGlobalExpr(GV->getOperand(11))) { addToAccelTable = true; // GV is a merged global. DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); @@ -1709,14 +1773,14 @@ void CompileUnit::constructEnumTypeDIE(DIE &Buffer, DICompositeType CTy) { // Add enumerators to enumeration type. for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { - DIDescriptor Enum(Elements.getElement(i)); - DIEnumerator ETy = DIEnumerator(Enum); + DIEnumerator Enum(Elements.getElement(i)); if (Enum.isEnumerator()) { DIE *Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer); - StringRef Name = ETy.getName(); + StringRef Name = Enum.getName(); addString(Enumerator, dwarf::DW_AT_name, Name); - int64_t Value = ETy.getEnumValue(); - addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value); + int64_t Value = Enum.getEnumValue(); + addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, + Value); } } DIType DTy = resolve(CTy.getTypeDerivedFrom()); @@ -1772,8 +1836,8 @@ DIE *CompileUnit::constructVariableDIE(DbgVariable &DV, bool isScopeAbstract) { unsigned Offset = DV.getDotDebugLocOffset(); if (Offset != ~0U) { - addLabel(VariableDie, dwarf::DW_AT_location, dwarf::DW_FORM_data4, - Asm->GetTempSymbol("debug_loc", Offset)); + addSectionLabel(VariableDie, dwarf::DW_AT_location, + Asm->GetTempSymbol("debug_loc", Offset)); DV.setDIE(VariableDie); return VariableDie; }