mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-12 13:30:51 +00:00
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:
parent
78aeae2d7b
commit
309b3af547
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user