Parse custom metadata attached with an instruction.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83033 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2009-09-29 00:01:14 +00:00
parent 9ad675893f
commit 0475c9170e
9 changed files with 75 additions and 40 deletions

View File

@ -305,8 +305,10 @@ public:
//===----------------------------------------------------------------------===//
/// MetadataContext -
/// MetadataContext manages metadata used in a context.
/// MetadataContext handles uniquing and assignment of IDs for custom metadata
/// types. Custom metadata handler names do not contain spaces. And the name
/// must start with an alphabet. The regular expression used to check name
/// is [a-zA-Z$._][a-zA-Z$._0-9]*
class MetadataContext {
public:
typedef std::pair<unsigned, WeakVH> MDPairTy;
@ -330,6 +332,9 @@ public:
/// is not registered then return 0.
unsigned getMDKind(const char *Name);
/// validName - Return true if Name is a valid custom metadata handler name.
bool validName(const char *Name);
/// getMD - Get the metadata of given kind attached with an Instruction.
/// If the metadata is not found then return 0.
MDNode *getMD(unsigned Kind, const Instruction *Inst);

View File

@ -434,7 +434,7 @@ lltok::Kind LLLexer::LexMetadata() {
++CurPtr;
StrVal.assign(TokStart+1, CurPtr); // Skip !
return lltok::NamedMD;
return lltok::NamedOrCustomMD;
}
return lltok::Metadata;
}
@ -530,7 +530,6 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(asm);
KEYWORD(sideeffect);
KEYWORD(gc);
KEYWORD(dbg);
KEYWORD(ccc);
KEYWORD(fastcc);

View File

