diff options
author | Manman Ren <manman.ren@gmail.com> | 2013-09-05 18:48:31 +0000 |
---|---|---|
committer | Manman Ren <manman.ren@gmail.com> | 2013-09-05 18:48:31 +0000 |
commit | 60352032bf87498601f436c9ed77c235c82f3d29 (patch) | |
tree | c7c74d94f287cf792e7cbd171ef14d1e4e240dd9 /llvm/lib | |
parent | 13c68ef88b23458a5030579e651fd204c8d3a0b8 (diff) | |
download | bcm5719-llvm-60352032bf87498601f436c9ed77c235c82f3d29.tar.gz bcm5719-llvm-60352032bf87498601f436c9ed77c235c82f3d29.zip |
Debug Info: Use identifier to reference DIType in base type field of
ptr_to_member.
We introduce a new class DITypeRef that represents a reference to a DIType.
It wraps around a Value*, which can be either an identifier in MDString
or an actual MDNode. The class has a helper function "resolve" that
finds the actual MDNode for a given DITypeRef.
We specialize getFieldAs to return a field that is a reference to a
DIType. To correctly access the base type field of ptr_to_member,
getClassType now calls getFieldAs<DITypeRef> to return a DITypeRef.
Also add a typedef for DITypeIdentifierMap and a helper
generateDITypeIdentifierMap in DebugInfo.h. In DwarfDebug.cpp, we keep
a DITypeIdentifierMap and call generateDITypeIdentifierMap to actually
populate the map.
Verifier is updated accordingly.
llvm-svn: 190081
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 7 | ||||
-rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfo.cpp | 72 |
5 files changed, 97 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 4c95e140969..6db54d2fafb 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -905,7 +905,7 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) { if (Tag == dwarf::DW_TAG_ptr_to_member_type) addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, - getOrCreateTypeDIE(DTy.getClassType())); + getOrCreateTypeDIE(DD->resolve(DTy.getClassType()))); // Add source line info if available and TyDesc is not a forward declaration. if (!DTy.isForwardDecl()) addSourceLine(&Buffer, DTy); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index f97ddcb5a84..57ad489970d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -823,6 +823,7 @@ void DwarfDebug::beginModule() { NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); if (!CU_Nodes) return; + TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes); // Emit initial sections so we can reference labels later. emitSectionLabels(); @@ -2631,3 +2632,8 @@ void DwarfDebug::emitDebugStrDWO() { InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(), OffSec, StrSym); } + +/// Find the MDNode for the given type reference. +MDNode *DwarfDebug::resolve(DITypeRef TRef) const { + return TRef.resolve(TypeIdentifierMap); +} diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 97a454ac9da..0258fdc3dbb 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -450,6 +450,9 @@ class DwarfDebug { // Holder for the skeleton information. DwarfUnits SkeletonHolder; + // Maps from a type identifier to the actual MDNode. + DITypeIdentifierMap TypeIdentifierMap; + private: void addScopeVariable(LexicalScope *LS, DbgVariable *Var); @@ -679,6 +682,10 @@ public: /// Returns the Dwarf Version. unsigned getDwarfVersion() const { return DwarfVersion; } + + /// Find the MDNode for the given type reference. + MDNode *resolve(DITypeRef TRef) const; + }; } // End of namespace llvm diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 51e296383e0..2ff10b593ed 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -75,6 +75,18 @@ void DIBuilder::finalize() { DIType(TempImportedModules).replaceAllUsesWith(IMs); } +/// Use the type identifier instead of the actual MDNode if possible, +/// to help type uniquing. This function returns the identifier if it +/// exists for the given type, otherwise returns the MDNode. +static Value *getTypeIdentifier(DIType T) { + if (!T.isCompositeType()) + return T; + DICompositeType DTy(T); + if (!DTy.getIdentifier()) + return T; + return DTy.getIdentifier(); +} + /// getNonCompileUnitScope - If N is compile unit return NULL otherwise return /// N. static MDNode *getNonCompileUnitScope(MDNode *N) { @@ -322,7 +334,7 @@ DIDerivedType DIBuilder::createMemberPointerType(DIType PointeeTy, ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags PointeeTy, - Base + getTypeIdentifier(Base) }; return DIDerivedType(MDNode::get(VMContext, Elts)); } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 9684bd73f4e..d3207cae350 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -425,6 +425,17 @@ static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) { return !Fld || isa<MDString>(Fld); } +/// Check if a value can be a TypeRef. +static bool isTypeRef(const Value *Val) { + return !Val || isa<MDString>(Val) || isa<MDNode>(Val); +} + +/// Check if a field at position Elt of a MDNode can be a TypeRef. +static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) { + Value *Fld = getField(DbgNode, Elt); + return isTypeRef(Fld); +} + /// Verify - Verify that a type descriptor is well formed. bool DIType::Verify() const { if (!isType()) @@ -470,8 +481,8 @@ bool DIDerivedType::Verify() const { if (!fieldIsMDNode(DbgNode, 9)) return false; if (getTag() == dwarf::DW_TAG_ptr_to_member_type) - // Make sure ClassType @ field 10 is MDNode. - if (!fieldIsMDNode(DbgNode, 10)) + // Make sure ClassType @ field 10 is a TypeRef. + if (!fieldIsTypeRef(DbgNode, 10)) return false; return isDerivedType() && DbgNode->getNumOperands() >= 10 && @@ -923,6 +934,32 @@ bool llvm::isSubprogramContext(const MDNode *Context) { return false; } +/// Update DITypeIdentifierMap by going through retained types of each CU. +DITypeIdentifierMap llvm::generateDITypeIdentifierMap( + const NamedMDNode *CU_Nodes) { + DITypeIdentifierMap Map; + for (unsigned CUi = 0, CUe = CU_Nodes->getNumOperands(); CUi != CUe; ++CUi) { + DICompileUnit CU(CU_Nodes->getOperand(CUi)); + DIArray Retain = CU.getRetainedTypes(); + for (unsigned Ti = 0, Te = Retain.getNumElements(); Ti != Te; ++Ti) { + if (!Retain.getElement(Ti).isCompositeType()) + continue; + DICompositeType Ty(Retain.getElement(Ti)); + if (MDString *TypeId = Ty.getIdentifier()) { + // Definition has priority over declaration. + // Try to insert (TypeId, Ty) to Map. + std::pair<DITypeIdentifierMap::iterator, bool> P = + Map.insert(std::make_pair(TypeId, Ty)); + // If TypeId already exists in Map and this is a definition, replace + // whatever we had (declaration or definition) with the definition. + if (!P.second && !Ty.isForwardDecl()) + P.first->second = Ty; + } + } + } + return Map; +} + //===----------------------------------------------------------------------===// // DebugInfoFinder implementations. //===----------------------------------------------------------------------===// @@ -1378,3 +1415,34 @@ void DIVariable::printExtendedName(raw_ostream &OS) const { } } } + +DITypeRef::DITypeRef(const Value *V) : TypeVal(V) { + assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode"); +} + +/// Given a DITypeIdentifierMap, tries to find the corresponding +/// DIType for a DITypeRef. +DIType DITypeRef::resolve(const DITypeIdentifierMap &Map) const { + if (!TypeVal) + return NULL; + + if (const MDNode *MD = dyn_cast<MDNode>(TypeVal)) { + assert(DIType(MD).isType() && + "MDNode in DITypeRef should be a DIType."); + return MD; + } + + const MDString *MS = cast<MDString>(TypeVal); + // Find the corresponding MDNode. + DITypeIdentifierMap::const_iterator Iter = Map.find(MS); + assert(Iter != Map.end() && "Identifier not in the type map?"); + assert(DIType(Iter->second).isType() && + "MDNode in DITypeIdentifierMap should be a DIType."); + return Iter->second; +} + +/// Specialize getFieldAs to handle fields that are references to DITypes. +template <> +DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const { + return DITypeRef(getField(DbgNode, Elt)); +} |