diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-11-18 00:37:17 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-11-18 00:37:17 +0000 |
commit | 50846f80acea3d2e2e74d472ae22ddbae0984930 (patch) | |
tree | ea98a752c8216e1abd7fb700f337c9a34d1b0da0 /llvm/lib/IR | |
parent | 94d384e4231e5e1e511873e421fdb63b175d64f0 (diff) | |
download | bcm5719-llvm-50846f80acea3d2e2e74d472ae22ddbae0984930.tar.gz bcm5719-llvm-50846f80acea3d2e2e74d472ae22ddbae0984930.zip |
IR: Split MDNode into GenericMDNode and MDNodeFwdDecl
Split `MDNode` into two classes:
- `GenericMDNode`, which is uniquable (and for now, always starts
uniqued). Once `Metadata` is split from the `Value` hierarchy, this
class will lose the ability to RAUW itself.
- `MDNodeFwdDecl`, which is used for the "temporary" interface, is
never uniqued, and isn't managed by `LLVMContext` at all.
I've left most of the guts in `MDNode` for now, but I'll incrementally
move things to the right places (or delete the functionality, as
appropriate).
Part of PR21532.
llvm-svn: 222205
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 26 | ||||
-rw-r--r-- | llvm/lib/IR/Metadata.cpp | 67 |
3 files changed, 57 insertions, 43 deletions
diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp index cd9da0d0e08..d4239e5fa3d 100644 --- a/llvm/lib/IR/LLVMContextImpl.cpp +++ b/llvm/lib/IR/LLVMContextImpl.cpp @@ -122,13 +122,12 @@ LLVMContextImpl::~LLVMContextImpl() { // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet // and the NonUniquedMDNodes sets, so copy the values out first. - SmallVector<MDNode*, 8> MDNodes; + SmallVector<GenericMDNode *, 8> MDNodes; MDNodes.reserve(MDNodeSet.size() + NonUniquedMDNodes.size()); MDNodes.append(MDNodeSet.begin(), MDNodeSet.end()); MDNodes.append(NonUniquedMDNodes.begin(), NonUniquedMDNodes.end()); - for (SmallVectorImpl<MDNode *>::iterator I = MDNodes.begin(), - E = MDNodes.end(); I != E; ++I) - (*I)->destroy(); + for (auto &I : MDNodes) + I->destroy(); assert(MDNodeSet.empty() && NonUniquedMDNodes.empty() && "Destroying all MDNodes didn't empty the Context's sets."); diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 48343b2989e..e743ec3abc4 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -191,7 +191,7 @@ struct FunctionTypeKeyInfo { } }; -/// \brief DenseMapInfo for MDNode. +/// \brief DenseMapInfo for GenericMDNode. /// /// Note that we don't need the is-function-local bit, since that's implicit in /// the operands. @@ -203,7 +203,7 @@ struct GenericMDNodeInfo { KeyTy(ArrayRef<Value *> Ops) : Ops(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {} - KeyTy(MDNode *N, SmallVectorImpl<Value *> &Storage) { + KeyTy(GenericMDNode *N, SmallVectorImpl<Value *> &Storage) { Storage.resize(N->getNumOperands()); for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I) Storage[I] = N->getOperand(I); @@ -211,7 +211,7 @@ struct GenericMDNodeInfo { Hash = hash_combine_range(Ops.begin(), Ops.end()); } - bool operator==(const MDNode *RHS) const { + bool operator==(const GenericMDNode *RHS) const { if (RHS == getEmptyKey() || RHS == getTombstoneKey()) return false; if (Hash != RHS->getHash() || Ops.size() != RHS->getNumOperands()) @@ -222,20 +222,20 @@ struct GenericMDNodeInfo { return true; } }; - static inline MDNode *getEmptyKey() { - return DenseMapInfo<MDNode *>::getEmptyKey(); + static inline GenericMDNode *getEmptyKey() { + return DenseMapInfo<GenericMDNode *>::getEmptyKey(); } - static inline MDNode *getTombstoneKey() { - return DenseMapInfo<MDNode *>::getTombstoneKey(); + static inline GenericMDNode *getTombstoneKey() { + return DenseMapInfo<GenericMDNode *>::getTombstoneKey(); } static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; } - static unsigned getHashValue(const MDNode *U) { + static unsigned getHashValue(const GenericMDNode *U) { return U->getHash(); } - static bool isEqual(const KeyTy &LHS, const MDNode *RHS) { + static bool isEqual(const KeyTy &LHS, const GenericMDNode *RHS) { return LHS == RHS; } - static bool isEqual(const MDNode *LHS, const MDNode *RHS) { + static bool isEqual(const GenericMDNode *LHS, const GenericMDNode *RHS) { return LHS == RHS; } }; @@ -293,14 +293,14 @@ public: StringMap<MDString> MDStringCache; - DenseSet<MDNode *, GenericMDNodeInfo> MDNodeSet; + DenseSet<GenericMDNode *, GenericMDNodeInfo> MDNodeSet; // 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<MDNode*, 1> NonUniquedMDNodes; - + SmallPtrSet<GenericMDNode *, 1> NonUniquedMDNodes; + DenseMap<Type*, ConstantAggregateZero*> CAZConstants; typedef ConstantUniqueMap<ConstantArray> ArrayConstantsTy; diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index e15317445f9..3c6c846b2fe 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -108,6 +108,11 @@ void MDNodeOperand::allUsesReplacedWith(Value *NV) { /// \brief Get the MDNodeOperand's coallocated on the end of the MDNode. static MDNodeOperand *getOperandPtr(MDNode *N, unsigned Op) { + static_assert(sizeof(GenericMDNode) == sizeof(MDNode), + "Expected subclasses to have no size overhead"); + static_assert(sizeof(MDNodeFwdDecl) == sizeof(MDNode), + "Expected subclasses to have no size overhead"); + // Use <= instead of < to permit a one-past-the-end address. assert(Op <= N->getNumOperands() && "Invalid operand number"); return reinterpret_cast<MDNodeOperand*>(N + 1) + Op; @@ -118,8 +123,9 @@ void MDNode::replaceOperandWith(unsigned i, Value *Val) { replaceOperand(Op, Val); } -MDNode::MDNode(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal) - : Metadata(C, Value::MDNodeVal), Hash(0) { +MDNode::MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals, + bool isFunctionLocal) + : Metadata(C, ID), Hash(0) { NumOperands = Vals.size(); if (isFunctionLocal) @@ -137,16 +143,18 @@ MDNode::MDNode(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal) } } -/// ~MDNode - Destroy MDNode. -MDNode::~MDNode() { - assert((getSubclassDataFromValue() & DestroyFlag) != 0 && - "Not being destroyed through destroy()?"); +GenericMDNode::~GenericMDNode() { LLVMContextImpl *pImpl = getType()->getContext().pImpl; if (isNotUniqued()) { pImpl->NonUniquedMDNodes.erase(this); } else { pImpl->MDNodeSet.erase(this); } +} + +MDNode::~MDNode() { + assert((getSubclassDataFromValue() & DestroyFlag) != 0 && + "Not being destroyed through destroy()?"); // Destroy the operands. for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands; @@ -209,10 +217,17 @@ const Function *MDNode::getFunction() const { } // destroy - Delete this node. Only when there are no uses. -void MDNode::destroy() { +void GenericMDNode::destroy() { + setValueSubclassData(getSubclassDataFromValue() | DestroyFlag); + // Placement delete, then free the memory. + this->~GenericMDNode(); + free(this); +} + +void MDNodeFwdDecl::destroy() { setValueSubclassData(getSubclassDataFromValue() | DestroyFlag); // Placement delete, then free the memory. - this->~MDNode(); + this->~MDNodeFwdDecl(); free(this); } @@ -253,8 +268,9 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals, } // Coallocate space for the node and Operands together, then placement new. - void *Ptr = malloc(sizeof(MDNode) + Vals.size() * sizeof(MDNodeOperand)); - MDNode *N = new (Ptr) MDNode(Context, Vals, isFunctionLocal); + void *Ptr = + malloc(sizeof(GenericMDNode) + Vals.size() * sizeof(MDNodeOperand)); + GenericMDNode *N = new (Ptr) GenericMDNode(Context, Vals, isFunctionLocal); N->Hash = Key.Hash; Store.insert(N); @@ -276,9 +292,9 @@ MDNode *MDNode::getIfExists(LLVMContext &Context, ArrayRef<Value*> Vals) { } MDNode *MDNode::getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals) { - MDNode *N = - (MDNode *)malloc(sizeof(MDNode) + Vals.size() * sizeof(MDNodeOperand)); - N = new (N) MDNode(Context, Vals, FL_No); + MDNode *N = (MDNode *)malloc(sizeof(MDNodeFwdDecl) + + Vals.size() * sizeof(MDNodeOperand)); + N = new (N) MDNodeFwdDecl(Context, Vals, FL_No); N->setValueSubclassData(N->getSubclassDataFromValue() | NotUniquedBit); LeakDetector::addGarbageObject(N); @@ -287,16 +303,13 @@ MDNode *MDNode::getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals) { void MDNode::deleteTemporary(MDNode *N) { assert(N->use_empty() && "Temporary MDNode has uses!"); - assert(!N->getContext().pImpl->MDNodeSet.erase(N) && - "Deleting a non-temporary uniqued node!"); - assert(!N->getContext().pImpl->NonUniquedMDNodes.erase(N) && - "Deleting a non-temporary non-uniqued node!"); + assert(isa<MDNodeFwdDecl>(N) && "Expected forward declaration"); assert((N->getSubclassDataFromValue() & NotUniquedBit) && "Temporary MDNode does not have NotUniquedBit set!"); assert((N->getSubclassDataFromValue() & DestroyFlag) == 0 && "Temporary MDNode has DestroyFlag set!"); LeakDetector::removeGarbageObject(N); - N->destroy(); + cast<MDNodeFwdDecl>(N)->destroy(); } /// \brief Return specified operand. @@ -308,8 +321,9 @@ Value *MDNode::getOperand(unsigned i) const { void MDNode::setIsNotUniqued() { setValueSubclassData(getSubclassDataFromValue() | NotUniquedBit); LLVMContextImpl *pImpl = getType()->getContext().pImpl; - Hash = 0; - pImpl->NonUniquedMDNodes.insert(this); + auto *G = cast<GenericMDNode>(this); + G->Hash = 0; + pImpl->NonUniquedMDNodes.insert(G); } // Replace value from this node's operand list. @@ -345,9 +359,10 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { } auto &Store = getContext().pImpl->MDNodeSet; + auto *N = cast<GenericMDNode>(this); // Remove "this" from the context map. - Store.erase(this); + Store.erase(N); // Update the operand. Op->set(To); @@ -365,16 +380,16 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { // check to see if another node with the same operands already exists in the // set. If so, then this node is redundant. SmallVector<Value *, 8> Vals; - GenericMDNodeInfo::KeyTy Key(this, Vals); + GenericMDNodeInfo::KeyTy Key(N, Vals); auto I = Store.find_as(Key); if (I != Store.end()) { - replaceAllUsesWith(*I); - destroy(); + N->replaceAllUsesWith(*I); + N->destroy(); return; } - this->Hash = Key.Hash; - Store.insert(this); + N->Hash = Key.Hash; + Store.insert(N); // If this MDValue was previously function-local but no longer is, clear // its function-local flag. |