Fix parsing of optional metadata for 'load', 'store' and 'alloc' instructions.

llvm-svn: 82175
This commit is contained in:
Devang Patel 2009-09-17 23:04:48 +00:00
parent 6b574afc3a
commit ea8a4b984c
2 changed files with 105 additions and 65 deletions

View File

@ -1025,6 +1025,28 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
return false; return false;
} }
/// ParseOptionalDbgInfo
/// ::= /* empty */
/// ::= 'dbg' !42
bool LLParser::ParseOptionalDbgInfo() {
if (!EatIfPresent(lltok::kw_dbg))
return false;
if (Lex.getKind() != lltok::Metadata)
return TokError("Expected '!' here");
Lex.Lex();
MetadataBase *Node;
if (ParseMDNode(Node)) return true;
Metadata &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)));
return false;
}
/// ParseOptionalAlignment /// ParseOptionalAlignment
/// ::= /* empty */ /// ::= /* empty */
/// ::= 'align' 4 /// ::= 'align' 4
@ -1039,17 +1061,24 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) {
return false; return false;
} }
/// ParseOptionalCommaAlignment /// ParseOptionalInfo
/// ::= /* empty */ /// ::= OptionalInfo (',' OptionalInfo)+
/// ::= ',' 'align' 4 bool LLParser::ParseOptionalInfo(unsigned &Alignment) {
bool LLParser::ParseOptionalCommaAlignment(unsigned &Alignment) {
Alignment = 0; // FIXME: Handle customized metadata info attached with an instruction.
if (!EatIfPresent(lltok::comma)) do {
if (Lex.getKind() == lltok::kw_dbg) {
if (ParseOptionalDbgInfo()) return true;
} else if (Lex.getKind() == lltok::kw_align) {
if (ParseOptionalAlignment(Alignment)) return true;
} else
return true;
} while (EatIfPresent(lltok::comma));
return false; return false;
return ParseToken(lltok::kw_align, "expected 'align'") ||
ParseUInt32(Alignment);
} }
/// ParseIndexList /// ParseIndexList
/// ::= (',' uint32)+ /// ::= (',' uint32)+
bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices) { bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices) {
@ -2623,24 +2652,16 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
} }
if (ParseInstruction(Inst, BB, PFS)) return true; if (ParseInstruction(Inst, BB, PFS)) return true;
if (EatIfPresent(lltok::comma))
ParseOptionalDbgInfo();
// Parse optional debug info // Set metadata attached with this instruction.
if (Lex.getKind() == lltok::comma) {
Lex.Lex();
if (Lex.getKind() == lltok::kw_dbg) {
Lex.Lex();
if (Lex.getKind() != lltok::Metadata)
return TokError("Expected '!' here");
Lex.Lex();
MetadataBase *N = 0;
if (ParseMDNode(N)) return true;
Metadata &TheMetadata = M->getContext().getMetadata(); Metadata &TheMetadata = M->getContext().getMetadata();
unsigned MDDbgKind = TheMetadata.getMDKind("dbg"); for (SmallVector<std::pair<MDKindID, MDNode *>, 2>::iterator
if (!MDDbgKind) MDI = MDsOnInst.begin(), MDE = MDsOnInst.end(); MDI != MDE; ++MDI)
MDDbgKind = TheMetadata.RegisterMDKind("dbg"); TheMetadata.setMD(MDI->first, MDI->second, Inst);
TheMetadata.setMD(MDDbgKind, cast<MDNode>(N), Inst); MDsOnInst.clear();
}
}
BB->getInstList().push_back(Inst); BB->getInstList().push_back(Inst);
// Set the name on the instruction. // Set the name on the instruction.
@ -2820,15 +2841,18 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// ParseRet - Parse a return instruction. /// ParseRet - Parse a return instruction.
/// ::= 'ret' void /// ::= 'ret' void (',' 'dbg' !1)
/// ::= 'ret' TypeAndValue /// ::= 'ret' TypeAndValue (',' 'dbg' !1)
/// ::= 'ret' TypeAndValue (',' TypeAndValue)+ [[obsolete: LLVM 3.0]] /// ::= 'ret' TypeAndValue (',' TypeAndValue)+ (',' 'dbg' !1)
/// [[obsolete: LLVM 3.0]]
bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
PerFunctionState &PFS) { PerFunctionState &PFS) {
PATypeHolder Ty(Type::getVoidTy(Context)); PATypeHolder Ty(Type::getVoidTy(Context));
if (ParseType(Ty, true /*void allowed*/)) return true; if (ParseType(Ty, true /*void allowed*/)) return true;
if (Ty == Type::getVoidTy(Context)) { if (Ty == Type::getVoidTy(Context)) {
if (EatIfPresent(lltok::comma))
if (ParseOptionalDbgInfo()) return true;
Inst = ReturnInst::Create(Context); Inst = ReturnInst::Create(Context);
return false; return false;
} }
@ -2836,17 +2860,24 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
Value *RV; Value *RV;
if (ParseValue(Ty, RV, PFS)) return true; if (ParseValue(Ty, RV, PFS)) return true;
if (EatIfPresent(lltok::comma)) {
// Parse optional 'dbg'
if (Lex.getKind() == lltok::kw_dbg) {
if (ParseOptionalDbgInfo()) return true;
} else {
// The normal case is one return value. // The normal case is one return value.
if (Lex.getKind() == lltok::comma) {
// FIXME: LLVM 3.0 remove MRV support for 'ret i32 1, i32 2', requiring use // FIXME: LLVM 3.0 remove MRV support for 'ret i32 1, i32 2', requiring use
// of 'ret {i32,i32} {i32 1, i32 2}' // of 'ret {i32,i32} {i32 1, i32 2}'
SmallVector<Value*, 8> RVs; SmallVector<Value*, 8> RVs;
RVs.push_back(RV); RVs.push_back(RV);
while (EatIfPresent(lltok::comma)) { do {
// If optional 'dbg' is seen then this is the end of MRV.
if (Lex.getKind() == lltok::kw_dbg)
break;
if (ParseTypeAndValue(RV, PFS)) return true; if (ParseTypeAndValue(RV, PFS)) return true;
RVs.push_back(RV); RVs.push_back(RV);
} } while (EatIfPresent(lltok::comma));
RV = UndefValue::get(PFS.getFunction().getReturnType()); RV = UndefValue::get(PFS.getFunction().getReturnType());
for (unsigned i = 0, e = RVs.size(); i != e; ++i) { for (unsigned i = 0, e = RVs.size(); i != e; ++i) {
@ -2855,6 +2886,10 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
RV = I; RV = I;
} }
} }
}
if (EatIfPresent(lltok::comma))
if (ParseOptionalDbgInfo()) return true;
Inst = ReturnInst::Create(Context, RV); Inst = ReturnInst::Create(Context, RV);
return false; return false;
} }
@ -3393,8 +3428,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// ParseAlloc /// ParseAlloc
/// ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalAlignment)? /// ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalInfo)?
/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalAlignment)? /// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)?
bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS, bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
unsigned Opc) { unsigned Opc) {
PATypeHolder Ty(Type::getVoidTy(Context)); PATypeHolder Ty(Type::getVoidTy(Context));
@ -3404,11 +3439,12 @@ bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
if (ParseType(Ty)) return true; if (ParseType(Ty)) return true;
if (EatIfPresent(lltok::comma)) { if (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::kw_align) { if (Lex.getKind() == lltok::kw_align || Lex.getKind() == lltok::kw_dbg) {
if (ParseOptionalAlignment(Alignment)) return true; if (ParseOptionalInfo(Alignment)) return true;
} else if (ParseTypeAndValue(Size, SizeLoc, PFS) || } else {
ParseOptionalCommaAlignment(Alignment)) { if (ParseTypeAndValue(Size, SizeLoc, PFS)) return true;
return true; if (EatIfPresent(lltok::comma))
if (ParseOptionalInfo(Alignment)) return true;
} }
} }
@ -3434,14 +3470,15 @@ bool LLParser::ParseFree(Instruction *&Inst, PerFunctionState &PFS) {
} }
/// ParseLoad /// ParseLoad
/// ::= 'volatile'? 'load' TypeAndValue (',' 'align' i32)? /// ::= 'volatile'? 'load' TypeAndValue (',' OptionalInfo)?
bool LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS, bool LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS,
bool isVolatile) { bool isVolatile) {
Value *Val; LocTy Loc; Value *Val; LocTy Loc;
unsigned Alignment; unsigned Alignment = 0;
if (ParseTypeAndValue(Val, Loc, PFS) || if (ParseTypeAndValue(Val, Loc, PFS)) return true;
ParseOptionalCommaAlignment(Alignment))
return true; if (EatIfPresent(lltok::comma))
if (ParseOptionalInfo(Alignment)) return true;
if (!isa<PointerType>(Val->getType()) || if (!isa<PointerType>(Val->getType()) ||
!cast<PointerType>(Val->getType())->getElementType()->isFirstClassType()) !cast<PointerType>(Val->getType())->getElementType()->isFirstClassType())
@ -3456,13 +3493,15 @@ bool LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS,
bool LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS, bool LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS,
bool isVolatile) { bool isVolatile) {
Value *Val, *Ptr; LocTy Loc, PtrLoc; Value *Val, *Ptr; LocTy Loc, PtrLoc;
unsigned Alignment; unsigned Alignment = 0;
if (ParseTypeAndValue(Val, Loc, PFS) || if (ParseTypeAndValue(Val, Loc, PFS) ||
ParseToken(lltok::comma, "expected ',' after store operand") || ParseToken(lltok::comma, "expected ',' after store operand") ||
ParseTypeAndValue(Ptr, PtrLoc, PFS) || ParseTypeAndValue(Ptr, PtrLoc, PFS))
ParseOptionalCommaAlignment(Alignment))
return true; return true;
if (EatIfPresent(lltok::comma))
if (ParseOptionalInfo(Alignment)) return true;
if (!isa<PointerType>(Ptr->getType())) if (!isa<PointerType>(Ptr->getType()))
return Error(PtrLoc, "store operand must be a pointer"); return Error(PtrLoc, "store operand must be a pointer");
if (!Val->getType()->isFirstClassType()) if (!Val->getType()->isFirstClassType())

View File

@ -48,7 +48,7 @@ namespace llvm {
/// MetadataCache - This map keeps track of parsed metadata constants. /// MetadataCache - This map keeps track of parsed metadata constants.
std::map<unsigned, MetadataBase *> MetadataCache; std::map<unsigned, MetadataBase *> MetadataCache;
std::map<unsigned, std::pair<MetadataBase *, LocTy> > ForwardRefMDNodes; std::map<unsigned, std::pair<MetadataBase *, LocTy> > ForwardRefMDNodes;
SmallVector<std::pair<MDKindID, MDNode *>, 2> MDsOnInst;
struct UpRefRecord { struct UpRefRecord {
/// Loc - This is the location of the upref. /// Loc - This is the location of the upref.
LocTy Loc; LocTy Loc;
@ -128,7 +128,8 @@ namespace llvm {
bool ParseOptionalVisibility(unsigned &Visibility); bool ParseOptionalVisibility(unsigned &Visibility);
bool ParseOptionalCallingConv(CallingConv::ID &CC); bool ParseOptionalCallingConv(CallingConv::ID &CC);
bool ParseOptionalAlignment(unsigned &Alignment); bool ParseOptionalAlignment(unsigned &Alignment);
bool ParseOptionalCommaAlignment(unsigned &Alignment); bool ParseOptionalDbgInfo();
bool ParseOptionalInfo(unsigned &Alignment);
bool ParseIndexList(SmallVectorImpl<unsigned> &Indices); bool ParseIndexList(SmallVectorImpl<unsigned> &Indices);
// Top-Level Entities // Top-Level Entities