@ -125,7 +125,7 @@ bool LLParser::ParseTopLevelEntities() {
case lltok::GlobalID: if (ParseUnnamedGlobal()) return true; break;
case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break;
case lltok::Metadata: if (ParseStandaloneMetadata()) return true; break;
case lltok::NamedMD: if (ParseNamedMetadata()) return true; break;
case lltok::NamedOrCustomMD: if (ParseNamedMetadata()) return true; break;
// The Global variable production with no name can have many different
// optional leading prefixes, the production is:
@ -461,7 +461,7 @@ bool LLParser::ParseMDNode(MetadataBase *&Node) {
///ParseNamedMetadata:
/// !foo = !{ !1, !2 }
bool LLParser::ParseNamedMetadata() {
assert(Lex.getKind() == lltok::NamedMD);
assert(Lex.getKind() == lltok::NamedOrCustomMD);
Lex.Lex();
std::string Name = Lex.getStrVal();
@ -1025,24 +1025,30 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
return false;
}
/// ParseOptionalDbgInfo
/// ParseOptionalCustomMetadata
/// ::= /* empty */
/// ::= 'dbg' !42
bool LLParser::ParseOptionalDbgInfo() {
/// ::= !dbg !42
bool LLParser::ParseOptionalCustomMetadata() {
if (!EatIfPresent(lltok::kw_dbg))
std::string Name;
if (Lex.getKind() == lltok::NamedOrCustomMD) {
Name = Lex.getStrVal();
Lex.Lex();
} else
return false;
if (Lex.getKind() != lltok::Metadata)
return TokError("Expected '!' here");
Lex.Lex();
MetadataBase *Node;
if (ParseMDNode(Node)) return true;
MetadataContext &TheMetadata = M->getContext().getMetadata();
unsigned MDDbgKind = TheMetadata.getMDKind("dbg");
if (!MDDbgKind)
MDDbgKind = TheMetadata.RegisterMDKind("dbg");
MDsOnInst.push_back(std::make_pair(MDDbgKind, cast<MDNode>(Node)));
unsigned MDK = TheMetadata.getMDKind(Name.c_str());
if (!MDK)
MDK = TheMetadata.RegisterMDKind(Name.c_str());
MDsOnInst.push_back(std::make_pair(MDK, cast<MDNode>(Node)));
return false;
}
@ -1067,8 +1073,8 @@ bool LLParser::ParseOptionalInfo(unsigned &Alignment) {
// FIXME: Handle customized metadata info attached with an instruction.
do {
if (Lex.getKind() == lltok::kw_dbg) {
if (ParseOptionalDbgInfo()) return true;
if (Lex.getKind() == lltok::NamedOrCustomMD) {
if (ParseOptionalCustomMetadata()) return true;
} else if (Lex.getKind() == lltok::kw_align) {
if (ParseOptionalAlignment(Alignment)) return true;
} else
@ -2653,7 +2659,7 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
if (ParseInstruction(Inst, BB, PFS)) return true;
if (EatIfPresent(lltok::comma))
ParseOptionalDbgInfo();
ParseOptionalCustomMetadata();
// Set metadata attached with this instruction.
MetadataContext &TheMetadata = M->getContext().getMetadata();
@ -2841,9 +2847,9 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) {
//===----------------------------------------------------------------------===//
/// ParseRet - Parse a return instruction.
/// ::= 'ret' void (',' 'dbg' !1)
/// ::= 'ret' TypeAndValue (',' 'dbg' !1)
/// ::= 'ret' TypeAndValue (',' TypeAndValue)+ (',' 'dbg' !1)
/// ::= 'ret' void (',' !dbg, !1)
/// ::= 'ret' TypeAndValue (',' !dbg, !1)
/// ::= 'ret' TypeAndValue (',' TypeAndValue)+ (',' !dbg, !1)
/// [[obsolete: LLVM 3.0]]
bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
PerFunctionState &PFS) {
@ -2852,7 +2858,7 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
if (Ty == Type::getVoidTy(Context)) {
if (EatIfPresent(lltok::comma))
if (ParseOptionalDbgInfo()) return true;
if (ParseOptionalCustomMetadata()) return true;
Inst = ReturnInst::Create(Context);
return false;
}
@ -2861,9 +2867,9 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
if (ParseValue(Ty, RV, PFS)) return true;
if (EatIfPresent(lltok::comma)) {
// Parse optional 'dbg'
if (Lex.getKind() == lltok::kw_dbg) {
if (ParseOptionalDbgInfo()) return true;
// Parse optional custom metadata, e.g. !dbg
if (Lex.getKind() == lltok::NamedOrCustomMD) {
if (ParseOptionalCustomMetadata()) return true;
} else {
// The normal case is one return value.
// FIXME: LLVM 3.0 remove MRV support for 'ret i32 1, i32 2', requiring use
@ -2872,8 +2878,9 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
RVs.push_back(RV);
do {
// If optional 'dbg' is seen then this is the end of MRV.
if (Lex.getKind() == lltok::kw_dbg)
// If optional custom metadata, e.g. !dbg is seen then this is the
// end of MRV.
if (Lex.getKind() == lltok::NamedOrCustomMD)
break;
if (ParseTypeAndValue(RV, PFS)) return true;
RVs.push_back(RV);
@ -2888,7 +2895,7 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
}
}
if (EatIfPresent(lltok::comma))
if (ParseOptionalDbgInfo()) return true;
if (ParseOptionalCustomMetadata()) return true;
Inst = ReturnInst::Create(Context, RV);
return false;
@ -3439,7 +3446,8 @@ bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
if (ParseType(Ty)) return true;
if (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::kw_align || Lex.getKind() == lltok::kw_dbg) {
if (Lex.getKind() == lltok::kw_align
|| Lex.getKind() == lltok::NamedOrCustomMD) {
if (ParseOptionalInfo(Alignment)) return true;
} else {
if (ParseTypeAndValue(Size, SizeLoc, PFS)) return true;

View File

@ -128,7 +128,7 @@ namespace llvm {
bool ParseOptionalVisibility(unsigned &Visibility);
bool ParseOptionalCallingConv(CallingConv::ID &CC);
bool ParseOptionalAlignment(unsigned &Alignment);
bool ParseOptionalDbgInfo();
bool ParseOptionalCustomMetadata();
bool ParseOptionalInfo(unsigned &Alignment);
bool ParseIndexList(SmallVectorImpl<unsigned> &Indices);

View File

@ -127,7 +127,7 @@ namespace lltok {
GlobalVar, // @foo @"foo"
LocalVar, // %foo %"foo"
StringConstant, // "foo"
NamedMD, // !foo
NamedOrCustomMD, // !foo
// Metadata valued tokens.
Metadata, // !"foo" !{i8 42}

View File

@ -2007,7 +2007,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
for (MetadataContext::MDMapTy::const_iterator MI = MDMap->begin(),
ME = MDMap->end(); MI != ME; ++MI)
if (const MDNode *MD = dyn_cast_or_null<MDNode>(MI->second))
Out << ", " << MDNames[MI->first]
Out << ", !" << MDNames[MI->first]
<< " !" << Machine.getMetadataSlot(MD);
printInfoComment(I);

View File

@ -260,6 +260,7 @@ NamedMDNode::~NamedMDNode() {
/// RegisterMDKind - Register a new metadata kind and return its ID.
/// A metadata kind can be registered only once.
unsigned MetadataContext::RegisterMDKind(const char *Name) {
assert (validName(Name) && "Invalid custome metadata name!");
unsigned Count = MDHandlerNames.size();
StringMap<unsigned>::iterator I = MDHandlerNames.find(Name);
assert(I == MDHandlerNames.end() && "Already registered MDKind!");
@ -267,9 +268,31 @@ unsigned MetadataContext::RegisterMDKind(const char *Name) {
return Count + 1;
}
/// validName - Return true if Name is a valid custom metadata handler name.
bool MetadataContext::validName(const char *Name) {
if (!Name)
return false;
if (!isalpha(*Name))
return false;
unsigned Length = strlen(Name);
unsigned Count = 1;
++Name;
while (Name &&
(isalnum(*Name) || *Name == '_' || *Name == '-' || *Name == '.')) {
++Name;
++Count;
}
if (Length != Count)
return false;
return true;
}
/// getMDKind - Return metadata kind. If the requested metadata kind
/// is not registered then return 0.
unsigned MetadataContext::getMDKind(const char *Name) {
assert (validName(Name) && "Invalid custome metadata name!");
StringMap<unsigned>::iterator I = MDHandlerNames.find(Name);
if (I == MDHandlerNames.end())
return 0;

View File

@ -4,13 +4,13 @@ define i32 @foo() nounwind ssp {
entry:
%retval = alloca i32 ; <i32*> [#uses=2]
call void @llvm.dbg.func.start(metadata !0)
store i32 42, i32* %retval, dbg !3
br label %0, dbg !3
store i32 42, i32* %retval, !dbg !3
br label %0, !dbg !3
; <label>:0 ; preds = %entry
call void @llvm.dbg.region.end(metadata !0)
%1 = load i32* %retval, dbg !3 ; <i32> [#uses=1]
ret i32 %1, dbg !3
%1 = load i32* %retval, !dbg !3 ; <i32> [#uses=1]
ret i32 %1, !dbg !3
}
declare void @llvm.dbg.func.start(metadata) nounwind readnone

View File

@ -1,15 +1,15 @@
; RUN: llvm-as < %s | llvm-dis | grep " dbg " | count 4
; RUN: llvm-as < %s | llvm-dis | grep " !dbg " | count 4
define i32 @foo() nounwind ssp {
entry:
%retval = alloca i32 ; <i32*> [#uses=2]
call void @llvm.dbg.func.start(metadata !0)
store i32 42, i32* %retval, dbg !3
br label %0, dbg !3
store i32 42, i32* %retval, !dbg !3
br label %0, !dbg !3
; <label>:0 ; preds = %entry
call void @llvm.dbg.region.end(metadata !0)
%1 = load i32* %retval, dbg !3 ; <i32> [#uses=1]
ret i32 %1, dbg !3
%1 = load i32* %retval, !dbg !3 ; <i32> [#uses=1]
ret i32 %1, !dbg !3
}
declare void @llvm.dbg.func.start(metadata) nounwind readnone