diff options
Diffstat (limited to 'llvm/lib/VMCore/Metadata.cpp')
-rw-r--r-- | llvm/lib/VMCore/Metadata.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/llvm/lib/VMCore/Metadata.cpp b/llvm/lib/VMCore/Metadata.cpp index bf845eb5422..8e025b6d7a2 100644 --- a/llvm/lib/VMCore/Metadata.cpp +++ b/llvm/lib/VMCore/Metadata.cpp @@ -72,6 +72,9 @@ MDNode::MDNode(LLVMContext &C, Value*const* Vals, unsigned NumVals) // Only record metadata uses. if (MetadataBase *MB = dyn_cast_or_null<MetadataBase>(Vals[i])) OperandList[NumOperands++] = MB; + else if(Vals[i] && + Vals[i]->getType()->getTypeID() == Type::MetadataTyID) + OperandList[NumOperands++] = Vals[i]; Node.push_back(ElementVH(Vals[i], this)); } } @@ -144,6 +147,27 @@ void MDNode::replaceElement(Value *From, Value *To) { pImpl->MDNodeSet.RemoveNode(this); } + // MDNode only lists metadata elements in operand list, because MDNode + // used by MDNode is considered a valid use. However on the side, MDNode + // using a non-metadata value is not considered a "use" of non-metadata + // value. + SmallVector<unsigned, 4> OpIndexes; + unsigned OpIndex = 0; + for (User::op_iterator OI = op_begin(), OE = op_end(); + OI != OE; ++OI, OpIndex++) { + if (*OI == From) + OpIndexes.push_back(OpIndex); + } + if (MetadataBase *MDTo = dyn_cast_or_null<MetadataBase>(To)) { + for (SmallVector<unsigned, 4>::iterator OI = OpIndexes.begin(), + OE = OpIndexes.end(); OI != OE; ++OI) + setOperand(*OI, MDTo); + } else { + for (SmallVector<unsigned, 4>::iterator OI = OpIndexes.begin(), + OE = OpIndexes.end(); OI != OE; ++OI) + setOperand(*OI, 0); + } + // Replace From element(s) in place. for (SmallVector<unsigned, 4>::iterator I = Indexes.begin(), E = Indexes.end(); I != E; ++I) { |