diff options
author | Dan Gohman <gohman@apple.com> | 2010-08-24 02:24:03 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-08-24 02:24:03 +0000 |
commit | 309b3af547a60bedd74daa2a94ebd3d3ed5f06e9 (patch) | |
tree | 1ed0e391d9675ac9427569fa9e34d34146789144 /lib/Bitcode/Writer/ValueEnumerator.cpp | |
parent | 78aeae2d7b771e33c5ff5218802cd2e9dab13df0 (diff) |
Extend function-local metadata to be usable as attachments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111895 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bitcode/Writer/ValueEnumerator.cpp')
-rw-r--r-- | lib/Bitcode/Writer/ValueEnumerator.cpp | 97 |
1 files changed, 77 insertions, 20 deletions
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 043a65de3b..69789c006a 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -220,8 +220,35 @@ void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) { EnumerateMetadata(MD->getOperand(i)); } +/// EnumerateMDNodeOperands - Enumerate all non-function-local values +/// and types referenced by the given MDNode. +void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) { + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + if (Value *V = N->getOperand(i)) { + if (isa<MDNode>(V) || isa<MDString>(V)) + EnumerateMetadata(V); + else if (!isa<Instruction>(V) && !isa<Argument>(V)) + EnumerateValue(V); + } else + EnumerateType(Type::getVoidTy(N->getContext())); + } +} + void ValueEnumerator::EnumerateMetadata(const Value *MD) { assert((isa<MDNode>(MD) || isa<MDString>(MD)) && "Invalid metadata kind"); + + // Enumerate the type of this value. + EnumerateType(MD->getType()); + + const MDNode *N = dyn_cast<MDNode>(MD); + + // In the module-level pass, skip function-local nodes themselves, but + // do walk their operands. + if (N && N->isFunctionLocal() && N->getFunction()) { + EnumerateMDNodeOperands(N); + return; + } + // Check to see if it's already in! unsigned &MDValueID = MDValueMap[MD]; if (MDValueID) { @@ -229,35 +256,52 @@ void ValueEnumerator::EnumerateMetadata(const Value *MD) { MDValues[MDValueID-1].second++; return; } + MDValues.push_back(std::make_pair(MD, 1U)); + MDValueID = MDValues.size(); + + // Enumerate all non-function-local operands. + if (N) + EnumerateMDNodeOperands(N); +} + +/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata +/// information reachable from the given MDNode. +void ValueEnumerator::EnumerateFunctionLocalMetadata(const MDNode *N) { + assert(N->isFunctionLocal() && N->getFunction() && + "EnumerateFunctionLocalMetadata called on non-function-local mdnode!"); // Enumerate the type of this value. - EnumerateType(MD->getType()); + EnumerateType(N->getType()); - if (const MDNode *N = dyn_cast<MDNode>(MD)) { - MDValues.push_back(std::make_pair(MD, 1U)); - MDValueMap[MD] = MDValues.size(); - MDValueID = MDValues.size(); - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - if (Value *V = N->getOperand(i)) - EnumerateValue(V); - else - EnumerateType(Type::getVoidTy(MD->getContext())); - } - if (N->isFunctionLocal() && N->getFunction()) - FunctionLocalMDs.push_back(N); + // Check to see if it's already in! + unsigned &MDValueID = MDValueMap[N]; + if (MDValueID) { + // Increment use count. + MDValues[MDValueID-1].second++; return; } - - // Add the value. - assert(isa<MDString>(MD) && "Unknown metadata kind"); - MDValues.push_back(std::make_pair(MD, 1U)); + MDValues.push_back(std::make_pair(N, 1U)); MDValueID = MDValues.size(); + + // To incoroporate function-local information visit all function-local + // MDNodes and all function-local values they reference. + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) + if (Value *V = N->getOperand(i)) { + if (MDNode *O = dyn_cast<MDNode>(V)) + if (O->isFunctionLocal() && O->getFunction()) + EnumerateFunctionLocalMetadata(O); + else if (isa<Instruction>(V) || isa<Argument>(V)) + EnumerateValue(V); + } + + // Also, collect all function-local MDNodes for easy access. + FunctionLocalMDs.push_back(N); } void ValueEnumerator::EnumerateValue(const Value *V) { assert(!V->getType()->isVoidTy() && "Can't insert void values!"); - if (isa<MDNode>(V) || isa<MDString>(V)) - return EnumerateMetadata(V); + assert(!isa<MDNode>(V) && !isa<MDString>(V) && + "EnumerateValue doesn't handle Metadata!"); // Check to see if it's already in! unsigned &ValueID = ValueMap[V]; @@ -370,6 +414,7 @@ void ValueEnumerator::EnumerateAttributes(const AttrListPtr &PAL) { void ValueEnumerator::incorporateFunction(const Function &F) { InstructionCount = 0; NumModuleValues = Values.size(); + NumModuleMDValues = MDValues.size(); // Adding function arguments to the value table. for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); @@ -412,6 +457,15 @@ void ValueEnumerator::incorporateFunction(const Function &F) { // Enumerate metadata after the instructions they might refer to. FnLocalMDVector.push_back(MD); } + + SmallVector<std::pair<unsigned, MDNode*>, 8> MDs; + I->getAllMetadataOtherThanDebugLoc(MDs); + for (unsigned i = 0, e = MDs.size(); i != e; ++i) { + MDNode *N = MDs[i].second; + if (N->isFunctionLocal() && N->getFunction()) + FnLocalMDVector.push_back(N); + } + if (!I->getType()->isVoidTy()) EnumerateValue(I); } @@ -419,17 +473,20 @@ void ValueEnumerator::incorporateFunction(const Function &F) { // Add all of the function-local metadata. for (unsigned i = 0, e = FnLocalMDVector.size(); i != e; ++i) - EnumerateOperandType(FnLocalMDVector[i]); + EnumerateFunctionLocalMetadata(FnLocalMDVector[i]); } void ValueEnumerator::purgeFunction() { /// Remove purged values from the ValueMap. for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i) ValueMap.erase(Values[i].first); + for (unsigned i = NumModuleMDValues, e = MDValues.size(); i != e; ++i) + MDValueMap.erase(MDValues[i].first); for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) ValueMap.erase(BasicBlocks[i]); Values.resize(NumModuleValues); + MDValues.resize(NumModuleMDValues); BasicBlocks.clear(); } |