diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index 63601d2d25f..7cfaeafa8f1 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -27,7 +27,6 @@ class LLVMContext; class Module; class MetadataContextImpl; template class SmallVectorImpl; -template class SmallPtrSet; //===----------------------------------------------------------------------===// // MetadataBase - A base class for MDNode, MDString and NamedMDNode. @@ -91,16 +90,19 @@ class MDNodeElement; /// MDNode is always unnamed. class MDNode : public MetadataBase, public FoldingSetNode { MDNode(const MDNode &); // DO NOT IMPLEMENT - + void operator=(const MDNode &); // DO NOT IMPLEMENT friend class MDNodeElement; - - static const unsigned short FunctionLocalBit = 1; - - // Replace each instance of F from the element list of this node with T. - void replaceElement(Value *F, Value *T); MDNodeElement *Operands; unsigned NumOperands; + + // Subclass data enums. + enum { + FunctionLocalBit = 1 + }; + + // Replace each instance of F from the element list of this node with T. + void replaceElement(Value *F, Value *T); protected: explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, @@ -125,13 +127,6 @@ public: /// refer to function-local IR. bool isFunctionLocal() const { return SubclassData & FunctionLocalBit; } - /// 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 getLocalFunction(Function *LocalFunction, - SmallPtrSet *VisitedMDNodes = NULL); - /// Profile - calculate a unique identifier for this MDNode to collapse /// duplicates void Profile(FoldingSetNodeID &ID) const; diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index 01b47d67679..c1213a3d3a9 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -188,46 +188,6 @@ 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 *VisitedMDNodes) { - if (!isFunctionLocal()) - return true; - - if (!VisitedMDNodes) - VisitedMDNodes = new SmallPtrSet(); - - 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(V)) - LocalFunctionTemp = I->getParent()->getParent(); - else if (MDNode *MD = dyn_cast(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/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index a1b89dedeab..b7e87711ae4 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -329,6 +329,8 @@ namespace { int VT, unsigned ArgNo, std::string &Suffix); void VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F, unsigned RetNum, unsigned ParamNum, ...); + void VerifyFunctionLocalMetadata(MDNode *N, Function *F, + SmallPtrSet &Visited); void VerifyParameterAttrs(Attributes Attrs, const Type *Ty, bool isReturnValue, const Value *V); void VerifyFunctionAttrs(const FunctionType *FT, const AttrListPtr &Attrs, @@ -1526,6 +1528,38 @@ void Verifier::VerifyType(const Type *Ty) { } } +/// VerifyFunctionLocalMetadata - Verify that the specified MDNode is local to +/// specified Function. +void Verifier::VerifyFunctionLocalMetadata(MDNode *N, Function *F, + SmallPtrSet &Visited) { + assert(N->isFunctionLocal() && "Should only be called on function-local MD"); + + // Only visit each node once. + if (!Visited.insert(N)) + return; + + for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) { + Value *V = N->getElement(i); + if (!V) continue; + + Function *ActualF = 0; + if (Instruction *I = dyn_cast(V)) + ActualF = I->getParent()->getParent(); + else if (BasicBlock *BB = dyn_cast(V)) + ActualF = BB->getParent(); + else if (Argument *A = dyn_cast(V)) + ActualF = A->getParent(); + else if (MDNode *MD = dyn_cast(V)) + if (MD->isFunctionLocal()) + VerifyFunctionLocalMetadata(MD, F, Visited); + + // If this was an instruction, bb, or argument, verify that it is in the + // function that we expect. + Assert1(ActualF == 0 || ActualF == F, + "function-local metadata used in wrong function", N); + } +} + // Flags used by TableGen to mark intrinsic parameters with the // LLVMExtendedElementVectorType and LLVMTruncatedElementVectorType classes. static const unsigned ExtendedElementVectorType = 0x40000000; @@ -1542,14 +1576,13 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_VERIFIER + // If the intrinsic takes MDNode arguments, verify that they are either global + // or are local to *this* function. for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i) if (MDNode *MD = dyn_cast(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); + if (!MD->isFunctionLocal()) continue; + SmallPtrSet Visited; + VerifyFunctionLocalMetadata(MD, CI.getParent()->getParent(), Visited); } switch (ID) {