aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Metadata.h21
-rw-r--r--lib/VMCore/Metadata.cpp40
-rw-r--r--lib/VMCore/Verifier.cpp45
3 files changed, 47 insertions, 59 deletions
diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h
index 63601d2d25..7cfaeafa8f 100644
--- a/include/llvm/Metadata.h
+++ b/include/llvm/Metadata.h
@@ -27,7 +27,6 @@ class LLVMContext;
class Module;
class MetadataContextImpl;
template <typename T> class SmallVectorImpl;
-template<class PtrType, unsigned SmallSize> class SmallPtrSet;
//===----------------------------------------------------------------------===//
// MetadataBase - A base class for MDNode, MDString and NamedMDNode.
@@ -91,17 +90,20 @@ 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;
+
+ MDNodeElement *Operands;
+ unsigned NumOperands;
- static const unsigned short FunctionLocalBit = 1;
+ // 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);
- MDNodeElement *Operands;
- unsigned NumOperands;
-
protected:
explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
bool isFunctionLocal);
@@ -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<MDNode *, 32> *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 01b47d6767..c1213a3d3a 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<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/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index a1b89dedea..b7e87711ae 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<MDNode *, 32> &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<MDNode *, 32> &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<Instruction>(V))
+ ActualF = I->getParent()->getParent();
+ else if (BasicBlock *BB = dyn_cast<BasicBlock>(V))
+ ActualF = BB->getParent();
+ else if (Argument *A = dyn_cast<Argument>(V))
+ ActualF = A->getParent();
+ else if (MDNode *MD = dyn_cast<MDNode>(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<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);
+ if (!MD->isFunctionLocal()) continue;
+ SmallPtrSet<MDNode *, 32> Visited;
+ VerifyFunctionLocalMetadata(MD, CI.getParent()->getParent(), Visited);
}
switch (ID) {