diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index 7988b446fb6..8a40fed1cca 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -122,66 +122,59 @@ MDNode::~MDNode() { } #ifndef NDEBUG -static Function *assertLocalFunction(const MDNode *N, - SmallPtrSet &Visited) { - 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); - Function *NewF = NULL; - if (!V) continue; - if (Instruction *I = dyn_cast(V)) - NewF = I->getParent()->getParent(); - else if (BasicBlock *BB = dyn_cast(V)) - NewF = BB->getParent(); - else if (Argument *A = dyn_cast(V)) - NewF = A->getParent(); - else if (MDNode *MD = dyn_cast(V)) - if (MD->isFunctionLocal()) - NewF = assertLocalFunction(MD, Visited); - if (F && NewF) assert(F == NewF && "inconsistent function-local metadata"); - if (!F) F = NewF; - } - return F; -} -#endif +static Function *assertLocalFunction(const MDNode *N) { + if (!N->isFunctionLocal()) return NULL; -static Function *getFunctionHelper(const MDNode *N, - SmallPtrSet &Visited) { - assert(N->isFunctionLocal() && "Should only be called on function-local MD"); -#ifndef NDEBUG - return assertLocalFunction(N, Visited); -#endif 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(V)) - F = I->getParent()->getParent(); - else if (BasicBlock *BB = dyn_cast(V)) - F = BB->getParent(); - else if (Argument *A = dyn_cast(V)) - F = A->getParent(); - else if (MDNode *MD = dyn_cast(V)) - if (MD->isFunctionLocal()) - F = getFunctionHelper(MD, Visited); - if (F) break; + if (Instruction *I = dyn_cast(V)) { + if (F) assert(F == I->getParent()->getParent() && + "inconsistent function-local metadata"); + else F = I->getParent()->getParent(); + } else if (BasicBlock *BB = dyn_cast(V)) { + if (F) assert(F == BB->getParent() && + "inconsistent function-local metadata"); + else F = BB->getParent(); + } else if (Argument *A = dyn_cast(V)) { + if (F) assert(F == A->getParent() && + "inconsistent function-local metadata"); + else F = A->getParent(); + } else if (MDNode *MD = dyn_cast(V)) { + if (Function *NewF = assertLocalFunction(MD)) { + if (F) assert(F == NewF && "inconsistent function-local metadata"); + else F = NewF; + } + } } return F; } +#endif // 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 { +#ifndef NDEBUG + return assertLocalFunction(this); +#endif + if (!isFunctionLocal()) return NULL; - SmallPtrSet Visited; - return getFunctionHelper(this, Visited); + + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + Value *V = getOperand(i); + if (!V) continue; + if (Instruction *I = dyn_cast(V)) + return I->getParent()->getParent(); + if (BasicBlock *BB = dyn_cast(V)) + return BB->getParent(); + if (Argument *A = dyn_cast(V)) + return A->getParent(); + if (MDNode *MD = dyn_cast(V)) + if (Function *F = MD->getFunction()) return F; + } + return NULL; } // destroy - Delete this node. Only when there are no uses.