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.
/// 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);
/// 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;
}
}
-// 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.
//
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,
}
}
+/// 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;
#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) {