From 94c7ddb6f52a5200983fed0ce74dc602a7737879 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Tue, 16 Aug 2011 22:09:43 +0000 Subject: [PATCH] Until now all debug info MDNodes referred to a root MDNode, a compile unit. This simplified handling of these needs in dwarf writer. However, one side effect of this is that during link time optimization all these MDNodes are _not_ uniqued. In other words there will be N number of MDNodes describing "int", "char" and all other types, which would suddenly grow when each object file starts using libraries like STL. MDNodes graph structure such that compiler unit keeps track of important MDNodes and update dwarf writer to process mdnodes top-down instead of bottom up. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137778 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/SourceLevelDebugging.html | 15 +- include/llvm/Analysis/DIBuilder.h | 10 ++ include/llvm/Analysis/DebugInfo.h | 15 +- lib/Analysis/DIBuilder.cpp | 122 ++++++++------ lib/Analysis/DebugInfo.cpp | 71 +++++--- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 10 +- lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 2 +- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 173 ++++++++++---------- lib/CodeGen/AsmPrinter/DwarfDebug.h | 10 +- 9 files changed, 249 insertions(+), 179 deletions(-) diff --git a/docs/SourceLevelDebugging.html b/docs/SourceLevelDebugging.html index 9f84b4c3bbc..1bf63959817 100644 --- a/docs/SourceLevelDebugging.html +++ b/docs/SourceLevelDebugging.html @@ -355,7 +355,7 @@ height="369"> ;; (DW_TAG_file_type) metadata, ;; Source file name metadata, ;; Source file directory (includes trailing slash) - metadata ;; Reference to compile unit where defined + metadata ;; Unused } @@ -365,8 +365,7 @@ height="369"> provide context for source line correspondence.

Each input file is encoded as a separate file descriptor in LLVM debugging - information output. Each file descriptor would be defined using a - compile unit.

+ information output.

@@ -485,7 +484,7 @@ global variables are collected by named metadata !llvm.dbg.gv.

