<br><br><div class="gmail_quote">On Mon Nov 17 2014 at 4:45:03 PM Duncan P. N. Exon Smith <<a href="mailto:dexonsmith@apple.com">dexonsmith@apple.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dexonsmith<br>
Date: Mon Nov 17 18:37:17 2014<br>
New Revision: 222205<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=222205&view=rev" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project?rev=222205&view=rev</a><br>
Log:<br>
IR: Split MDNode into GenericMDNode and MDNodeFwdDecl<br>
<br></blockquote><div><br></div><div>Small bikeshedding:</div><div><br></div><div><span style="font-size:13.3333339691162px">Replaceable</span>NDNode maybe?</div><div> </div><div>Best name I've been able to come up with so far.</div><div><br></div><div>-eric</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Split `MDNode` into two classes:<br>
<br>
- `GenericMDNode`, which is uniquable (and for now, always starts<br>
uniqued). Once `Metadata` is split from the `Value` hierarchy, this<br>
class will lose the ability to RAUW itself.<br>
<br>
- `MDNodeFwdDecl`, which is used for the "temporary" interface, is<br>
never uniqued, and isn't managed by `LLVMContext` at all.<br>
<br>
I've left most of the guts in `MDNode` for now, but I'll incrementally<br>
move things to the right places (or delete the functionality, as<br>
appropriate).<br>
<br>
Part of PR21532.<br>
<br>
Modified:<br>
llvm/trunk/include/llvm/IR/<u></u>Metadata.h<br>
llvm/trunk/include/llvm/IR/<u></u>Value.h<br>
llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp<br>
llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h<br>
llvm/trunk/lib/IR/Metadata.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>Metadata.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=222205&r1=222204&r2=222205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/Metadata.h?rev=222205&<u></u>r1=222204&r2=222205&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>Metadata.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>Metadata.h Mon Nov 17 18:37:17 2014<br>
@@ -45,7 +45,9 @@ protected:<br>
<br>
public:<br>
static bool classof(const Value *V) {<br>
- return V->getValueID() == MDNodeVal || V->getValueID() == MDStringVal;<br>
+ return V->getValueID() == GenericMDNodeVal ||<br>
+ V->getValueID() == MDNodeFwdDeclVal ||<br>
+ V->getValueID() == MDStringVal;<br>
}<br>
};<br>
<br>
@@ -137,14 +139,16 @@ struct DenseMapInfo<AAMDNodes> {<br>
class MDNodeOperand;<br>
<br>
//===-------------------------<u></u>------------------------------<u></u>---------------===//<br>
-/// \brief Generic tuple of metadata.<br>
+/// \brief Tuple of metadata.<br>
class MDNode : public Metadata {<br>
MDNode(const MDNode &) LLVM_DELETED_FUNCTION;<br>
void operator=(const MDNode &) LLVM_DELETED_FUNCTION;<br>
friend class MDNodeOperand;<br>
friend class LLVMContextImpl;<br>
<br>
- /// \brief If the MDNode is uniqued cache the hash to speed up lookup.<br>
+protected:<br>
+ // TODO: Sink this into GenericMDNode. Can't do this until operands are<br>
+ // allocated at the front (currently they're at the back).<br>
unsigned Hash;<br>
<br>
/// \brief Subclass data enums.<br>
@@ -174,7 +178,8 @@ class MDNode : public Metadata {<br>
void replaceOperand(MDNodeOperand *Op, Value *NewVal);<br>
~MDNode();<br>
<br>
- MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal);<br>
+ MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,<br>
+ bool isFunctionLocal);<br>
<br>
static MDNode *getMDNode(LLVMContext &C, ArrayRef<Value*> Vals,<br>
FunctionLocalness FL, bool Insert = true);<br>
@@ -223,12 +228,10 @@ public:<br>
/// code because it recursively visits all the MDNode's operands.<br>
const Function *getFunction() const;<br>
<br>
- /// \brief Get the hash, if any.<br>
- unsigned getHash() const { return Hash; }<br>
-<br>
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast:<br>
static bool classof(const Value *V) {<br>
- return V->getValueID() == MDNodeVal;<br>
+ return V->getValueID() == GenericMDNodeVal ||<br>
+ V->getValueID() == MDNodeFwdDeclVal;<br>
}<br>
<br>
/// \brief Check whether MDNode is a vtable access.<br>
@@ -241,10 +244,8 @@ public:<br>
static AAMDNodes getMostGenericAA(const AAMDNodes &A, const AAMDNodes &B);<br>
static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);<br>
static MDNode *getMostGenericRange(MDNode *A, MDNode *B);<br>
-private:<br>
- /// \brief Delete this node. Only when there are no uses.<br>
- void destroy();<br>
<br>
+protected:<br>
bool isNotUniqued() const {<br>
return (getSubclassDataFromValue() & NotUniquedBit) != 0;<br>
}<br>
@@ -257,6 +258,61 @@ private:<br>
}<br>
};<br>
<br>
+/// \brief Generic metadata node.<br>
+///<br>
+/// Generic metadata nodes, with opt-out support for uniquing.<br>
+///<br>
+/// Although nodes are uniqued by default, \a GenericMDNode has no support for<br>
+/// RAUW. If an operand change (due to RAUW or otherwise) causes a uniquing<br>
+/// collision, the uniquing bit is dropped.<br>
+///<br>
+/// TODO: Make uniquing opt-out (status: mandatory, sometimes dropped).<br>
+/// TODO: Drop support for RAUW.<br>
+class GenericMDNode : public MDNode {<br>
+ friend class MDNode;<br>
+<br>
+ GenericMDNode(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)<br>
+ : MDNode(C, GenericMDNodeVal, Vals, isFunctionLocal) {}<br>
+ ~GenericMDNode();<br>
+<br>
+public:<br>
+ /// \brief Get the hash, if any.<br>
+ unsigned getHash() const { return Hash; }<br>
+<br>
+ static bool classof(const Value *V) {<br>
+ return V->getValueID() == GenericMDNodeVal;<br>
+ }<br>
+<br>
+private:<br>
+ /// \brief Delete this node. Only when there are no uses.<br>
+ void destroy();<br>
+ friend class MDNode;<br>
+ friend class LLVMContextImpl;<br>
+};<br>
+<br>
+/// \brief Forward declaration of metadata.<br>
+///<br>
+/// Forward declaration of metadata, in the form of a metadata node. Unlike \a<br>
+/// GenericMDNode, this class has support for RAUW and is suitable for forward<br>
+/// references.<br>
+class MDNodeFwdDecl : public MDNode {<br>
+ friend class MDNode;<br>
+<br>
+ MDNodeFwdDecl(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)<br>
+ : MDNode(C, MDNodeFwdDeclVal, Vals, isFunctionLocal) {}<br>
+ ~MDNodeFwdDecl() {}<br>
+<br>
+public:<br>
+ static bool classof(const Value *V) {<br>
+ return V->getValueID() == MDNodeFwdDeclVal;<br>
+ }<br>
+<br>
+private:<br>
+ /// \brief Delete this node. Only when there are no uses.<br>
+ void destroy();<br>
+ friend class MDNode;<br>
+};<br>
+<br>
//===-------------------------<u></u>------------------------------<u></u>---------------===//<br>
/// \brief A tuple of MDNodes.<br>
///<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>Value.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Value.h?rev=222205&r1=222204&r2=222205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/Value.h?rev=222205&r1=<u></u>222204&r2=222205&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>Value.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>Value.h Mon Nov 17 18:37:17 2014<br>
@@ -345,7 +345,8 @@ public:<br>
ConstantStructVal, // This is an instance of ConstantStruct<br>
ConstantVectorVal, // This is an instance of ConstantVector<br>
ConstantPointerNullVal, // This is an instance of ConstantPointerNull<br>
- MDNodeVal, // This is an instance of MDNode<br>
+ GenericMDNodeVal, // This is an instance of GenericMDNode<br>
+ MDNodeFwdDeclVal, // This is an instance of MDNodeFwdDecl<br>
MDStringVal, // This is an instance of MDString<br>
InlineAsmVal, // This is an instance of InlineAsm<br>
InstructionVal, // This is an instance of Instruction<br>
@@ -681,7 +682,8 @@ template <> struct isa_impl<GlobalObject<br>
<br>
template <> struct isa_impl<MDNode, Value> {<br>
static inline bool doit(const Value &Val) {<br>
- return Val.getValueID() == Value::MDNodeVal;<br>
+ return Val.getValueID() == Value::GenericMDNodeVal ||<br>
+ Val.getValueID() == Value::MDNodeFwdDeclVal;<br>
}<br>
};<br>
<br>
<br>
Modified: llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=222205&r1=222204&r2=222205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp?rev=<u></u>222205&r1=222204&r2=222205&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp (original)<br>
+++ llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp Mon Nov 17 18:37:17 2014<br>
@@ -122,13 +122,12 @@ LLVMContextImpl::~<u></u>LLVMContextImpl() {<br>
<br>
// Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet<br>
// and the NonUniquedMDNodes sets, so copy the values out first.<br>
- SmallVector<MDNode*, 8> MDNodes;<br>
+ SmallVector<GenericMDNode *, 8> MDNodes;<br>
MDNodes.reserve(MDNodeSet.<u></u>size() + NonUniquedMDNodes.size());<br>
MDNodes.append(MDNodeSet.<u></u>begin(), MDNodeSet.end());<br>
MDNodes.append(<u></u>NonUniquedMDNodes.begin(), NonUniquedMDNodes.end());<br>
- for (SmallVectorImpl<MDNode *>::iterator I = MDNodes.begin(),<br>
- E = MDNodes.end(); I != E; ++I)<br>
- (*I)->destroy();<br>
+ for (auto &I : MDNodes)<br>
+ I->destroy();<br>
assert(MDNodeSet.empty() && NonUniquedMDNodes.empty() &&<br>
"Destroying all MDNodes didn't empty the Context's sets.");<br>
<br>
<br>
Modified: llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=222205&r1=222204&r2=222205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h?rev=222205&<u></u>r1=222204&r2=222205&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h (original)<br>
+++ llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h Mon Nov 17 18:37:17 2014<br>
@@ -191,7 +191,7 @@ struct FunctionTypeKeyInfo {<br>
}<br>
};<br>
<br>
-/// \brief DenseMapInfo for MDNode.<br>
+/// \brief DenseMapInfo for GenericMDNode.<br>
///<br>
/// Note that we don't need the is-function-local bit, since that's implicit in<br>
/// the operands.<br>
@@ -203,7 +203,7 @@ struct GenericMDNodeInfo {<br>
KeyTy(ArrayRef<Value *> Ops)<br>
: Ops(Ops), Hash(hash_combine_range(Ops.<u></u>begin(), Ops.end())) {}<br>
<br>
- KeyTy(MDNode *N, SmallVectorImpl<Value *> &Storage) {<br>
+ KeyTy(GenericMDNode *N, SmallVectorImpl<Value *> &Storage) {<br>
Storage.resize(N-><u></u>getNumOperands());<br>
for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I)<br>
Storage[I] = N->getOperand(I);<br>
@@ -211,7 +211,7 @@ struct GenericMDNodeInfo {<br>
Hash = hash_combine_range(Ops.begin()<u></u>, Ops.end());<br>
}<br>
<br>
- bool operator==(const MDNode *RHS) const {<br>
+ bool operator==(const GenericMDNode *RHS) const {<br>
if (RHS == getEmptyKey() || RHS == getTombstoneKey())<br>
return false;<br>
if (Hash != RHS->getHash() || Ops.size() != RHS->getNumOperands())<br>
@@ -222,20 +222,20 @@ struct GenericMDNodeInfo {<br>
return true;<br>
}<br>
};<br>
- static inline MDNode *getEmptyKey() {<br>
- return DenseMapInfo<MDNode *>::getEmptyKey();<br>
+ static inline GenericMDNode *getEmptyKey() {<br>
+ return DenseMapInfo<GenericMDNode *>::getEmptyKey();<br>
}<br>
- static inline MDNode *getTombstoneKey() {<br>
- return DenseMapInfo<MDNode *>::getTombstoneKey();<br>
+ static inline GenericMDNode *getTombstoneKey() {<br>
+ return DenseMapInfo<GenericMDNode *>::getTombstoneKey();<br>
}<br>
static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; }<br>
- static unsigned getHashValue(const MDNode *U) {<br>
+ static unsigned getHashValue(const GenericMDNode *U) {<br>
return U->getHash();<br>
}<br>
- static bool isEqual(const KeyTy &LHS, const MDNode *RHS) {<br>
+ static bool isEqual(const KeyTy &LHS, const GenericMDNode *RHS) {<br>
return LHS == RHS;<br>
}<br>
- static bool isEqual(const MDNode *LHS, const MDNode *RHS) {<br>
+ static bool isEqual(const GenericMDNode *LHS, const GenericMDNode *RHS) {<br>
return LHS == RHS;<br>
}<br>
};<br>
@@ -293,14 +293,14 @@ public:<br>
<br>
StringMap<MDString> MDStringCache;<br>
<br>
- DenseSet<MDNode *, GenericMDNodeInfo> MDNodeSet;<br>
+ DenseSet<GenericMDNode *, GenericMDNodeInfo> MDNodeSet;<br>
<br>
// MDNodes may be uniqued or not uniqued. When they're not uniqued, they<br>
// aren't in the MDNodeSet, but they're still shared between objects, so no<br>
// one object can destroy them. This set allows us to at least destroy them<br>
// on Context destruction.<br>
- SmallPtrSet<MDNode*, 1> NonUniquedMDNodes;<br>
-<br>
+ SmallPtrSet<GenericMDNode *, 1> NonUniquedMDNodes;<br>
+<br>
DenseMap<Type*, ConstantAggregateZero*> CAZConstants;<br>
<br>
typedef ConstantUniqueMap<<u></u>ConstantArray> ArrayConstantsTy;<br>
<br>
Modified: llvm/trunk/lib/IR/Metadata.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=222205&r1=222204&r2=222205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/lib/IR/<u></u>Metadata.cpp?rev=222205&r1=<u></u>222204&r2=222205&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/IR/Metadata.cpp (original)<br>
+++ llvm/trunk/lib/IR/Metadata.cpp Mon Nov 17 18:37:17 2014<br>
@@ -108,6 +108,11 @@ void MDNodeOperand::<u></u>allUsesReplacedWith(<br>
<br>
/// \brief Get the MDNodeOperand's coallocated on the end of the MDNode.<br>
static MDNodeOperand *getOperandPtr(MDNode *N, unsigned Op) {<br>
+ static_assert(sizeof(<u></u>GenericMDNode) == sizeof(MDNode),<br>
+ "Expected subclasses to have no size overhead");<br>
+ static_assert(sizeof(<u></u>MDNodeFwdDecl) == sizeof(MDNode),<br>
+ "Expected subclasses to have no size overhead");<br>
+<br>
// Use <= instead of < to permit a one-past-the-end address.<br>
assert(Op <= N->getNumOperands() && "Invalid operand number");<br>
return reinterpret_cast<<u></u>MDNodeOperand*>(N + 1) + Op;<br>
@@ -118,8 +123,9 @@ void MDNode::replaceOperandWith(<u></u>unsigned<br>
replaceOperand(Op, Val);<br>
}<br>
<br>
-MDNode::MDNode(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)<br>
- : Metadata(C, Value::MDNodeVal), Hash(0) {<br>
+MDNode::MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,<br>
+ bool isFunctionLocal)<br>
+ : Metadata(C, ID), Hash(0) {<br>
NumOperands = Vals.size();<br>
<br>
if (isFunctionLocal)<br>
@@ -137,16 +143,18 @@ MDNode::MDNode(LLVMContext &C, ArrayRef<<br>
}<br>
}<br>
<br>
-/// ~MDNode - Destroy MDNode.<br>
-MDNode::~MDNode() {<br>
- assert((<u></u>getSubclassDataFromValue() & DestroyFlag) != 0 &&<br>
- "Not being destroyed through destroy()?");<br>
+GenericMDNode::~<u></u>GenericMDNode() {<br>
LLVMContextImpl *pImpl = getType()->getContext().pImpl;<br>
if (isNotUniqued()) {<br>
pImpl->NonUniquedMDNodes.<u></u>erase(this);<br>
} else {<br>
pImpl->MDNodeSet.erase(this);<br>
}<br>
+}<br>
+<br>
+MDNode::~MDNode() {<br>
+ assert((<u></u>getSubclassDataFromValue() & DestroyFlag) != 0 &&<br>
+ "Not being destroyed through destroy()?");<br>
<br>
// Destroy the operands.<br>
for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands;<br>
@@ -209,10 +217,17 @@ const Function *MDNode::getFunction() co<br>
}<br>
<br>
// destroy - Delete this node. Only when there are no uses.<br>
-void MDNode::destroy() {<br>
+void GenericMDNode::destroy() {<br>
+ setValueSubclassData(<u></u>getSubclassDataFromValue() | DestroyFlag);<br>
+ // Placement delete, then free the memory.<br>
+ this->~GenericMDNode();<br>
+ free(this);<br>
+}<br>
+<br>
+void MDNodeFwdDecl::destroy() {<br>
setValueSubclassData(<u></u>getSubclassDataFromValue() | DestroyFlag);<br>
// Placement delete, then free the memory.<br>
- this->~MDNode();<br>
+ this->~MDNodeFwdDecl();<br>
free(this);<br>
}<br>
<br>
@@ -253,8 +268,9 @@ MDNode *MDNode::getMDNode(LLVMContext &C<br>
}<br>
<br>
// Coallocate space for the node and Operands together, then placement new.<br>
- void *Ptr = malloc(sizeof(MDNode) + Vals.size() * sizeof(MDNodeOperand));<br>
- MDNode *N = new (Ptr) MDNode(Context, Vals, isFunctionLocal);<br>
+ void *Ptr =<br>
+ malloc(sizeof(GenericMDNode) + Vals.size() * sizeof(MDNodeOperand));<br>
+ GenericMDNode *N = new (Ptr) GenericMDNode(Context, Vals, isFunctionLocal);<br>
<br>
N->Hash = Key.Hash;<br>
Store.insert(N);<br>
@@ -276,9 +292,9 @@ MDNode *MDNode::getIfExists(<u></u>LLVMContext<br>
}<br>
<br>
MDNode *MDNode::getTemporary(<u></u>LLVMContext &Context, ArrayRef<Value*> Vals) {<br>
- MDNode *N =<br>
- (MDNode *)malloc(sizeof(MDNode) + Vals.size() * sizeof(MDNodeOperand));<br>
- N = new (N) MDNode(Context, Vals, FL_No);<br>
+ MDNode *N = (MDNode *)malloc(sizeof(MDNodeFwdDecl) +<br>
+ Vals.size() * sizeof(MDNodeOperand));<br>
+ N = new (N) MDNodeFwdDecl(Context, Vals, FL_No);<br>
N->setValueSubclassData(N-><u></u>getSubclassDataFromValue() |<br>
NotUniquedBit);<br>
LeakDetector::<u></u>addGarbageObject(N);<br>
@@ -287,16 +303,13 @@ MDNode *MDNode::getTemporary(<u></u>LLVMContext<br>
<br>
void MDNode::deleteTemporary(MDNode *N) {<br>
assert(N->use_empty() && "Temporary MDNode has uses!");<br>
- assert(!N->getContext().pImpl-<u></u>>MDNodeSet.erase(N) &&<br>
- "Deleting a non-temporary uniqued node!");<br>
- assert(!N->getContext().pImpl-<u></u>>NonUniquedMDNodes.erase(N) &&<br>
- "Deleting a non-temporary non-uniqued node!");<br>
+ assert(isa<MDNodeFwdDecl>(N) && "Expected forward declaration");<br>
assert((N-><u></u>getSubclassDataFromValue() & NotUniquedBit) &&<br>
"Temporary MDNode does not have NotUniquedBit set!");<br>
assert((N-><u></u>getSubclassDataFromValue() & DestroyFlag) == 0 &&<br>
"Temporary MDNode has DestroyFlag set!");<br>
LeakDetector::<u></u>removeGarbageObject(N);<br>
- N->destroy();<br>
+ cast<MDNodeFwdDecl>(N)-><u></u>destroy();<br>
}<br>
<br>
/// \brief Return specified operand.<br>
@@ -308,8 +321,9 @@ Value *MDNode::getOperand(unsigned i) co<br>
void MDNode::setIsNotUniqued() {<br>
setValueSubclassData(<u></u>getSubclassDataFromValue() | NotUniquedBit);<br>
LLVMContextImpl *pImpl = getType()->getContext().pImpl;<br>
- Hash = 0;<br>
- pImpl->NonUniquedMDNodes.<u></u>insert(this);<br>
+ auto *G = cast<GenericMDNode>(this);<br>
+ G->Hash = 0;<br>
+ pImpl->NonUniquedMDNodes.<u></u>insert(G);<br>
}<br>
<br>
// Replace value from this node's operand list.<br>
@@ -345,9 +359,10 @@ void MDNode::replaceOperand(<u></u>MDNodeOperan<br>
}<br>
<br>
auto &Store = getContext().pImpl->MDNodeSet;<br>
+ auto *N = cast<GenericMDNode>(this);<br>
<br>
// Remove "this" from the context map.<br>
- Store.erase(this);<br>
+ Store.erase(N);<br>
<br>
// Update the operand.<br>
Op->set(To);<br>
@@ -365,16 +380,16 @@ void MDNode::replaceOperand(<u></u>MDNodeOperan<br>
// check to see if another node with the same operands already exists in the<br>
// set. If so, then this node is redundant.<br>
SmallVector<Value *, 8> Vals;<br>
- GenericMDNodeInfo::KeyTy Key(this, Vals);<br>
+ GenericMDNodeInfo::KeyTy Key(N, Vals);<br>
auto I = Store.find_as(Key);<br>
if (I != Store.end()) {<br>
- replaceAllUsesWith(*I);<br>
- destroy();<br>
+ N->replaceAllUsesWith(*I);<br>
+ N->destroy();<br>
return;<br>
}<br>
<br>
- this->Hash = Key.Hash;<br>
- Store.insert(this);<br>
+ N->Hash = Key.Hash;<br>
+ Store.insert(N);<br>
<br>
// If this MDValue was previously function-local but no longer is, clear<br>
// its function-local flag.<br>
<br>
<br>
______________________________<u></u>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/llvm-commits</a><br>
</blockquote></div>