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
This commit is contained in:
Dan Gohman
2010-08-24 02:24:03 +00:00
parent 78aeae2d7b
commit 309b3af547
5 changed files with 128 additions and 45 deletions

View File

@ -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;
}
// Enumerate the type of this value.
EnumerateType(MD->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);
return;
}
// Add the value.
assert(isa<MDString>(MD) && "Unknown metadata kind");
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(N->getType());
// Check to see if it's already in!
unsigned &MDValueID = MDValueMap[N];
if (MDValueID) {
// Increment use count.
MDValues[MDValueID-1].second++;
return;
}
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();
}