diff options
| author | Victor Hernandez <vhernandez@apple.com> | 2009-12-18 20:09:14 +0000 |
|---|---|---|
| committer | Victor Hernandez <vhernandez@apple.com> | 2009-12-18 20:09:14 +0000 |
| commit | 0471abd58bf916538dc6e4e1099ddbcf0d7af820 (patch) | |
| tree | ee4e23a25cd2a7834db78d1dbde345e01c4922a0 /llvm/lib/VMCore | |
| parent | 45281870ef126385ec4e7d838ee78cbb9b6919ea (diff) | |
| download | bcm5719-llvm-0471abd58bf916538dc6e4e1099ddbcf0d7af820.tar.gz bcm5719-llvm-0471abd58bf916538dc6e4e1099ddbcf0d7af820.zip | |
Formalize MDNode's function-localness:
- an MDNode is designated as function-local when created, and continues to be even if its operands are modified not to refer to function-local IR
- function-localness is designated via lowest bit in SubclassData
- getLocalFunction() descends MDNode tree to see if it is consistently function-local
Add verification of MDNodes to checks that MDNodes are consistently function-local.
Update AsmWriter to use isFunctionLocal().
llvm-svn: 91708
Diffstat (limited to 'llvm/lib/VMCore')
| -rw-r--r-- | llvm/lib/VMCore/AsmWriter.cpp | 9 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Metadata.cpp | 50 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Verifier.cpp | 10 |
3 files changed, 58 insertions, 11 deletions
diff --git a/llvm/lib/VMCore/AsmWriter.cpp b/llvm/lib/VMCore/AsmWriter.cpp index c765d968fcd..13905ea1906 100644 --- a/llvm/lib/VMCore/AsmWriter.cpp +++ b/llvm/lib/VMCore/AsmWriter.cpp @@ -813,10 +813,9 @@ void SlotTracker::CreateFunctionSlot(const Value *V) { void SlotTracker::CreateMetadataSlot(const MDNode *N) { assert(N && "Can't insert a null Value into SlotTracker!"); - // Don't insert if N contains an instruction. - for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) - if (N->getElement(i) && isa<Instruction>(N->getElement(i))) - return; + // Don't insert if N is a function-local metadata. + if (N->isFunctionLocal()) + return; ValueMap::iterator I = mdnMap.find(N); if (I != mdnMap.end()) @@ -1232,7 +1231,7 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, } if (const MDNode *N = dyn_cast<MDNode>(V)) { - if (Machine->getMetadataSlot(N) == -1) { + if (N->isFunctionLocal()) { // Print metadata inline, not via slot reference number. Out << "!{"; for (unsigned mi = 0, me = N->getNumElements(); mi != me; ++mi) { diff --git a/llvm/lib/VMCore/Metadata.cpp b/llvm/lib/VMCore/Metadata.cpp index ac91a40e10d..ba89e09ae56 100644 --- a/llvm/lib/VMCore/Metadata.cpp +++ b/llvm/lib/VMCore/Metadata.cpp @@ -50,14 +50,15 @@ MDString *MDString::get(LLVMContext &Context, const char *Str) { // MDNode implementation. // MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, - Function *LocalFunc) + bool isFunctionLocal) : MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) { NodeSize = NumVals; Node = new ElementVH[NodeSize]; ElementVH *Ptr = Node; for (unsigned i = 0; i != NumVals; ++i) *Ptr++ = ElementVH(Vals[i], this); - LocalFunction = LocalFunc; + if (isFunctionLocal) + SubclassData |= FunctionLocalBit; } void MDNode::Profile(FoldingSetNodeID &ID) const { @@ -66,19 +67,17 @@ void MDNode::Profile(FoldingSetNodeID &ID) const { } MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals, - Function *LocalFunction) { + bool isFunctionLocal) { LLVMContextImpl *pImpl = Context.pImpl; FoldingSetNodeID ID; for (unsigned i = 0; i != NumVals; ++i) ID.AddPointer(Vals[i]); - if (LocalFunction) - ID.AddPointer(LocalFunction); void *InsertPoint; MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); if (!N) { // InsertPoint will have been set by the FindNodeOrInsertPos call. - N = new MDNode(Context, Vals, NumVals, LocalFunction); + N = new MDNode(Context, Vals, NumVals, isFunctionLocal); pImpl->MDNodeSet.InsertNode(N, InsertPoint); } return N; @@ -146,6 +145,45 @@ void MDNode::replaceElement(Value *From, Value *To) { } } +// getLocalFunction - Return false if MDNode's recursive function-localness is +// invalid (local to more than one function). Return true otherwise. If MDNode +// has one function to which it is local, set LocalFunction to that function. +bool MDNode::getLocalFunction(Function *LocalFunction, + SmallPtrSet<MDNode *, 32> *VisitedMDNodes) { + if (!isFunctionLocal()) + return true; + + if (!VisitedMDNodes) + VisitedMDNodes = new SmallPtrSet<MDNode *, 32>(); + + if (!VisitedMDNodes->insert(this)) + // MDNode has already been visited, nothing to do. + return true; + + for (unsigned i = 0, e = getNumElements(); i != e; ++i) { + Value *V = getElement(i); + if (!V) continue; + + Function *LocalFunctionTemp = NULL; + if (Instruction *I = dyn_cast<Instruction>(V)) + LocalFunctionTemp = I->getParent()->getParent(); + else if (MDNode *MD = dyn_cast<MDNode>(V)) + if (!MD->getLocalFunction(LocalFunctionTemp, VisitedMDNodes)) + // This MDNode's operand is function-locally invalid or local to a + // different function. + return false; + + if (LocalFunctionTemp) + if (!LocalFunction) + LocalFunction = LocalFunctionTemp; + else if (LocalFunction != LocalFunctionTemp) + // This MDNode contains operands that are local to different functions. + return false; + } + + return true; +} + //===----------------------------------------------------------------------===// // NamedMDNode implementation. // diff --git a/llvm/lib/VMCore/Verifier.cpp b/llvm/lib/VMCore/Verifier.cpp index 7aa86b776c7..a1b89dedeab 100644 --- a/llvm/lib/VMCore/Verifier.cpp +++ b/llvm/lib/VMCore/Verifier.cpp @@ -1542,6 +1542,16 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_VERIFIER + for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i) + if (MDNode *MD = dyn_cast<MDNode>(CI.getOperand(i))) { + Function* LocalFunction = NULL; + Assert1(MD && MD->getLocalFunction(LocalFunction), + "invalid function-local metadata", &CI); + if (LocalFunction) + Assert1(LocalFunction == CI.getParent()->getParent(), + "function-local metadata used in wrong function", &CI); + } + switch (ID) { default: break; |

