summaryrefslogtreecommitdiffstats
path: root/llvm/lib
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
commit0471abd58bf916538dc6e4e1099ddbcf0d7af820 (patch)
treeee4e23a25cd2a7834db78d1dbde345e01c4922a0 /llvm/lib
parent45281870ef126385ec4e7d838ee78cbb9b6919ea (diff)
downloadbcm5719-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')
-rw-r--r--llvm/lib/VMCore/AsmWriter.cpp9
-rw-r--r--llvm/lib/VMCore/Metadata.cpp50
-rw-r--r--llvm/lib/VMCore/Verifier.cpp10
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;
OpenPOWER on IntegriCloud