Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
DebugInfo: Remove MDString-based type references
Browse files Browse the repository at this point in the history
Eliminate DITypeIdentifierMap and make DITypeRef a thin wrapper around
DIType*.  It is no longer legal to refer to a DICompositeType by its
'identifier:', and DIBuilder no longer retains all types with an
'identifier:' automatically.

Aside from the bitcode upgrade, this is mainly removing logic to resolve
an MDString-based reference to an actualy DIType.  The commits leading
up to this have made the implicit type map in DICompileUnit's
'retainedTypes:' field superfluous.

This does not remove DITypeRef, DIScopeRef, DINodeRef, and
DITypeRefArray, or stop using them in DI-related metadata.  Although as
of this commit they aren't serving a useful purpose, there are patchces
under review to reuse them for CodeView support.

The tests in LLVM were updated with deref-typerefs.sh, which is attached
to the thread "[RFC] Lazy-loading of debug info metadata":

  http:https://lists.llvm.org/pipermail/llvm-dev/2016-April/098318.html

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267296 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
dexonsmith committed Apr 23, 2016
1 parent 7ceecf0 commit de74840
Show file tree
Hide file tree
Showing 77 changed files with 729 additions and 825 deletions.
26 changes: 15 additions & 11 deletions docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4019,12 +4019,13 @@ The following ``tag:`` values are valid:
DW_TAG_volatile_type = 53
DW_TAG_restrict_type = 55
.. _DIDerivedTypeMember:

``DW_TAG_member`` is used to define a member of a :ref:`composite type
<DICompositeType>`. The type of the member is the ``baseType:``. The
``offset:`` is the member's bit offset. If the composite type has a non-empty
``identifier:``, then it respects ODR rules. In that case, the ``scope:``
reference will be a :ref:`metadata string <metadata-string>`, and the member
will be uniqued solely based on its ``name:`` and ``scope:``.
``offset:`` is the member's bit offset. If the composite type has an ODR
``identifier:`` and does not set ``flags: DIFwdDecl``, then the member is
uniqued based only on its ``name:`` and ``scope:``.

``DW_TAG_inheritance`` and ``DW_TAG_friend`` are used in the ``elements:``
field of :ref:`composite types <DICompositeType>` to describe parents and
Expand All @@ -4047,9 +4048,10 @@ DICompositeType
structures and unions. ``elements:`` points to a tuple of the composed types.

If the source language supports ODR, the ``identifier:`` field gives the unique
identifier used for type merging between modules. When specified, other types
can refer to composite types indirectly via a :ref:`metadata string
<metadata-string>` that matches their identifier.
identifier used for type merging between modules. When specified,
:ref:`subprogram declarations <DISubprogramDeclaration>` and :ref:`member
derived types <DIDerivedTypeMember>` that reference the ODR-type in their
``scope:`` change uniquing rules.

For a given ``identifier:``, there should only be a single composite type that
does not have ``flags: DIFlagFwdDecl`` set. LLVM tools that link modules
Expand Down Expand Up @@ -4178,11 +4180,13 @@ metadata. The ``variables:`` field points at :ref:`variables <DILocalVariable>`
that must be retained, even if their IR counterparts are optimized out of
the IR. The ``type:`` field must point at an :ref:`DISubroutineType`.

.. _DISubprogramDeclaration:

When ``isDefinition: false``, subprograms describe a declaration in the type
tree as opposed to a definition of a funciton. If the scope is a
:ref:`metadata string <metadata-string>` then the composite type follows ODR
rules, and the subprogram declaration is uniqued based only on its
``linkageName:`` and ``scope:``.
tree as opposed to a definition of a function. If the scope is a composite
type with an ODR ``identifier:`` and that does not set ``flags: DIFwdDecl``,
then the subprogram declaration is uniqued based only on its ``linkageName:``
and ``scope:``.

.. code-block:: llvm
Expand Down
12 changes: 0 additions & 12 deletions include/llvm/IR/DebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,9 @@ class DbgValueInst;
template <typename K, typename V, typename KeyInfoT, typename BucketT>
class DenseMap;

/// \brief Maps from type identifier to the actual MDNode.
typedef DenseMap<const MDString *, DIType *> DITypeIdentifierMap;

/// \brief Find subprogram that is enclosing this scope.
DISubprogram *getDISubprogram(const MDNode *Scope);

/// \brief Generate map by visiting all retained types.
DITypeIdentifierMap generateDITypeIdentifierMap(const Module &M);

