summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Hernandez <vhernandez@apple.com>2009-12-18 20:09:14 +0000
committerVictor Hernandez <vhernandez@apple.com>2009-12-18 20:09:14 +0000
commit5d3016215075c52766711e741ce5401ee891d4ac (patch)
treebde7ea2658c9ec0f555730d5fe4a65b9f2f04a81
parent1edcafe10f05ba17dd1fbf36713fb40f98eca03a (diff)
downloadllvm-5d3016215075c52766711e741ce5401ee891d4ac.tar.gz
llvm-5d3016215075c52766711e741ce5401ee891d4ac.tar.bz2
llvm-5d3016215075c52766711e741ce5401ee891d4ac.tar.xz
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(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91708 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Metadata.h24
-rw-r--r--lib/VMCore/AsmWriter.cpp9
-rw-r--r--lib/VMCore/Metadata.cpp50
-rw-r--r--lib/VMCore/Verifier.cpp10
4 files changed, 76 insertions, 17 deletions
diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h
index 32c7fad203..fd8ea0c13b 100644
--- a/include/llvm/Metadata.h
+++ b/include/llvm/Metadata.h
@@ -19,6 +19,7 @@
#include "llvm/Value.h"
#include "llvm/Type.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/Support/ValueHandle.h"
@@ -106,21 +107,22 @@ class MDNode : public MetadataBase, public FoldingSetNode {
Parent->replaceElement(this->operator Value*(), NV);
}
};
+
+ 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);
ElementVH *Node;
unsigned NodeSize;
- Function *LocalFunction;
protected:
explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
- Function *LocalFunc = NULL);
+ bool isFunctionLocal);
public:
// Constructors and destructors.
- static MDNode *get(LLVMContext &Context,
- Value *const *Vals, unsigned NumVals,
- Function *LocalFunction = NULL);
+ static MDNode *get(LLVMContext &Context, Value *const *Vals, unsigned NumVals,
+ bool isFunctionLocal = false);
/// ~MDNode - Destroy MDNode.
~MDNode();
@@ -135,7 +137,17 @@ public:
unsigned getNumElements() const { return NodeSize; }
/// isFunctionLocal - Return whether MDNode is local to a function.
- bool isFunctionLocal() const { return LocalFunction; }
+ /// Note: MDNodes are designated as function-local when created, and keep
+ /// that designation even if their operands are modified to no longer
+ /// 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
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index c765d968fc..13905ea190 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/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/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index ac91a40e10..ba89e09ae5 100644
--- a/lib/VMCore/Metadata.cpp
+++ b/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/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 7aa86b776c..a1b89dedea 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/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;