diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-01-12 20:09:34 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-01-12 20:09:34 +0000 |
commit | ae9e15f9145ea6da81c297ac01dd42d1330c52ad (patch) | |
tree | 90cfdebf35f836ee8745a08649291e6bee7bada0 /lib/IR | |
parent | 2d88dc293bd5209ceb4ccb61a41d53a23cc09f20 (diff) |
IR: Split GenericMDNode into MDTuple and UniquableMDNode
Split `GenericMDNode` into two classes (with more descriptive names).
- `UniquableMDNode` will be a common subclass for `MDNode`s that are
sometimes uniqued like constants, and sometimes 'distinct'.
This class gets the (short-lived) RAUW support and related API.
- `MDTuple` is the basic tuple that has always been returned by
`MDNode::get()`. This is as opposed to more specific nodes to be
added soon, which have additional fields, custom assembly syntax,
and extra semantics.
This class gets the hash-related logic, since other sublcasses of
`UniquableMDNode` may need to hash based on other fields.
To keep this diff from getting too big, I've added casts to `MDTuple`
that won't really scale as new subclasses of `UniquableMDNode` are
added, but I'll clean those up incrementally.
(No functionality change intended.)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225682 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r-- | lib/IR/DIBuilder.cpp | 5 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.cpp | 20 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.h | 28 | ||||
-rw-r--r-- | lib/IR/Metadata.cpp | 75 | ||||
-rw-r--r-- | lib/IR/MetadataTracking.cpp | 4 |
5 files changed, 68 insertions, 64 deletions
diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index 6485ca5a003..856bb3c3375 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -55,7 +55,8 @@ DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes) AllowUnresolvedNodes(AllowUnresolvedNodes) {} static bool isUnresolved(MDNode *N) { - return N && (isa<MDNodeFwdDecl>(N) || !cast<GenericMDNode>(N)->isResolved()); + return N && + (isa<MDNodeFwdDecl>(N) || !cast<UniquableMDNode>(N)->isResolved()); } void DIBuilder::trackIfUnresolved(MDNode *N) { @@ -110,7 +111,7 @@ void DIBuilder::finalize() { // cycles. for (const auto &N : UnresolvedNodes) if (N) - cast<GenericMDNode>(N)->resolveCycles(); + cast<UniquableMDNode>(N)->resolveCycles(); UnresolvedNodes.clear(); // Can't handle unresolved nodes anymore. diff --git a/lib/IR/LLVMContextImpl.cpp b/lib/IR/LLVMContextImpl.cpp index 7c34f0949a4..a9268b46488 100644 --- a/lib/IR/LLVMContextImpl.cpp +++ b/lib/IR/LLVMContextImpl.cpp @@ -135,17 +135,17 @@ LLVMContextImpl::~LLVMContextImpl() { for (auto &Pair : ValuesAsMetadata) delete Pair.second; - // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet - // and the NonUniquedMDNodes sets, so copy the values out first. - SmallVector<GenericMDNode *, 8> MDNodes; - MDNodes.reserve(MDNodeSet.size() + NonUniquedMDNodes.size()); - MDNodes.append(MDNodeSet.begin(), MDNodeSet.end()); - MDNodes.append(NonUniquedMDNodes.begin(), NonUniquedMDNodes.end()); - for (GenericMDNode *I : MDNodes) + // Destroy MDNodes. ~MDNode can move and remove nodes between the MDTuples + // and the DistinctMDNodes sets, so copy the values out first. + SmallVector<UniquableMDNode *, 8> Uniquables; + Uniquables.reserve(MDTuples.size() + DistinctMDNodes.size()); + Uniquables.append(MDTuples.begin(), MDTuples.end()); + Uniquables.append(DistinctMDNodes.begin(), DistinctMDNodes.end()); + for (UniquableMDNode *I : Uniquables) I->dropAllReferences(); - for (GenericMDNode *I : MDNodes) - delete I; - assert(MDNodeSet.empty() && NonUniquedMDNodes.empty() && + for (UniquableMDNode *I : Uniquables) + delete cast<MDTuple>(I); + assert(MDTuples.empty() && DistinctMDNodes.empty() && "Destroying all MDNodes didn't empty the Context's sets."); // Destroy MDStrings. diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index a9de5c78822..11b8d38f9af 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -166,11 +166,11 @@ struct FunctionTypeKeyInfo { } }; -/// \brief DenseMapInfo for GenericMDNode. +/// \brief DenseMapInfo for MDTuple. /// /// Note that we don't need the is-function-local bit, since that's implicit in /// the operands. -struct GenericMDNodeInfo { +struct MDTupleInfo { struct KeyTy { ArrayRef<Metadata *> RawOps; ArrayRef<MDOperand> Ops; @@ -179,10 +179,10 @@ struct GenericMDNodeInfo { KeyTy(ArrayRef<Metadata *> Ops) : RawOps(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {} - KeyTy(GenericMDNode *N) + KeyTy(MDTuple *N) : Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {} - bool operator==(const GenericMDNode *RHS) const { + bool operator==(const MDTuple *RHS) const { if (RHS == getEmptyKey() || RHS == getTombstoneKey()) return false; if (Hash != RHS->getHash()) @@ -191,26 +191,26 @@ struct GenericMDNodeInfo { return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS); } template <class T> - static bool compareOps(ArrayRef<T> Ops, const GenericMDNode *RHS) { + static bool compareOps(ArrayRef<T> Ops, const MDTuple *RHS) { if (Ops.size() != RHS->getNumOperands()) return false; return std::equal(Ops.begin(), Ops.end(), RHS->op_begin()); } }; - static inline GenericMDNode *getEmptyKey() { - return DenseMapInfo<GenericMDNode *>::getEmptyKey(); + static inline MDTuple *getEmptyKey() { + return DenseMapInfo<MDTuple *>::getEmptyKey(); } - static inline GenericMDNode *getTombstoneKey() { - return DenseMapInfo<GenericMDNode *>::getTombstoneKey(); + static inline MDTuple *getTombstoneKey() { + return DenseMapInfo<MDTuple *>::getTombstoneKey(); } static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; } - static unsigned getHashValue(const GenericMDNode *U) { + static unsigned getHashValue(const MDTuple *U) { return U->getHash(); } - static bool isEqual(const KeyTy &LHS, const GenericMDNode *RHS) { + static bool isEqual(const KeyTy &LHS, const MDTuple *RHS) { return LHS == RHS; } - static bool isEqual(const GenericMDNode *LHS, const GenericMDNode *RHS) { + static bool isEqual(const MDTuple *LHS, const MDTuple *RHS) { return LHS == RHS; } }; @@ -245,13 +245,13 @@ public: DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata; DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues; - DenseSet<GenericMDNode *, GenericMDNodeInfo> MDNodeSet; + DenseSet<MDTuple *, MDTupleInfo> MDTuples; // 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 // one object can destroy them. This set allows us to at least destroy them // on Context destruction. - SmallPtrSet<GenericMDNode *, 1> NonUniquedMDNodes; + SmallPtrSet<UniquableMDNode *, 1> DistinctMDNodes; DenseMap<Type*, ConstantAggregateZero*> CAZConstants; diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp index 859512db001..282ea49aa41 100644 --- a/lib/IR/Metadata.cpp +++ b/lib/IR/Metadata.cpp @@ -222,8 +222,8 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) { if (Owner.is<MetadataAsValue *>()) continue; - // Resolve GenericMDNodes that point at this. - auto *OwnerMD = dyn_cast<GenericMDNode>(Owner.get<Metadata *>()); + // Resolve UniquableMDNodes that point at this. + auto *OwnerMD = dyn_cast<UniquableMDNode>(Owner.get<Metadata *>()); if (!OwnerMD) continue; if (OwnerMD->isResolved()) @@ -400,7 +400,7 @@ MDNode::MDNode(LLVMContext &Context, unsigned ID, ArrayRef<Metadata *> MDs) bool MDNode::isResolved() const { if (isa<MDNodeFwdDecl>(this)) return false; - return cast<GenericMDNode>(this)->isResolved(); + return cast<UniquableMDNode>(this)->isResolved(); } static bool isOperandUnresolved(Metadata *Op) { @@ -409,9 +409,9 @@ static bool isOperandUnresolved(Metadata *Op) { return false; } -GenericMDNode::GenericMDNode(LLVMContext &C, ArrayRef<Metadata *> Vals, - bool AllowRAUW) - : MDNode(C, GenericMDNodeKind, Vals) { +UniquableMDNode::UniquableMDNode(LLVMContext &C, unsigned ID, + ArrayRef<Metadata *> Vals, bool AllowRAUW) + : MDNode(C, ID, Vals) { if (!AllowRAUW) return; @@ -427,16 +427,14 @@ GenericMDNode::GenericMDNode(LLVMContext &C, ArrayRef<Metadata *> Vals, SubclassData32 = NumUnresolved; } -GenericMDNode::~GenericMDNode() { - LLVMContextImpl *pImpl = getContext().pImpl; +UniquableMDNode::~UniquableMDNode() { if (isStoredDistinctInContext()) - pImpl->NonUniquedMDNodes.erase(this); - else - pImpl->MDNodeSet.erase(this); + getContext().pImpl->DistinctMDNodes.erase(this); + dropAllReferences(); } -void GenericMDNode::resolve() { +void UniquableMDNode::resolve() { assert(!isResolved() && "Expected this to be unresolved"); // Move the map, so that this immediately looks resolved. @@ -448,7 +446,7 @@ void GenericMDNode::resolve() { Uses->resolveAllUses(); } -void GenericMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) { +void UniquableMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) { assert(SubclassData32 != 0 && "Expected unresolved operands"); // Check if an operand was resolved. @@ -458,13 +456,13 @@ void GenericMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) { decrementUnresolvedOperandCount(); } -void GenericMDNode::decrementUnresolvedOperandCount() { +void UniquableMDNode::decrementUnresolvedOperandCount() { if (!--SubclassData32) // Last unresolved operand has just been resolved. resolve(); } -void GenericMDNode::resolveCycles() { +void UniquableMDNode::resolveCycles() { if (isResolved()) return; @@ -477,13 +475,18 @@ void GenericMDNode::resolveCycles() { continue; assert(!isa<MDNodeFwdDecl>(Op) && "Expected all forward declarations to be resolved"); - if (auto *N = dyn_cast<GenericMDNode>(Op)) + if (auto *N = dyn_cast<UniquableMDNode>(Op)) if (!N->isResolved()) N->resolveCycles(); } } -void GenericMDNode::recalculateHash() { +MDTuple::~MDTuple() { + if (!isStoredDistinctInContext()) + getContext().pImpl->MDTuples.erase(this); +} + +void MDTuple::recalculateHash() { setHash(hash_combine_range(op_begin(), op_end())); #ifndef NDEBUG { @@ -498,10 +501,10 @@ void GenericMDNode::recalculateHash() { void MDNode::dropAllReferences() { for (unsigned I = 0, E = NumOperands; I != E; ++I) setOperand(I, nullptr); - if (auto *G = dyn_cast<GenericMDNode>(this)) - if (!G->isResolved()) { - G->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false); - G->ReplaceableUses.reset(); + if (auto *N = dyn_cast<UniquableMDNode>(this)) + if (!N->isResolved()) { + N->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false); + N->ReplaceableUses.reset(); } } @@ -522,7 +525,7 @@ namespace llvm { static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); } } -void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) { +void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *New) { unsigned Op = static_cast<MDOperand *>(Ref) - op_begin(); assert(Op < getNumOperands() && "Expected valid operand"); @@ -534,8 +537,8 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) { return; } - auto &Store = getContext().pImpl->MDNodeSet; - Store.erase(this); + auto &Store = getContext().pImpl->MDTuples; + Store.erase(cast<MDTuple>(this)); Metadata *Old = getOperand(Op); setOperand(Op, New); @@ -549,11 +552,11 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) { } // Re-unique the node. - recalculateHash(); - GenericMDNodeInfo::KeyTy Key(this); + cast<MDTuple>(this)->recalculateHash(); + MDTupleInfo::KeyTy Key(cast<MDTuple>(this)); auto I = Store.find_as(Key); if (I == Store.end()) { - Store.insert(this); + Store.insert(cast<MDTuple>(this)); if (!isResolved()) resolveAfterOperandChange(Old, New); @@ -570,7 +573,7 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) { for (unsigned O = 0, E = getNumOperands(); O != E; ++O) setOperand(O, nullptr); ReplaceableUses->replaceAllUsesWith(*I); - delete this; + delete cast<MDTuple>(this); return; } @@ -580,9 +583,9 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) { MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Metadata *> MDs, bool Insert) { - auto &Store = Context.pImpl->MDNodeSet; + auto &Store = Context.pImpl->MDTuples; - GenericMDNodeInfo::KeyTy Key(MDs); + MDTupleInfo::KeyTy Key(MDs); auto I = Store.find_as(Key); if (I != Store.end()) return *I; @@ -590,14 +593,14 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Metadata *> MDs, return nullptr; // Coallocate space for the node and Operands together, then placement new. - auto *N = new (MDs.size()) GenericMDNode(Context, MDs, /* AllowRAUW */ true); + auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ true); N->setHash(Key.Hash); Store.insert(N); return N; } MDNode *MDNode::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) { - auto *N = new (MDs.size()) GenericMDNode(Context, MDs, /* AllowRAUW */ false); + auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ false); N->storeDistinctInContext(); return N; } @@ -616,9 +619,9 @@ void MDNode::deleteTemporary(MDNode *N) { void MDNode::storeDistinctInContext() { assert(!IsDistinctInContext && "Expected newly distinct metadata"); IsDistinctInContext = true; - auto *G = cast<GenericMDNode>(this); - G->setHash(0); - getContext().pImpl->NonUniquedMDNodes.insert(G); + auto *T = cast<MDTuple>(this); + T->setHash(0); + getContext().pImpl->DistinctMDNodes.insert(T); } void MDNode::replaceOperandWith(unsigned I, Metadata *New) { @@ -630,7 +633,7 @@ void MDNode::replaceOperandWith(unsigned I, Metadata *New) { return; } - cast<GenericMDNode>(this)->handleChangedOperand(mutable_begin() + I, New); + cast<UniquableMDNode>(this)->handleChangedOperand(mutable_begin() + I, New); } void MDNode::setOperand(unsigned I, Metadata *New) { diff --git a/lib/IR/MetadataTracking.cpp b/lib/IR/MetadataTracking.cpp index 5b4b55586a9..ba97ca033a4 100644 --- a/lib/IR/MetadataTracking.cpp +++ b/lib/IR/MetadataTracking.cpp @@ -18,8 +18,8 @@ using namespace llvm; ReplaceableMetadataImpl *ReplaceableMetadataImpl::get(Metadata &MD) { if (auto *N = dyn_cast<MDNode>(&MD)) { - if (auto *G = dyn_cast<GenericMDNode>(N)) - return G->ReplaceableUses.get(); + if (auto *U = dyn_cast<UniquableMDNode>(N)) + return U->ReplaceableUses.get(); return cast<MDNodeFwdDecl>(N); } return dyn_cast<ValueAsMetadata>(&MD); |