diff options
author | Devang Patel <dpatel@apple.com> | 2009-09-04 21:32:05 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2009-09-04 21:32:05 +0000 |
commit | 68f195cc50a8b7722004c8f3ca3dcf624b524552 (patch) | |
tree | 83bbb57d4c4205218fb60647ab2ff46990ceb2bd /lib | |
parent | 31dcbc3b4a1dea7351af5e8c08285c91049ab2c3 (diff) | |
download | external_llvm-68f195cc50a8b7722004c8f3ca3dcf624b524552.tar.gz external_llvm-68f195cc50a8b7722004c8f3ca3dcf624b524552.tar.bz2 external_llvm-68f195cc50a8b7722004c8f3ca3dcf624b524552.zip |
While replacing an MDNode elment, properly update MDNode's operand list.
MDNode's operand list does not include all elements.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81045 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/VMCore/LLVMContext.cpp | 7 | ||||
-rw-r--r-- | lib/VMCore/Metadata.cpp | 24 |
2 files changed, 28 insertions, 3 deletions
diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 887679e08d..7d233d9921 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -62,9 +62,10 @@ bool LLVMContext::RemoveDeadMetadata() { return Changed; while (!DeadMDNodes.empty()) { - const MDNode *N = cast<MDNode>(DeadMDNodes.back()); DeadMDNodes.pop_back(); - if (N->use_empty()) - delete N; + Value *V = DeadMDNodes.back(); DeadMDNodes.pop_back(); + if (const MDNode *N = dyn_cast_or_null<MDNode>(V)) + if (N->use_empty()) + delete N; } } return Changed; diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index bf845eb542..8e025b6d7a 100644 --- a/lib/VMCore/Metadata.cpp +++ b/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) { |