aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Hernandez <vhernandez@apple.com>2010-01-14 01:45:14 +0000
committerVictor Hernandez <vhernandez@apple.com>2010-01-14 01:45:14 +0000
commitc7650b4d1907becbf2ed112074fd2c4a6f174aa8 (patch)
tree6ec82961417b99323f6ad437146ab42e7d530cc3
parent069e100f9a79a63db177a521fd790f4d77d1209c (diff)
Add MDNode::getFunction(), which figures out the metadata's function, if it has function that it is local to.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93400 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Metadata.h5
-rw-r--r--lib/VMCore/Metadata.cpp34
2 files changed, 39 insertions, 0 deletions
diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h
index 84a37290f9..179010b165 100644
--- a/include/llvm/Metadata.h
+++ b/include/llvm/Metadata.h
@@ -151,6 +151,11 @@ public:
bool isFunctionLocal() const {
return (getSubclassDataFromValue() & FunctionLocalBit) != 0;
}
+
+ // getFunction - If this metadata is function-local and recursively has a
+ // function-local operand, return the first such operand's parent function.
+ // Otherwise, return null.
+ Function *getFunction() const;
// destroy - Delete this node. Only when there are no uses.
void destroy();
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index bac89bfd7b..1e767ffba6 100644
--- a/lib/VMCore/Metadata.cpp
+++ b/lib/VMCore/Metadata.cpp
@@ -121,6 +121,40 @@ MDNode::~MDNode() {
Op->~MDNodeOperand();
}
+static Function *getFunctionHelper(const MDNode *N,
+ SmallPtrSet<const MDNode *, 32> &Visited) {
+ assert(N->isFunctionLocal() && "Should only be called on function-local MD");
+ Function *F = NULL;
+ // Only visit each MDNode once.
+ if (!Visited.insert(N)) return F;
+
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+ Value *V = N->getOperand(i);
+ if (!V) continue;
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ F = I->getParent()->getParent();
+ else if (BasicBlock *BB = dyn_cast<BasicBlock>(V))
+ F = BB->getParent();
+ else if (Argument *A = dyn_cast<Argument>(V))
+ F = A->getParent();
+ else if (MDNode *MD = dyn_cast<MDNode>(V))
+ if (MD->isFunctionLocal())
+ F = getFunctionHelper(MD, Visited);
+ if (F) break;
+ }
+
+ return F;
+}
+
+// getFunction - If this metadata is function-local and recursively has a
+// function-local operand, return the first such operand's parent function.
+// Otherwise, return null.
+Function *MDNode::getFunction() const {
+ if (!isFunctionLocal()) return NULL;
+ SmallPtrSet<const MDNode *, 32> Visited;
+ return getFunctionHelper(this, Visited);
+}
+
// destroy - Delete this node. Only when there are no uses.
void MDNode::destroy() {
setValueSubclassData(getSubclassDataFromValue() | DestroyFlag);