/// \brief Strip debug info in the module if it exists.
///
/// To do this, we remove all calls to the debugger intrinsics and any named
Expand All @@ -63,8 +57,6 @@ unsigned getDebugMetadataVersionFromModule(const Module &M);
/// used by the CUs.
class DebugInfoFinder {
public:
DebugInfoFinder() : TypeMapInitialized(false) {}

/// \brief Process entire module and collect debug info anchors.
void processModule(const Module &M);

Expand Down Expand Up @@ -132,10 +124,6 @@ class DebugInfoFinder {
SmallVector<DIType *, 8> TYs;
SmallVector<DIScope *, 8> Scopes;
SmallPtrSet<const MDNode *, 32> NodesSeen;
DITypeIdentifierMap TypeIdentifierMap;

/// \brief Specify if TypeIdentifierMap is initialized.
bool TypeMapInitialized;
};

} // end namespace llvm
Expand Down
48 changes: 10 additions & 38 deletions include/llvm/IR/DebugInfoMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,23 @@ namespace llvm {

template <typename T> class Optional;

/// \brief Pointer union between a subclass of DINode and MDString.
/// Holds a subclass of DINode.
///
/// \a DICompositeType can be referenced via an \a MDString unique identifier.
/// This class allows some type safety in the face of that, requiring either a
/// node of a particular type or an \a MDString.
/// FIXME: This class doesn't currently make much sense. Previously it was a
/// union beteen MDString (for ODR-uniqued types) and things like DIType. To
/// support CodeView work, it wasn't deleted outright when MDString-based type
/// references were deleted; we'll soon need a similar concept for CodeView
/// DITypeIndex.
template <class T> class TypedDINodeRef {
const Metadata *MD = nullptr;

public:
TypedDINodeRef() = default;
TypedDINodeRef(std::nullptr_t) {}
TypedDINodeRef(const T *MD) : MD(MD) {}

/// \brief Construct from a raw pointer.
explicit TypedDINodeRef(const Metadata *MD) : MD(MD) {
assert((!MD || isa<MDString>(MD) || isa<T>(MD)) && "Expected valid ref");
assert((!MD || isa<T>(MD)) && "Expected valid type ref");
}

template <class U>
Expand All @@ -71,26 +73,10 @@ template <class T> class TypedDINodeRef {

operator Metadata *() const { return const_cast<Metadata *>(MD); }

T *resolve() const { return const_cast<T *>(cast_or_null<T>(MD)); }

bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; }
bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; }

/// \brief Create a reference.
///
/// Get a reference to \c N, using an \a MDString reference if available.
static TypedDINodeRef get(const T *N);

template <class MapTy> T *resolve(const MapTy &Map) const {
if (!MD)
return nullptr;

if (auto *Typed = dyn_cast<T>(MD))
return const_cast<T *>(Typed);

auto *S = cast<MDString>(MD);
auto I = Map.find(S);
assert(I != Map.end() && "Missing identifier in type map");
return cast<T>(I->second);
}
};

typedef TypedDINodeRef<DINode> DINodeRef;
Expand Down Expand Up @@ -201,8 +187,6 @@ class DINode : public MDNode {
static unsigned splitFlags(unsigned Flags,
SmallVectorImpl<unsigned> &SplitFlags);

DINodeRef getRef() const { return DINodeRef::get(this); }

static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
Expand Down Expand Up @@ -437,8 +421,6 @@ class DIScope : public DINode {
: static_cast<Metadata *>(getOperand(0));
}

DIScopeRef getRef() const { return DIScopeRef::get(this); }

static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
Expand Down Expand Up @@ -602,8 +584,6 @@ class DIType : public DIScope {
bool isRValueReference() const { return getFlags() & FlagRValueReference; }
bool isExternalTypeRef() const { return getFlags() & FlagExternalTypeRef; }

DITypeRef getRef() const { return DITypeRef::get(this); }

static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
Expand Down Expand Up @@ -933,14 +913,6 @@ class DICompositeType : public DIType {
}
};

template <class T> TypedDINodeRef<T> TypedDINodeRef<T>::get(const T *N) {
if (N)
if (auto *Composite = dyn_cast<DICompositeType>(N))
if (auto *S = Composite->getRawIdentifier())
return TypedDINodeRef<T>(S);
return TypedDINodeRef<T>(N);
}

/// \brief Type array for a subprogram.
///
/// TODO: Fold the array of types in directly as operands.
Expand Down
Loading

0 comments on commit de74840

Please sign in to comment.