aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2009-09-04 21:32:05 +0000
committerDevang Patel <dpatel@apple.com>2009-09-04 21:32:05 +0000
commit68f195cc50a8b7722004c8f3ca3dcf624b524552 (patch)
tree83bbb57d4c4205218fb60647ab2ff46990ceb2bd /lib
parent31dcbc3b4a1dea7351af5e8c08285c91049ab2c3 (diff)
downloadexternal_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.cpp7
-rw-r--r--lib/VMCore/Metadata.cpp24
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) {