diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 61 | ||||
-rw-r--r-- | llvm/lib/IR/Metadata.cpp | 45 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/ValueMapper.cpp | 8 |
5 files changed, 110 insertions, 16 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index d9165437ec7..56355cc913c 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1286,6 +1286,12 @@ raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) { } } // end namespace +static void writeGenericDwarfNode(raw_ostream &, const GenericDwarfNode *, + TypePrinting *, SlotTracker *, + const Module *) { + llvm_unreachable("Unimplemented write"); +} + static void writeMDLocation(raw_ostream &Out, const MDLocation *DL, TypePrinting *TypePrinter, SlotTracker *Machine, const Module *Context) { diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp index 0c50a120d5d..81ff9a96f49 100644 --- a/llvm/lib/IR/LLVMContextImpl.cpp +++ b/llvm/lib/IR/LLVMContextImpl.cpp @@ -180,11 +180,11 @@ namespace llvm { static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); } } -unsigned MDNodeOpsKey::calculateHash(MDNode *N) { - unsigned Hash = hash_combine_range(N->op_begin(), N->op_end()); +unsigned MDNodeOpsKey::calculateHash(MDNode *N, unsigned Offset) { + unsigned Hash = hash_combine_range(N->op_begin() + Offset, N->op_end()); #ifndef NDEBUG { - SmallVector<Metadata *, 8> MDs(N->op_begin(), N->op_end()); + SmallVector<Metadata *, 8> MDs(N->op_begin() + Offset, N->op_end()); unsigned RawHash = calculateHash(MDs); assert(Hash == RawHash && "Expected hash of MDOperand to equal hash of Metadata*"); diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 092104f6d0e..4604d9babb5 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -179,25 +179,27 @@ protected: : RawOps(Ops), Hash(calculateHash(Ops)) {} template <class NodeTy> - MDNodeOpsKey(NodeTy *N) - : Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {} + MDNodeOpsKey(NodeTy *N, unsigned Offset = 0) + : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {} - template <class NodeTy> bool compareOps(const NodeTy *RHS) const { + template <class NodeTy> + bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const { if (getHash() != RHS->getHash()) return false; assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?"); - return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS); + return RawOps.empty() ? compareOps(Ops, RHS, Offset) + : compareOps(RawOps, RHS, Offset); } - static unsigned calculateHash(MDNode *N); + static unsigned calculateHash(MDNode *N, unsigned Offset = 0); private: template <class T> - static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS) { - if (Ops.size() != RHS->getNumOperands()) + static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) { + if (Ops.size() != RHS->getNumOperands() - Offset) return false; - return std::equal(Ops.begin(), Ops.end(), RHS->op_begin()); + return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset); } static unsigned calculateHash(ArrayRef<Metadata *> Ops); @@ -283,6 +285,48 @@ struct MDLocationInfo { } }; +/// \brief DenseMapInfo for GenericDwarfNode. +struct GenericDwarfNodeInfo { + struct KeyTy : MDNodeOpsKey { + unsigned Tag; + MDString *Header; + KeyTy(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps) + : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {} + KeyTy(GenericDwarfNode *N) + : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getHeader()) {} + + bool operator==(const GenericDwarfNode *RHS) const { + if (RHS == getEmptyKey() || RHS == getTombstoneKey()) + return false; + return Tag == RHS->getTag() && Header == RHS->getHeader() && + compareOps(RHS, 1); + } + + static unsigned calculateHash(GenericDwarfNode *N) { + return MDNodeOpsKey::calculateHash(N, 1); + } + }; + static inline GenericDwarfNode *getEmptyKey() { + return DenseMapInfo<GenericDwarfNode *>::getEmptyKey(); + } + static inline GenericDwarfNode *getTombstoneKey() { + return DenseMapInfo<GenericDwarfNode *>::getTombstoneKey(); + } + static unsigned getHashValue(const KeyTy &Key) { + return hash_combine(Key.getHash(), Key.Tag, Key.Header); + } + static unsigned getHashValue(const GenericDwarfNode *U) { + return hash_combine(U->getHash(), U->getTag(), U->getHeader()); + } + static bool isEqual(const KeyTy &LHS, const GenericDwarfNode *RHS) { + return LHS == RHS; + } + static bool isEqual(const GenericDwarfNode *LHS, + const GenericDwarfNode *RHS) { + return LHS == RHS; + } +}; + class LLVMContextImpl { public: /// OwnedModules - The set of modules instantiated in this context, and which @@ -315,6 +359,7 @@ public: DenseSet<MDTuple *, MDTupleInfo> MDTuples; DenseSet<MDLocation *, MDLocationInfo> MDLocations; + DenseSet<GenericDwarfNode *, GenericDwarfNodeInfo> GenericDwarfNodes; // MDNodes may be uniqued or not uniqued. When they're not uniqued, they // aren't in the MDNodeSet, but they're still shared between objects, so no diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index 0ce704c7c3d..5f5708565d4 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -397,11 +397,14 @@ void MDNode::operator delete(void *Mem) { } MDNode::MDNode(LLVMContext &Context, unsigned ID, StorageType Storage, - ArrayRef<Metadata *> MDs) - : Metadata(ID, Storage), NumOperands(MDs.size()), NumUnresolved(0), - Context(Context) { - for (unsigned I = 0, E = MDs.size(); I != E; ++I) - setOperand(I, MDs[I]); + ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2) + : Metadata(ID, Storage), NumOperands(Ops1.size() + Ops2.size()), + NumUnresolved(0), Context(Context) { + unsigned Op = 0; + for (Metadata *MD : Ops1) + setOperand(Op++, MD); + for (Metadata *MD : Ops2) + setOperand(Op++, MD); if (isDistinct()) return; @@ -527,6 +530,10 @@ void MDTuple::recalculateHash() { setHash(MDTupleInfo::KeyTy::calculateHash(this)); } +void GenericDwarfNode::recalculateHash() { + setHash(GenericDwarfNodeInfo::KeyTy::calculateHash(this)); +} + void MDNode::dropAllReferences() { for (unsigned I = 0, E = NumOperands; I != E; ++I) setOperand(I, nullptr); @@ -621,6 +628,9 @@ MDNode *MDNode::uniquify() { case MDTupleKind: cast<MDTuple>(this)->recalculateHash(); break; + case GenericDwarfNodeKind: + cast<GenericDwarfNode>(this)->recalculateHash(); + break; } // Try to insert into uniquing store. @@ -733,6 +743,29 @@ MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line, Storage, Context.pImpl->MDLocations); } +GenericDwarfNode *GenericDwarfNode::getImpl(LLVMContext &Context, unsigned Tag, + MDString *Header, + ArrayRef<Metadata *> DwarfOps, + StorageType Storage, + bool ShouldCreate) { + unsigned Hash = 0; + if (Storage == Uniqued) { + GenericDwarfNodeInfo::KeyTy Key(Tag, Header, DwarfOps); + if (auto *N = getUniqued(Context.pImpl->GenericDwarfNodes, Key)) + return N; + if (!ShouldCreate) + return nullptr; + Hash = Key.getHash(); + } else { + assert(ShouldCreate && "Expected non-uniqued nodes to always be created"); + } + + Metadata *PreOps[] = {Header}; + return storeImpl(new (DwarfOps.size() + 1) GenericDwarfNode( + Context, Storage, Hash, Tag, PreOps, DwarfOps), + Storage, Context.pImpl->GenericDwarfNodes); +} + void MDNode::deleteTemporary(MDNode *N) { assert(N->isTemporary() && "Expected temporary node"); N->deleteAsSubclass(); @@ -743,6 +776,8 @@ void MDNode::storeDistinctInContext() { Storage = Distinct; if (auto *T = dyn_cast<MDTuple>(this)) T->setHash(0); + else if (auto *G = dyn_cast<GenericDwarfNode>(this)) + G->setHash(0); getContext().pImpl->DistinctMDNodes.insert(this); } diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 20ce27823fb..cba4677a2b0 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -192,6 +192,14 @@ static TempMDLocation cloneMDLocation(const MDLocation *Node) { Node->getInlinedAt()); } +static TempGenericDwarfNode +cloneGenericDwarfNode(const GenericDwarfNode *Node) { + SmallVector<Metadata *, 4> DwarfOps; + DwarfOps.append(Node->dwarf_op_begin(), Node->dwarf_op_end()); + return GenericDwarfNode::getTemporary(Node->getContext(), Node->getTag(), + Node->getHeader(), DwarfOps); +} + static TempMDNode cloneMDNode(const MDNode *Node) { switch (Node->getMetadataID()) { default: |