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

@ -1124,23 +1124,33 @@ bool LLParser::ParseInstructionMetadata(Instruction *Inst,
return TokError("expected metadata after comma");
std::string Name = Lex.getStrVal();
unsigned MDK = M->getMDKindID(Name.c_str());
Lex.Lex();
MDNode *Node;
unsigned NodeID;
SMLoc Loc = Lex.getLoc();
if (ParseToken(lltok::exclaim, "expected '!' here") ||
ParseMDNodeID(Node, NodeID))
if (ParseToken(lltok::exclaim, "expected '!' here"))
return true;
unsigned MDK = M->getMDKindID(Name.c_str());
if (Node) {
// If we got the node, add it to the instruction.
Inst->setMetadata(MDK, Node);
if (Lex.getKind() == lltok::lbrace) {
ValID ID;
if (ParseMetadataListValue(ID, PFS))
return true;
assert(ID.Kind == ValID::t_MDNode);
Inst->setMetadata(MDK, ID.MDNodeVal);
} else {
MDRef R = { Loc, MDK, NodeID };
// Otherwise, remember that this should be resolved later.
ForwardRefInstMetadata[Inst].push_back(R);
if (ParseMDNodeID(Node, NodeID))
return true;
if (Node) {
// If we got the node, add it to the instruction.
Inst->setMetadata(MDK, Node);
} else {
MDRef R = { Loc, MDK, NodeID };
// Otherwise, remember that this should be resolved later.
ForwardRefInstMetadata[Inst].push_back(R);
}
}
// If this is the end of the list, we're done.
@ -2505,6 +2515,20 @@ bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts) {
return false;
}
bool LLParser::ParseMetadataListValue(ValID &ID, PerFunctionState *PFS) {
assert(Lex.getKind() == lltok::lbrace);
Lex.Lex();
SmallVector<Value*, 16> Elts;
if (ParseMDNodeVector(Elts, PFS) ||
ParseToken(lltok::rbrace, "expected end of metadata node"))
return true;
ID.MDNodeVal = MDNode::get(Context, Elts.data(), Elts.size());
ID.Kind = ValID::t_MDNode;
return false;
}
/// ParseMetadataValue
/// ::= !42
/// ::= !{...}
@ -2515,16 +2539,8 @@ bool LLParser::ParseMetadataValue(ValID &ID, PerFunctionState *PFS) {
// MDNode:
// !{ ... }
if (EatIfPresent(lltok::lbrace)) {
SmallVector<Value*, 16> Elts;
if (ParseMDNodeVector(Elts, PFS) ||
ParseToken(lltok::rbrace, "expected end of metadata node"))
return true;
ID.MDNodeVal = MDNode::get(Context, Elts.data(), Elts.size());
ID.Kind = ValID::t_MDNode;
return false;
}
if (Lex.getKind() == lltok::lbrace)
return ParseMetadataListValue(ID, PFS);
// Standalone metadata reference
// !42

View File

@ -307,6 +307,7 @@ namespace llvm {
bool ParseGlobalValue(const Type *Ty, Constant *&V);
bool ParseGlobalTypeAndValue(Constant *&V);
bool ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts);
bool ParseMetadataListValue(ValID &ID, PerFunctionState *PFS);
bool ParseMetadataValue(ValID &ID, PerFunctionState *PFS);
bool ParseMDNodeVector(SmallVectorImpl<Value*> &, PerFunctionState *PFS);
bool ParseInstructionMetadata(Instruction *Inst, PerFunctionState *PFS);

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();
}

View File

@ -72,6 +72,11 @@ private:
/// When a function is incorporated, this is the size of the Values list
/// before incorporation.
unsigned NumModuleValues;
/// When a function is incorporated, this is the size of the MDValues list
/// before incorporation.
unsigned NumModuleMDValues;
unsigned FirstFuncConstantID;
unsigned FirstInstID;
@ -132,7 +137,9 @@ public:
private:
void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
void EnumerateMDNodeOperands(const MDNode *N);
void EnumerateMetadata(const Value *MD);
void EnumerateFunctionLocalMetadata(const MDNode *N);
void EnumerateNamedMDNode(const NamedMDNode *NMD);
void EnumerateValue(const Value *V);
void EnumerateType(const Type *T);

View File

@ -1,9 +1,11 @@
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis
; PR7105
define void @foo() {
define void @foo(i32 %x) {
call void @llvm.zonk(metadata !1, i64 0, metadata !1)
ret void
store i32 0, i32* null, !whatever !0, !whatever_else !{}, !more !{metadata !"hello"}
store i32 0, i32* null, !whatever !{i32 %x, metadata !"hello", metadata !1, metadata !{}, metadata !2}
ret void, !whatever !{i32 %x}
}
declare void @llvm.zonk(metadata, i64, metadata) nounwind readnone