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 | bc66071baa3153ba95d673b8084383835221eef6 (patch) | |
tree | ea089a4002af6dfa75f7df34d5da3c0a36b04247 /lib/IR | |
parent | 79916948e1fd176a3898b596b679cc9dba3d40a8 (diff) | |
download | external_llvm-bc66071baa3153ba95d673b8084383835221eef6.zip external_llvm-bc66071baa3153ba95d673b8084383835221eef6.tar.gz external_llvm-bc66071baa3153ba95d673b8084383835221eef6.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190081 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r-- | lib/IR/DIBuilder.cpp | 14 | ||||
-rw-r--r-- | lib/IR/DebugInfo.cpp | 72 |
2 files changed, 83 insertions, 3 deletions
diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index 51e2963..2ff10b5 100644 --- a/lib/IR/DIBuilder.cpp +++ b/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/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index 9684bd7..d3207ca 100644 --- a/lib/IR/DebugInfo.cpp +++ b/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)); +} |