From: Duncan P. N. Exon Smith Date: Mon, 2 Feb 2015 18:53:21 +0000 (+0000) Subject: IR: Split out DebugInfoMetadata.h, NFC X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ca8d3bf8af0bd32076e4a60b1f997ee48c3187d8;p=oota-llvm.git IR: Split out DebugInfoMetadata.h, NFC Move debug-info-centred `Metadata` subclasses into their own header/source file. A couple of private template functions are needed from both `Metadata.cpp` and `DebugInfoMetadata.cpp`, so I've moved them to `lib/IR/MetadataImpl.h`. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227835 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h index 1aec146c579..b3731024881 100644 --- a/include/llvm/IR/DebugInfo.h +++ b/include/llvm/IR/DebugInfo.h @@ -22,7 +22,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" -#include "llvm/IR/Metadata.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h new file mode 100644 index 00000000000..28f29ec8353 --- /dev/null +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -0,0 +1,201 @@ +//===- llvm/IR/DebugInfoMetadata.h - Debug info metadata --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Declarations for metadata specific to debug info. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_DEBUGINFOMETADATA_H +#define LLVM_IR_DEBUGINFOMETADATA_H + +#include "llvm/IR/Metadata.h" + +namespace llvm { + +/// \brief Debug location. +/// +/// A debug location in source code, used for debug info and otherwise. +class MDLocation : public MDNode { + friend class LLVMContextImpl; + friend class MDNode; + + MDLocation(LLVMContext &C, StorageType Storage, unsigned Line, + unsigned Column, ArrayRef MDs); + ~MDLocation() { dropAllReferences(); } + + static MDLocation *getImpl(LLVMContext &Context, unsigned Line, + unsigned Column, Metadata *Scope, + Metadata *InlinedAt, StorageType Storage, + bool ShouldCreate = true); + + TempMDLocation cloneImpl() const { + return getTemporary(getContext(), getLine(), getColumn(), getScope(), + getInlinedAt()); + } + + // Disallow replacing operands. + void replaceOperandWith(unsigned I, Metadata *New) LLVM_DELETED_FUNCTION; + +public: + static MDLocation *get(LLVMContext &Context, unsigned Line, unsigned Column, + Metadata *Scope, Metadata *InlinedAt = nullptr) { + return getImpl(Context, Line, Column, Scope, InlinedAt, Uniqued); + } + static MDLocation *getIfExists(LLVMContext &Context, unsigned Line, + unsigned Column, Metadata *Scope, + Metadata *InlinedAt = nullptr) { + return getImpl(Context, Line, Column, Scope, InlinedAt, Uniqued, + /* ShouldCreate */ false); + } + static MDLocation *getDistinct(LLVMContext &Context, unsigned Line, + unsigned Column, Metadata *Scope, + Metadata *InlinedAt = nullptr) { + return getImpl(Context, Line, Column, Scope, InlinedAt, Distinct); + } + static TempMDLocation getTemporary(LLVMContext &Context, unsigned Line, + unsigned Column, Metadata *Scope, + Metadata *InlinedAt = nullptr) { + return TempMDLocation( + getImpl(Context, Line, Column, Scope, InlinedAt, Temporary)); + } + + /// \brief Return a (temporary) clone of this. + TempMDLocation clone() const { return cloneImpl(); } + + unsigned getLine() const { return SubclassData32; } + unsigned getColumn() const { return SubclassData16; } + Metadata *getScope() const { return getOperand(0); } + Metadata *getInlinedAt() const { + if (getNumOperands() == 2) + return getOperand(1); + return nullptr; + } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == MDLocationKind; + } +}; + +/// \brief Tagged DWARF-like metadata node. +/// +/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*, +/// defined in llvm/Support/Dwarf.h). Called \a DebugNode because it's +/// potentially used for non-DWARF output. +class DebugNode : public MDNode { + friend class LLVMContextImpl; + friend class MDNode; + +protected: + DebugNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, + ArrayRef Ops1, ArrayRef Ops2 = None) + : MDNode(C, ID, Storage, Ops1, Ops2) { + assert(Tag < 1u << 16); + SubclassData16 = Tag; + } + ~DebugNode() {} + +public: + unsigned getTag() const { return SubclassData16; } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == GenericDebugNodeKind; + } +}; + +/// \brief Generic tagged DWARF-like metadata node. +/// +/// An un-specialized DWARF-like metadata node. The first operand is a +/// (possibly empty) null-separated \a MDString header that contains arbitrary +/// fields. The remaining operands are \a dwarf_operands(), and are pointers +/// to other metadata. +class GenericDebugNode : public DebugNode { + friend class LLVMContextImpl; + friend class MDNode; + + GenericDebugNode(LLVMContext &C, StorageType Storage, unsigned Hash, + unsigned Tag, ArrayRef Ops1, + ArrayRef Ops2) + : DebugNode(C, GenericDebugNodeKind, Storage, Tag, Ops1, Ops2) { + setHash(Hash); + } + ~GenericDebugNode() { dropAllReferences(); } + + void setHash(unsigned Hash) { SubclassData32 = Hash; } + void recalculateHash(); + + static GenericDebugNode *getImpl(LLVMContext &Context, unsigned Tag, + StringRef Header, + ArrayRef DwarfOps, + StorageType Storage, + bool ShouldCreate = true); + + TempGenericDebugNode cloneImpl() const { + return getTemporary( + getContext(), getTag(), getHeader(), + SmallVector(dwarf_op_begin(), dwarf_op_end())); + } + +public: + unsigned getHash() const { return SubclassData32; } + + static GenericDebugNode *get(LLVMContext &Context, unsigned Tag, + StringRef Header, + ArrayRef DwarfOps) { + return getImpl(Context, Tag, Header, DwarfOps, Uniqued); + } + static GenericDebugNode *getIfExists(LLVMContext &Context, unsigned Tag, + StringRef Header, + ArrayRef DwarfOps) { + return getImpl(Context, Tag, Header, DwarfOps, Uniqued, + /* ShouldCreate */ false); + } + static GenericDebugNode *getDistinct(LLVMContext &Context, unsigned Tag, + StringRef Header, + ArrayRef DwarfOps) { + return getImpl(Context, Tag, Header, DwarfOps, Distinct); + } + static TempGenericDebugNode getTemporary(LLVMContext &Context, unsigned Tag, + StringRef Header, + ArrayRef DwarfOps) { + return TempGenericDebugNode( + getImpl(Context, Tag, Header, DwarfOps, Temporary)); + } + + /// \brief Return a (temporary) clone of this. + TempGenericDebugNode clone() const { return cloneImpl(); } + + unsigned getTag() const { return SubclassData16; } + StringRef getHeader() const { + if (auto *S = cast_or_null(getOperand(0))) + return S->getString(); + return StringRef(); + } + + op_iterator dwarf_op_begin() const { return op_begin() + 1; } + op_iterator dwarf_op_end() const { return op_end(); } + op_range dwarf_operands() const { + return op_range(dwarf_op_begin(), dwarf_op_end()); + } + + unsigned getNumDwarfOperands() const { return getNumOperands() - 1; } + const MDOperand &getDwarfOperand(unsigned I) const { + return getOperand(I + 1); + } + void replaceDwarfOperandWith(unsigned I, Metadata *New) { + replaceOperandWith(I + 1, New); + } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == GenericDebugNodeKind; + } +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index babad32be5e..66baa962880 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -961,184 +961,6 @@ void TempMDNodeDeleter::operator()(MDNode *Node) const { MDNode::deleteTemporary(Node); } -/// \brief Debug location. -/// -/// A debug location in source code, used for debug info and otherwise. -class MDLocation : public MDNode { - friend class LLVMContextImpl; - friend class MDNode; - - MDLocation(LLVMContext &C, StorageType Storage, unsigned Line, - unsigned Column, ArrayRef MDs); - ~MDLocation() { dropAllReferences(); } - - static MDLocation *getImpl(LLVMContext &Context, unsigned Line, - unsigned Column, Metadata *Scope, - Metadata *InlinedAt, StorageType Storage, - bool ShouldCreate = true); - - TempMDLocation cloneImpl() const { - return getTemporary(getContext(), getLine(), getColumn(), getScope(), - getInlinedAt()); - } - - // Disallow replacing operands. - void replaceOperandWith(unsigned I, Metadata *New) LLVM_DELETED_FUNCTION; - -public: - static MDLocation *get(LLVMContext &Context, unsigned Line, unsigned Column, - Metadata *Scope, Metadata *InlinedAt = nullptr) { - return getImpl(Context, Line, Column, Scope, InlinedAt, Uniqued); - } - static MDLocation *getIfExists(LLVMContext &Context, unsigned Line, - unsigned Column, Metadata *Scope, - Metadata *InlinedAt = nullptr) { - return getImpl(Context, Line, Column, Scope, InlinedAt, Uniqued, - /* ShouldCreate */ false); - } - static MDLocation *getDistinct(LLVMContext &Context, unsigned Line, - unsigned Column, Metadata *Scope, - Metadata *InlinedAt = nullptr) { - return getImpl(Context, Line, Column, Scope, InlinedAt, Distinct); - } - static TempMDLocation getTemporary(LLVMContext &Context, unsigned Line, - unsigned Column, Metadata *Scope, - Metadata *InlinedAt = nullptr) { - return TempMDLocation( - getImpl(Context, Line, Column, Scope, InlinedAt, Temporary)); - } - - /// \brief Return a (temporary) clone of this. - TempMDLocation clone() const { return cloneImpl(); } - - unsigned getLine() const { return SubclassData32; } - unsigned getColumn() const { return SubclassData16; } - Metadata *getScope() const { return getOperand(0); } - Metadata *getInlinedAt() const { - if (getNumOperands() == 2) - return getOperand(1); - return nullptr; - } - - static bool classof(const Metadata *MD) { - return MD->getMetadataID() == MDLocationKind; - } -}; - -/// \brief Tagged DWARF-like metadata node. -/// -/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*, -/// defined in llvm/Support/Dwarf.h). Called \a DebugNode because it's -/// potentially used for non-DWARF output. -class DebugNode : public MDNode { - friend class LLVMContextImpl; - friend class MDNode; - -protected: - DebugNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, - ArrayRef Ops1, ArrayRef Ops2 = None) - : MDNode(C, ID, Storage, Ops1, Ops2) { - assert(Tag < 1u << 16); - SubclassData16 = Tag; - } - ~DebugNode() {} - -public: - unsigned getTag() const { return SubclassData16; } - - static bool classof(const Metadata *MD) { - return MD->getMetadataID() == GenericDebugNodeKind; - } -}; - -/// \brief Generic tagged DWARF-like metadata node. -/// -/// An un-specialized DWARF-like metadata node. The first operand is a -/// (possibly empty) null-separated \a MDString header that contains arbitrary -/// fields. The remaining operands are \a dwarf_operands(), and are pointers -/// to other metadata. -class GenericDebugNode : public DebugNode { - friend class LLVMContextImpl; - friend class MDNode; - - GenericDebugNode(LLVMContext &C, StorageType Storage, unsigned Hash, - unsigned Tag, ArrayRef Ops1, - ArrayRef Ops2) - : DebugNode(C, GenericDebugNodeKind, Storage, Tag, Ops1, Ops2) { - setHash(Hash); - } - ~GenericDebugNode() { dropAllReferences(); } - - void setHash(unsigned Hash) { SubclassData32 = Hash; } - void recalculateHash(); - - static GenericDebugNode *getImpl(LLVMContext &Context, unsigned Tag, - StringRef Header, - ArrayRef DwarfOps, - StorageType Storage, - bool ShouldCreate = true); - - TempGenericDebugNode cloneImpl() const { - return getTemporary( - getContext(), getTag(), getHeader(), - SmallVector(dwarf_op_begin(), dwarf_op_end())); - } - -public: - unsigned getHash() const { return SubclassData32; } - - static GenericDebugNode *get(LLVMContext &Context, unsigned Tag, - StringRef Header, - ArrayRef DwarfOps) { - return getImpl(Context, Tag, Header, DwarfOps, Uniqued); - } - static GenericDebugNode *getIfExists(LLVMContext &Context, unsigned Tag, - StringRef Header, - ArrayRef DwarfOps) { - return getImpl(Context, Tag, Header, DwarfOps, Uniqued, - /* ShouldCreate */ false); - } - static GenericDebugNode *getDistinct(LLVMContext &Context, unsigned Tag, - StringRef Header, - ArrayRef DwarfOps) { - return getImpl(Context, Tag, Header, DwarfOps, Distinct); - } - static TempGenericDebugNode getTemporary(LLVMContext &Context, unsigned Tag, - StringRef Header, - ArrayRef DwarfOps) { - return TempGenericDebugNode( - getImpl(Context, Tag, Header, DwarfOps, Temporary)); - } - - /// \brief Return a (temporary) clone of this. - TempGenericDebugNode clone() const { return cloneImpl(); } - - unsigned getTag() const { return SubclassData16; } - StringRef getHeader() const { - if (auto *S = cast_or_null(getOperand(0))) - return S->getString(); - return StringRef(); - } - - op_iterator dwarf_op_begin() const { return op_begin() + 1; } - op_iterator dwarf_op_end() const { return op_end(); } - op_range dwarf_operands() const { - return op_range(dwarf_op_begin(), dwarf_op_end()); - } - - unsigned getNumDwarfOperands() const { return getNumOperands() - 1; } - const MDOperand &getDwarfOperand(unsigned I) const { - return getOperand(I + 1); - } - void replaceDwarfOperandWith(unsigned I, Metadata *New) { - replaceOperandWith(I + 1, New); - } - - static bool classof(const Metadata *MD) { - return MD->getMetadataID() == GenericDebugNodeKind; - } -}; - //===----------------------------------------------------------------------===// /// \brief A tuple of MDNodes. /// diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 0ad921ae4be..2ae869a7f77 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -16,6 +16,7 @@ #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 0af344ab557..d2ee73f61cc 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -15,6 +15,7 @@ #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/InlineAsm.h" diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 118edc15ce6..2f1c74ae01d 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -17,6 +17,7 @@ #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index bd623210a5b..2a7916b6da0 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" diff --git a/lib/IR/CMakeLists.txt b/lib/IR/CMakeLists.txt index 1a210e05827..6e3deaef20b 100644 --- a/lib/IR/CMakeLists.txt +++ b/lib/IR/CMakeLists.txt @@ -11,6 +11,7 @@ add_llvm_library(LLVMCore DIBuilder.cpp DataLayout.cpp DebugInfo.cpp + DebugInfoMetadata.cpp DebugLoc.cpp DiagnosticInfo.cpp DiagnosticPrinter.cpp diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp new file mode 100644 index 00000000000..9daf7857ba6 --- /dev/null +++ b/lib/IR/DebugInfoMetadata.cpp @@ -0,0 +1,101 @@ +//===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the debug info Metadata classes. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/DebugInfoMetadata.h" +#include "LLVMContextImpl.h" +#include "MetadataImpl.h" + +using namespace llvm; + +MDLocation::MDLocation(LLVMContext &C, StorageType Storage, unsigned Line, + unsigned Column, ArrayRef MDs) + : MDNode(C, MDLocationKind, Storage, MDs) { + assert((MDs.size() == 1 || MDs.size() == 2) && + "Expected a scope and optional inlined-at"); + + // Set line and column. + assert(Line < (1u << 24) && "Expected 24-bit line"); + assert(Column < (1u << 16) && "Expected 16-bit column"); + + SubclassData32 = Line; + SubclassData16 = Column; +} + +static void adjustLine(unsigned &Line) { + // Set to unknown on overflow. Still use 24 bits for now. + if (Line >= (1u << 24)) + Line = 0; +} + +static void adjustColumn(unsigned &Column) { + // Set to unknown on overflow. We only have 16 bits to play with here. + if (Column >= (1u << 16)) + Column = 0; +} + +MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line, + unsigned Column, Metadata *Scope, + Metadata *InlinedAt, StorageType Storage, + bool ShouldCreate) { + // Fixup line/column. + adjustLine(Line); + adjustColumn(Column); + + if (Storage == Uniqued) { + if (auto *N = + getUniqued(Context.pImpl->MDLocations, + MDLocationInfo::KeyTy(Line, Column, Scope, InlinedAt))) + return N; + if (!ShouldCreate) + return nullptr; + } else { + assert(ShouldCreate && "Expected non-uniqued nodes to always be created"); + } + + SmallVector Ops; + Ops.push_back(Scope); + if (InlinedAt) + Ops.push_back(InlinedAt); + return storeImpl(new (Ops.size()) + MDLocation(Context, Storage, Line, Column, Ops), + Storage, Context.pImpl->MDLocations); +} + +GenericDebugNode *GenericDebugNode::getImpl(LLVMContext &Context, unsigned Tag, + StringRef Header, + ArrayRef DwarfOps, + StorageType Storage, + bool ShouldCreate) { + unsigned Hash = 0; + if (Storage == Uniqued) { + GenericDebugNodeInfo::KeyTy Key(Tag, Header, DwarfOps); + if (auto *N = getUniqued(Context.pImpl->GenericDebugNodes, Key)) + return N; + if (!ShouldCreate) + return nullptr; + Hash = Key.getHash(); + } else { + assert(ShouldCreate && "Expected non-uniqued nodes to always be created"); + } + + // Use a nullptr for empty headers. + Metadata *PreOps[] = {Header.empty() ? nullptr + : MDString::get(Context, Header)}; + return storeImpl(new (DwarfOps.size() + 1) GenericDebugNode( + Context, Storage, Hash, Tag, PreOps, DwarfOps), + Storage, Context.pImpl->GenericDebugNodes); +} + +void GenericDebugNode::recalculateHash() { + setHash(GenericDebugNodeInfo::KeyTy::calculateHash(this)); +} diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index e4e9f8f2a45..8ed4e99646b 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -27,6 +27,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp index c06d36e1507..6227c209352 100644 --- a/lib/IR/Metadata.cpp +++ b/lib/IR/Metadata.cpp @@ -13,6 +13,7 @@ #include "llvm/IR/Metadata.h" #include "LLVMContextImpl.h" +#include "MetadataImpl.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" @@ -20,6 +21,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/ConstantRange.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" @@ -541,10 +543,6 @@ void MDTuple::recalculateHash() { setHash(MDTupleInfo::KeyTy::calculateHash(this)); } -void GenericDebugNode::recalculateHash() { - setHash(GenericDebugNodeInfo::KeyTy::calculateHash(this)); -} - void MDNode::dropAllReferences() { for (unsigned I = 0, E = NumOperands; I != E; ++I) setOperand(I, nullptr); @@ -615,13 +613,6 @@ void MDNode::deleteAsSubclass() { } } -template -static T *getUniqued(DenseSet &Store, - const typename InfoT::KeyTy &Key) { - auto I = Store.find_as(Key); - return I == Store.end() ? nullptr : *I; -} - template static T *uniquifyImpl(T *N, DenseSet &Store) { if (T *U = getUniqued(Store, N)) @@ -672,21 +663,6 @@ void MDNode::eraseFromStore() { } } -template -T *MDNode::storeImpl(T *N, StorageType Storage, StoreT &Store) { - switch (Storage) { - case Uniqued: - Store.insert(N); - break; - case Distinct: - N->storeDistinctInContext(); - break; - case Temporary: - break; - } - return N; -} - MDTuple *MDTuple::getImpl(LLVMContext &Context, ArrayRef MDs, StorageType Storage, bool ShouldCreate) { unsigned Hash = 0; @@ -705,85 +681,6 @@ MDTuple *MDTuple::getImpl(LLVMContext &Context, ArrayRef MDs, Storage, Context.pImpl->MDTuples); } -MDLocation::MDLocation(LLVMContext &C, StorageType Storage, unsigned Line, - unsigned Column, ArrayRef MDs) - : MDNode(C, MDLocationKind, Storage, MDs) { - assert((MDs.size() == 1 || MDs.size() == 2) && - "Expected a scope and optional inlined-at"); - - // Set line and column. - assert(Line < (1u << 24) && "Expected 24-bit line"); - assert(Column < (1u << 16) && "Expected 16-bit column"); - - SubclassData32 = Line; - SubclassData16 = Column; -} - -static void adjustLine(unsigned &Line) { - // Set to unknown on overflow. Still use 24 bits for now. - if (Line >= (1u << 24)) - Line = 0; -} - -static void adjustColumn(unsigned &Column) { - // Set to unknown on overflow. We only have 16 bits to play with here. - if (Column >= (1u << 16)) - Column = 0; -} - -MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line, - unsigned Column, Metadata *Scope, - Metadata *InlinedAt, StorageType Storage, - bool ShouldCreate) { - // Fixup line/column. - adjustLine(Line); - adjustColumn(Column); - - if (Storage == Uniqued) { - if (auto *N = getUniqued( - Context.pImpl->MDLocations, - MDLocationInfo::KeyTy(Line, Column, Scope, InlinedAt))) - return N; - if (!ShouldCreate) - return nullptr; - } else { - assert(ShouldCreate && "Expected non-uniqued nodes to always be created"); - } - - SmallVector Ops; - Ops.push_back(Scope); - if (InlinedAt) - Ops.push_back(InlinedAt); - return storeImpl(new (Ops.size()) - MDLocation(Context, Storage, Line, Column, Ops), - Storage, Context.pImpl->MDLocations); -} - -GenericDebugNode *GenericDebugNode::getImpl(LLVMContext &Context, unsigned Tag, - StringRef Header, - ArrayRef DwarfOps, - StorageType Storage, - bool ShouldCreate) { - unsigned Hash = 0; - if (Storage == Uniqued) { - GenericDebugNodeInfo::KeyTy Key(Tag, Header, DwarfOps); - if (auto *N = getUniqued(Context.pImpl->GenericDebugNodes, Key)) - return N; - if (!ShouldCreate) - return nullptr; - Hash = Key.getHash(); - } else { - assert(ShouldCreate && "Expected non-uniqued nodes to always be created"); - } - - // Use a nullptr for empty headers. - Metadata *PreOps[] = {Header.empty() ? nullptr - : MDString::get(Context, Header)}; - return storeImpl(new (DwarfOps.size() + 1) GenericDebugNode( - Context, Storage, Hash, Tag, PreOps, DwarfOps), - Storage, Context.pImpl->GenericDebugNodes); -} - void MDNode::deleteTemporary(MDNode *N) { assert(N->isTemporary() && "Expected temporary node"); N->replaceAllUsesWith(nullptr); diff --git a/lib/IR/MetadataImpl.h b/lib/IR/MetadataImpl.h new file mode 100644 index 00000000000..3d6ed3a0dd5 --- /dev/null +++ b/lib/IR/MetadataImpl.h @@ -0,0 +1,45 @@ +//===- MetadataImpl.h - Helpers for implementing metadata -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file has private helpers for implementing metadata types. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_METADATAIMPL_H +#define LLVM_IR_METADATAIMPL_H + +#include "llvm/ADT/DenseSet.h" + +namespace llvm { + +template +static T *getUniqued(DenseSet &Store, + const typename InfoT::KeyTy &Key) { + auto I = Store.find_as(Key); + return I == Store.end() ? nullptr : *I; +} + +template +T *MDNode::storeImpl(T *N, StorageType Storage, StoreT &Store) { + switch (Storage) { + case Uniqued: + Store.insert(N); + break; + case Distinct: + N->storeDistinctInContext(); + break; + case Temporary: + break; + } + return N; +} + +} // end namespace llvm + +#endif diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index 6b438e00939..8282017ed0e 100644 --- a/unittests/IR/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -9,6 +9,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h"