!4 = metadata !{ i32, ;; Tag = 36 + LLVMDebugVersion ;; (DW_TAG_base_type) - metadata, ;; Reference to context (typically a compile unit) + metadata, ;; Reference to context metadata, ;; Name (may be "" for anonymous types) metadata, ;; Reference to file where defined (may be NULL) i32, ;; Line number where defined (may be 0) @@ -500,7 +499,7 @@ global variables are collected by named metadata !llvm.dbg.gv.

These descriptors define primitive types used in the code. Example int, bool and float. The context provides the scope of the type, which is usually the - top level. Since basic types are not usually user defined the compile unit + top level. Since basic types are not usually user defined the context and line number can be left as NULL and 0. The size, alignment and offset are expressed in bits and can be 64 bit values. The alignment is used to round the offset when embedded in a @@ -585,7 +584,7 @@ DW_TAG_restrict_type = 55 the derived type.

Derived type location can be determined - from the compile unit and line number. The size, alignment and offset are + from the context and line number. The size, alignment and offset are expressed in bits and can be 64 bit values. The alignment is used to round the offset when embedded in a composite type (example to keep float doubles on 64 bit boundaries.) The offset is @@ -675,7 +674,7 @@ DW_TAG_inheritance = 28 the formal arguments to the subroutine.

Composite type location can be - determined from the compile unit and line number. The size, alignment and + determined from the context and line number. The size, alignment and offset are expressed in bits and can be 64 bit values. The alignment is used to round the offset when embedded in a composite type (as an example, to keep @@ -774,7 +773,7 @@ DW_TAG_return_variable = 258 has no source correspondent.

The context is either the subprogram or block where the variable is defined. - Name the source variable name. Compile unit and line indicate where the + Name the source variable name. Context and line indicate where the variable was defined. Type descriptor defines the declared type of the variable.

diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/Analysis/DIBuilder.h index 0f6fd503384..8a6a58e3ed4 100644 --- a/include/llvm/Analysis/DIBuilder.h +++ b/include/llvm/Analysis/DIBuilder.h @@ -48,9 +48,19 @@ namespace llvm { LLVMContext & VMContext; MDNode *TheCU; + MDNode *TempEnumTypes; + MDNode *TempRetainTypes; + MDNode *TempSubprograms; + MDNode *TempGVs; + Function *DeclareFn; // llvm.dbg.declare Function *ValueFn; // llvm.dbg.value + SmallVector AllEnumTypes; + SmallVector AllRetainTypes; + SmallVector AllSubprograms; + SmallVector AllGVs; + DIBuilder(const DIBuilder &); // DO NOT IMPLEMENT void operator=(const DIBuilder &); // DO NOT IMPLEMENT diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index d5f134e3319..e17b41e2534 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -182,6 +182,11 @@ namespace llvm { StringRef getFlags() const { return getStringField(8); } unsigned getRunTimeVersion() const { return getUnsignedField(9); } + DIArray getEnumTypes() const; + DIArray getRetainedTypes() const; + DIArray getSubprograms() const; + DIArray getGlobalVariables() const; + /// Verify - Verify that a compile unit is well formed. bool Verify() const; @@ -201,7 +206,10 @@ namespace llvm { } StringRef getFilename() const { return getStringField(1); } StringRef getDirectory() const { return getStringField(2); } - DICompileUnit getCompileUnit() const{ return getFieldAs(3); } + DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!"); + return getFieldAs(3); + } }; /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). @@ -237,6 +245,7 @@ namespace llvm { DIScope getContext() const { return getFieldAs(1); } StringRef getName() const { return getStringField(2); } DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); if (getVersion() == llvm::LLVMDebugVersion7) return getFieldAs(3); @@ -450,6 +459,7 @@ namespace llvm { StringRef getDisplayName() const { return getStringField(4); } StringRef getLinkageName() const { return getStringField(5); } DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); if (getVersion() == llvm::LLVMDebugVersion7) return getFieldAs(6); @@ -560,6 +570,7 @@ namespace llvm { StringRef getDisplayName() const { return getStringField(4); } StringRef getLinkageName() const { return getStringField(5); } DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); if (getVersion() == llvm::LLVMDebugVersion7) return getFieldAs(6); @@ -595,6 +606,7 @@ namespace llvm { DIScope getContext() const { return getFieldAs(1); } StringRef getName() const { return getStringField(2); } DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); if (getVersion() == llvm::LLVMDebugVersion7) return getFieldAs(3); @@ -687,6 +699,7 @@ namespace llvm { return getFieldAs(3).getFilename(); } DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); if (getVersion() == llvm::LLVMDebugVersion7) return getFieldAs(3); diff --git a/lib/Analysis/DIBuilder.cpp b/lib/Analysis/DIBuilder.cpp index 98a0ba085e1..55f6fcab56a 100644 --- a/lib/Analysis/DIBuilder.cpp +++ b/lib/Analysis/DIBuilder.cpp @@ -29,10 +29,30 @@ static Constant *GetTagConstant(LLVMContext &VMContext, unsigned Tag) { } DIBuilder::DIBuilder(Module &m) - : M(m), VMContext(M.getContext()), TheCU(0), DeclareFn(0), ValueFn(0) {} + : M(m), VMContext(M.getContext()), TheCU(0), TempEnumTypes(0), + TempRetainTypes(0), TempSubprograms(0), TempGVs(0), DeclareFn(0), ValueFn(0) +{} /// finalize - Construct any deferred debug info descriptors. void DIBuilder::finalize() { + DIArray Enums = getOrCreateArray(AllEnumTypes); + DIType(TempEnumTypes).replaceAllUsesWith(Enums); + + DIArray RetainTypes = getOrCreateArray(AllRetainTypes); + DIType(TempRetainTypes).replaceAllUsesWith(RetainTypes); + + DIArray SPs = getOrCreateArray(AllSubprograms); + DIType(TempSubprograms).replaceAllUsesWith(SPs); + + DIArray GVs = getOrCreateArray(AllGVs); + DIType(TempGVs).replaceAllUsesWith(GVs); +} + +/// getNonCompileUnitScope - If N is compile unit return NULL otherwise return N. +static MDNode *getNonCompileUnitScope(MDNode *N) { + if (DIDescriptor(N).isCompileUnit()) + return NULL; + return N; } /// createCompileUnit - A CompileUnit provides an anchor for all debugging @@ -41,6 +61,23 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, StringRef Directory, StringRef Producer, bool isOptimized, StringRef Flags, unsigned RunTimeVer) { + Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) }; + TempEnumTypes = MDNode::getTemporary(VMContext, TElts); + Value *THElts[] = { TempEnumTypes }; + MDNode *EnumHolder = MDNode::get(VMContext, THElts); + + TempRetainTypes = MDNode::getTemporary(VMContext, TElts); + Value *TRElts[] = { TempRetainTypes }; + MDNode *RetainHolder = MDNode::get(VMContext, TRElts); + + TempSubprograms = MDNode::getTemporary(VMContext, TElts); + Value *TSElts[] = { TempSubprograms }; + MDNode *SPHolder = MDNode::get(VMContext, TSElts); + + TempGVs = MDNode::getTemporary(VMContext, TElts); + Value *TVElts[] = { TempGVs }; + MDNode *GVHolder = MDNode::get(VMContext, TVElts); + Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_compile_unit), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), @@ -52,7 +89,11 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, ConstantInt::get(Type::getInt1Ty(VMContext), true), // isMain ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized), MDString::get(VMContext, Flags), - ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer) + ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer), + EnumHolder, + RetainHolder, + SPHolder, + GVHolder }; TheCU = DICompileUnit(MDNode::get(VMContext, Elts)); @@ -69,7 +110,7 @@ DIFile DIBuilder::createFile(StringRef Filename, StringRef Directory) { GetTagConstant(VMContext, dwarf::DW_TAG_file_type), MDString::get(VMContext, Filename), MDString::get(VMContext, Directory), - TheCU + NULL // TheCU }; return DIFile(MDNode::get(VMContext, Elts)); } @@ -93,7 +134,7 @@ DIType DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits, // offset and flags are always empty here. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_base_type), - TheCU, + NULL, //TheCU, MDString::get(VMContext, Name), NULL, // Filename ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line @@ -112,7 +153,7 @@ DIType DIBuilder::createQualifiedType(unsigned Tag, DIType FromTy) { // Qualified types are encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, Tag), - TheCU, + NULL, //TheCU, MDString::get(VMContext, StringRef()), // Empty name. NULL, // Filename ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line @@ -131,7 +172,7 @@ DIType DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits, // Pointer types are encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_pointer_type), - TheCU, + NULL, //TheCU, MDString::get(VMContext, Name), NULL, // Filename ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line @@ -149,7 +190,7 @@ DIType DIBuilder::createReferenceType(DIType RTy) { // References are encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_reference_type), - TheCU, + NULL, //TheCU, NULL, // Name NULL, // Filename ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line @@ -169,7 +210,7 @@ DIType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File, assert(Ty.Verify() && "Invalid typedef type!"); Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_typedef), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), @@ -231,7 +272,7 @@ DIType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name, // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), - Scope, + getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -256,7 +297,7 @@ DIType DIBuilder::createObjCIVar(StringRef Name, // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), - File, // Or TheCU ? Ty ? + getNonCompileUnitScope(File), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -283,7 +324,7 @@ DIType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, // TAG_class_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_class_type), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -308,7 +349,7 @@ DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name, unsigned ColumnNo) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_template_type_parameter), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), Ty, File, @@ -327,7 +368,7 @@ DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name, unsigned ColumnNo) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_template_value_parameter), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), Ty, ConstantInt::get(Type::getInt64Ty(VMContext), Val), @@ -347,7 +388,7 @@ DIType DIBuilder::createStructType(DIDescriptor Context, StringRef Name, // TAG_structure_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_structure_type), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -372,7 +413,7 @@ DIType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, // TAG_union_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_union_type), - Scope, + getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -393,7 +434,7 @@ DIType DIBuilder::createSubroutineType(DIFile File, DIArray ParameterTypes) { // TAG_subroutine_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subroutine_type), - File, + getNonCompileUnitScope(File), MDString::get(VMContext, ""), File, ConstantInt::get(Type::getInt32Ty(VMContext), 0), @@ -418,7 +459,7 @@ DIType DIBuilder::createEnumerationType(DIDescriptor Scope, StringRef Name, // TAG_enumeration_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_enumeration_type), - Scope, + getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -432,8 +473,7 @@ DIType DIBuilder::createEnumerationType(DIDescriptor Scope, StringRef Name, llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), }; MDNode *Node = MDNode::get(VMContext, Elts); - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.enum"); - NMD->addOperand(Node); + AllEnumTypes.push_back(Node); return DIType(Node); } @@ -443,9 +483,9 @@ DIType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, // TAG_array_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_array_type), - TheCU, + NULL, //TheCU, MDString::get(VMContext, ""), - TheCU, + NULL, //TheCU, ConstantInt::get(Type::getInt32Ty(VMContext), 0), ConstantInt::get(Type::getInt64Ty(VMContext), Size), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), @@ -465,9 +505,9 @@ DIType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits, // TAG_vector_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_vector_type), - TheCU, + NULL, //TheCU, MDString::get(VMContext, ""), - TheCU, + NULL, //TheCU, ConstantInt::get(Type::getInt32Ty(VMContext), 0), ConstantInt::get(Type::getInt64Ty(VMContext), Size), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), @@ -508,8 +548,7 @@ DIType DIBuilder::createArtificialType(DIType Ty) { /// retainType - Retain DIType in a module even if it is not referenced /// through debug info anchors. void DIBuilder::retainType(DIType T) { - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.ty"); - NMD->addOperand(T); + AllRetainTypes.push_back(T); } /// createUnspecifiedParameter - Create unspeicified type descriptor @@ -536,7 +575,7 @@ DIType DIBuilder::createTemporaryType(DIFile F) { // use here as long as DIType accepts it. Value *Elts[] = { GetTagConstant(VMContext, DW_TAG_base_type), - F.getCompileUnit(), + TheCU, NULL, F }; @@ -572,7 +611,7 @@ createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_variable), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), - TheCU, + NULL, // TheCU, MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, Name), @@ -584,9 +623,7 @@ createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber, Val }; MDNode *Node = MDNode::get(VMContext, Elts); - // Create a named metadata so that we do not lose this mdnode. - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv"); - NMD->addOperand(Node); + AllGVs.push_back(Node); return DIGlobalVariable(Node); } @@ -599,7 +636,7 @@ createStaticVariable(DIDescriptor Context, StringRef Name, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_variable), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -611,9 +648,7 @@ createStaticVariable(DIDescriptor Context, StringRef Name, Val }; MDNode *Node = MDNode::get(VMContext, Elts); - // Create a named metadata so that we do not lose this mdnode. - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv"); - NMD->addOperand(Node); + AllGVs.push_back(Node); return DIGlobalVariable(Node); } @@ -625,7 +660,7 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, unsigned ArgNo) { Value *Elts[] = { GetTagConstant(VMContext, Tag), - Scope, + getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), (LineNo | (ArgNo << 24))), @@ -660,7 +695,7 @@ DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope, unsigned ArgNo) { SmallVector Elts; Elts.push_back(GetTagConstant(VMContext, Tag)); - Elts.push_back(Scope); + Elts.push_back(getNonCompileUnitScope(Scope)), Elts.push_back(MDString::get(VMContext, Name)); Elts.push_back(F); Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), (LineNo | (ArgNo << 24)))); @@ -686,7 +721,7 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -707,8 +742,7 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, MDNode *Node = MDNode::get(VMContext, Elts); // Create a named metadata so that we do not lose this mdnode. - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.sp"); - NMD->addOperand(Node); + AllSubprograms.push_back(Node); return DISubprogram(Node); } @@ -729,7 +763,7 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -747,10 +781,6 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, TParam, }; MDNode *Node = MDNode::get(VMContext, Elts); - - // Create a named metadata so that we do not lose this mdnode. - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.sp"); - NMD->addOperand(Node); return DISubprogram(Node); } @@ -760,7 +790,7 @@ DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNo) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_namespace), - Scope, + getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNo) @@ -774,7 +804,7 @@ DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, static unsigned int unique_id = 0; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block), - Scope, + getNonCompileUnitScope(Scope), ConstantInt::get(Type::getInt32Ty(VMContext), Line), ConstantInt::get(Type::getInt32Ty(VMContext), Col), File, diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index de4b6021df7..e6ce9e4e74c 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -359,7 +359,7 @@ bool DICompileUnit::Verify() const { bool DIType::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) + if (getContext() && !getContext().Verify()) return false; unsigned Tag = getTag(); if (!isBasicType() && Tag != dwarf::DW_TAG_const_type && @@ -386,12 +386,9 @@ bool DIDerivedType::Verify() const { bool DICompositeType::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) + if (getContext() && !getContext().Verify()) return false; - DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) - return false; return true; } @@ -400,11 +397,7 @@ bool DISubprogram::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) - return false; - - DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) + if (getContext() && !getContext().Verify()) return false; DICompositeType Ty = getType(); @@ -421,11 +414,7 @@ bool DIGlobalVariable::Verify() const { if (getDisplayName().empty()) return false; - if (!getContext().Verify()) - return false; - - DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) + if (getContext() && !getContext().Verify()) return false; DIType Ty = getType(); @@ -443,10 +432,7 @@ bool DIVariable::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) - return false; - - if (!getCompileUnit().Verify()) + if (getContext() && !getContext().Verify()) return false; DIType Ty = getType(); @@ -470,8 +456,6 @@ bool DINameSpace::Verify() const { return false; if (getName().empty()) return false; - if (!getCompileUnit().Verify()) - return false; return true; } @@ -566,6 +550,47 @@ StringRef DIScope::getDirectory() const { return StringRef(); } +DIArray DICompileUnit::getEnumTypes() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(10))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + +DIArray DICompileUnit::getRetainedTypes() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(11))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + +DIArray DICompileUnit::getSubprograms() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(12))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + + +DIArray DICompileUnit::getGlobalVariables() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(13))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + //===----------------------------------------------------------------------===// // DIDescriptor: dump routines for all descriptors. //===----------------------------------------------------------------------===// @@ -597,7 +622,6 @@ void DIType::print(raw_ostream &OS) const { OS << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context - getCompileUnit().print(OS); OS << " [" << "line " << getLineNumber() << ", " << getSizeInBits() << " bits, " @@ -653,7 +677,6 @@ void DISubprogram::print(raw_ostream &OS) const { OS << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context - getCompileUnit().print(OS); OS << " [" << getLineNumber() << "] "; if (isLocalToUnit()) @@ -676,7 +699,6 @@ void DIGlobalVariable::print(raw_ostream &OS) const { OS << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context - getCompileUnit().print(OS); OS << " [" << getLineNumber() << "] "; if (isLocalToUnit()) @@ -732,7 +754,6 @@ void DIVariable::print(raw_ostream &OS) const { if (!Res.empty()) OS << " [" << Res << "] "; - getCompileUnit().print(OS); OS << " [" << getLineNumber() << "] "; getType().print(OS); OS << "\n"; diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 3df6c80ae47..f337d189896 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -577,7 +577,10 @@ void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) { /// getOrCreateTypeDIE - Find existing DIE or create new DIE for the /// given DIType. -DIE *CompileUnit::getOrCreateTypeDIE(DIType Ty) { +DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) { + DIType Ty(TyNode); + if (!Ty.Verify()) + return NULL; DIE *TyDIE = getDIE(Ty); if (TyDIE) return TyDIE; @@ -629,7 +632,8 @@ void CompileUnit::addType(DIE *Entity, DIType Ty) { void CompileUnit::addGlobalType(DIType Ty) { DIDescriptor Context = Ty.getContext(); if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl() - && (Context.isCompileUnit() || Context.isFile() || Context.isNameSpace())) + && (!Context || Context.isCompileUnit() || Context.isFile() + || Context.isNameSpace())) if (DIEEntry *Entry = getDIEEntry(Ty)) GlobalTypes[Ty.getName()] = Entry->getEntry(); } @@ -1358,7 +1362,7 @@ DIE *CompileUnit::createMemberDIE(DIDerivedType DT) { addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, dwarf::DW_ACCESS_private); // Otherwise C++ member and base classes are considered public. - else if (DT.getCompileUnit().getLanguage() == dwarf::DW_LANG_C_plus_plus) + else addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, dwarf::DW_ACCESS_public); if (DT.isVirtual()) diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 5a155b42a3d..785926579fa 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -236,7 +236,7 @@ public: /// getOrCreateTypeDIE - Find existing DIE or create new DIE for the /// given DIType. - DIE *getOrCreateTypeDIE(DIType Ty); + DIE *getOrCreateTypeDIE(const MDNode *N); /// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE /// for the given DITemplateTypeParameter. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 45e0aaa5010..d096c0b9aa6 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -465,7 +465,7 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName, /// constructCompileUnit - Create new CompileUnit for the given /// metadata node with tag DW_TAG_compile_unit. -void DwarfDebug::constructCompileUnit(const MDNode *N) { +CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) { DICompileUnit DIUnit(N); StringRef FN = DIUnit.getFilename(); StringRef Dir = DIUnit.getDirectory(); @@ -507,35 +507,7 @@ void DwarfDebug::constructCompileUnit(const MDNode *N) { if (!FirstCU) FirstCU = NewCU; CUMap.insert(std::make_pair(N, NewCU)); -} - -/// getCompileUnit - Get CompileUnit DIE. -CompileUnit *DwarfDebug::getCompileUnit(const MDNode *N) const { - assert (N && "Invalid DwarfDebug::getCompileUnit argument!"); - DIDescriptor D(N); - const MDNode *CUNode = NULL; - if (D.isCompileUnit()) - CUNode = N; - else if (D.isSubprogram()) - CUNode = DISubprogram(N).getCompileUnit(); - else if (D.isType()) - CUNode = DIType(N).getCompileUnit(); - else if (D.isGlobalVariable()) - CUNode = DIGlobalVariable(N).getCompileUnit(); - else if (D.isVariable()) - CUNode = DIVariable(N).getCompileUnit(); - else if (D.isNameSpace()) - CUNode = DINameSpace(N).getCompileUnit(); - else if (D.isFile()) - CUNode = DIFile(N).getCompileUnit(); - else - return FirstCU; - - DenseMap::const_iterator I - = CUMap.find(CUNode); - if (I == CUMap.end()) - return FirstCU; - return I->second; + return NewCU; } /// constructGlobalVariableDIE - Construct global variable DIE. @@ -571,22 +543,39 @@ void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU, // Expose as global. TheCU->addGlobal(SP.getName(), SubprogramDie); + SPMap[N] = TheCU; return; } /// collectInfoFromNamedMDNodes - Collect debug info from named mdnodes such /// as llvm.dbg.enum and llvm.dbg.ty void DwarfDebug::collectInfoFromNamedMDNodes(Module *M) { + if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp")) + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + const MDNode *N = NMD->getOperand(i); + if (CompileUnit *CU = CUMap.lookup(DISubprogram(N).getCompileUnit())) + constructSubprogramDIE(CU, N); + } + + if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv")) + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + const MDNode *N = NMD->getOperand(i); + if (CompileUnit *CU = CUMap.lookup(DIGlobalVariable(N).getCompileUnit())) + constructGlobalVariableDIE(CU, N); + } + if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.enum")) for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { DIType Ty(NMD->getOperand(i)); - getCompileUnit(Ty)->getOrCreateTypeDIE(Ty); + if (CompileUnit *CU = CUMap.lookup(Ty.getCompileUnit())) + CU->getOrCreateTypeDIE(Ty); } if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.ty")) for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { DIType Ty(NMD->getOperand(i)); - getCompileUnit(Ty)->getOrCreateTypeDIE(Ty); + if (CompileUnit *CU = CUMap.lookup(Ty.getCompileUnit())) + CU->getOrCreateTypeDIE(Ty); } } @@ -617,14 +606,16 @@ bool DwarfDebug::collectLegacyDebugInfo(Module *M) { for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(), E = DbgFinder.global_variable_end(); I != E; ++I) { const MDNode *N = *I; - constructGlobalVariableDIE(getCompileUnit(N), N); + if (CompileUnit *CU = CUMap.lookup(DIGlobalVariable(N).getCompileUnit())) + constructGlobalVariableDIE(CU, N); } - + // Create DIEs for each subprogram. for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(), E = DbgFinder.subprogram_end(); I != E; ++I) { const MDNode *N = *I; - constructSubprogramDIE(getCompileUnit(N), N); + if (CompileUnit *CU = CUMap.lookup(DISubprogram(N).getCompileUnit())) + constructSubprogramDIE(CU, N); } return HasDebugInfo; @@ -641,29 +632,22 @@ void DwarfDebug::beginModule(Module *M) { // module using debug info finder to collect debug info. NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); if (CU_Nodes) { - - NamedMDNode *GV_Nodes = M->getNamedMetadata("llvm.dbg.gv"); - NamedMDNode *SP_Nodes = M->getNamedMetadata("llvm.dbg.sp"); - if (!GV_Nodes && !SP_Nodes) - // If there are not any global variables or any functions then - // there is not any debug info in this module. - return; - - for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) - constructCompileUnit(CU_Nodes->getOperand(i)); - - if (GV_Nodes) - for (unsigned i = 0, e = GV_Nodes->getNumOperands(); i != e; ++i) { - const MDNode *N = GV_Nodes->getOperand(i); - constructGlobalVariableDIE(getCompileUnit(N), N); - } - - if (SP_Nodes) - for (unsigned i = 0, e = SP_Nodes->getNumOperands(); i != e; ++i) { - const MDNode *N = SP_Nodes->getOperand(i); - constructSubprogramDIE(getCompileUnit(N), N); - } - + for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { + DICompileUnit CUNode(CU_Nodes->getOperand(i)); + CompileUnit *CU = constructCompileUnit(CUNode); + DIArray GVs = CUNode.getGlobalVariables(); + for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) + constructGlobalVariableDIE(CU, GVs.getElement(i)); + DIArray SPs = CUNode.getSubprograms(); + for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) + constructSubprogramDIE(CU, SPs.getElement(i)); + DIArray EnumTypes = CUNode.getEnumTypes(); + for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) + CU->getOrCreateTypeDIE(EnumTypes.getElement(i)); + DIArray RetainedTypes = CUNode.getRetainedTypes(); + for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) + CU->getOrCreateTypeDIE(RetainedTypes.getElement(i)); + } } else if (!collectLegacyDebugInfo(M)) return; @@ -685,39 +669,44 @@ void DwarfDebug::endModule() { if (!FirstCU) return; const Module *M = MMI->getModule(); DenseMap DeadFnScopeMap; - if (NamedMDNode *AllSPs = M->getNamedMetadata("llvm.dbg.sp")) { - for (unsigned SI = 0, SE = AllSPs->getNumOperands(); SI != SE; ++SI) { - if (ProcessedSPNodes.count(AllSPs->getOperand(SI)) != 0) continue; - DISubprogram SP(AllSPs->getOperand(SI)); - if (!SP.Verify()) continue; - - // Collect info for variables that were optimized out. - if (!SP.isDefinition()) continue; - StringRef FName = SP.getLinkageName(); - if (FName.empty()) - FName = SP.getName(); - NamedMDNode *NMD = getFnSpecificMDNode(*(MMI->getModule()), FName); - if (!NMD) continue; - unsigned E = NMD->getNumOperands(); - if (!E) continue; - LexicalScope *Scope = new LexicalScope(NULL, DIDescriptor(SP), NULL, - false); - DeadFnScopeMap[SP] = Scope; - SmallVector Variables; - for (unsigned I = 0; I != E; ++I) { - DIVariable DV(NMD->getOperand(I)); - if (!DV.Verify()) continue; - Variables.push_back(DbgVariable(DV, NULL)); - } - // Construct subprogram DIE and add variables DIEs. - CompileUnit *SPCU = getCompileUnit(SP); - constructSubprogramDIE(SPCU, SP); - DIE *ScopeDIE = SPCU->getDIE(SP); - for (unsigned i = 0, N = Variables.size(); i < N; ++i) { - if (DIE *VariableDIE = - SPCU->constructVariableDIE(&Variables[i], Scope->isAbstractScope())) - ScopeDIE->addChild(VariableDIE); + // Collect info for variables that were optimized out. + if (NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu")) { + for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { + DICompileUnit TheCU(CU_Nodes->getOperand(i)); + DIArray Subprograms = TheCU.getSubprograms(); + for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) { + DISubprogram SP(Subprograms.getElement(i)); + if (ProcessedSPNodes.count(SP) != 0) continue; + if (!SP.Verify()) continue; + if (!SP.isDefinition()) continue; + StringRef FName = SP.getLinkageName(); + if (FName.empty()) + FName = SP.getName(); + NamedMDNode *NMD = getFnSpecificMDNode(*(MMI->getModule()), FName); + if (!NMD) continue; + unsigned E = NMD->getNumOperands(); + if (!E) continue; + LexicalScope *Scope = + new LexicalScope(NULL, DIDescriptor(SP), NULL, false); + DeadFnScopeMap[SP] = Scope; + + // Construct subprogram DIE and add variables DIEs. + SmallVector Variables; + for (unsigned I = 0; I != E; ++I) { + DIVariable DV(NMD->getOperand(I)); + if (!DV.Verify()) continue; + Variables.push_back(DbgVariable(DV, NULL)); + } + CompileUnit *SPCU = CUMap.lookup(TheCU); + assert (SPCU && "Unable to find Compile Unit!"); + constructSubprogramDIE(SPCU, SP); + DIE *ScopeDIE = SPCU->getDIE(SP); + for (unsigned i = 0, N = Variables.size(); i < N; ++i) { + if (DIE *VariableDIE = + SPCU->constructVariableDIE(&Variables[i], Scope->isAbstractScope())) + ScopeDIE->addChild(VariableDIE); + } } } } @@ -784,6 +773,7 @@ void DwarfDebug::endModule() { // clean up. DeleteContainerSeconds(DeadFnScopeMap); + SPMap.clear(); for (DenseMap::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) delete I->second; @@ -1333,7 +1323,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { collectVariableInfo(MF, ProcessedVars); LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); - CompileUnit *TheCU = getCompileUnit(FnScope->getScopeNode()); + CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); + assert (TheCU && "Unable to find compile unit!"); // Construct abstract scopes. ArrayRef AList = LScopes.getAbstractScopesList(); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 3c8c683bd04..042d693a9b6 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -192,8 +192,13 @@ class DwarfDebug { // CompileUnit *FirstCU; + + /// Maps MDNode with its corresponding CompileUnit. DenseMap CUMap; + /// Maps subprogram MDNode with its corresponding CompileUnit. + DenseMap SPMap; + /// AbbreviationsSet - Used to uniquely define abbreviations. /// FoldingSet AbbreviationsSet; @@ -410,10 +415,7 @@ private: /// constructCompileUnit - Create new CompileUnit for the given /// metadata node with tag DW_TAG_compile_unit. - void constructCompileUnit(const MDNode *N); - - /// getCompielUnit - Get CompileUnit DIE. - CompileUnit *getCompileUnit(const MDNode *N) const; + CompileUnit *constructCompileUnit(const MDNode *N); /// constructGlobalVariableDIE - Construct global variable DIE. void constructGlobalVariableDIE(CompileUnit *TheCU, const MDNode *N); -- 2.34.1