mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 16:36:40 +00:00
Fix parsing of optional metadata for 'load', 'store' and 'alloc' instructions.
llvm-svn: 82175
This commit is contained in:
parent
f2c6ae3996
commit
d90471a00d
@ -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 {
|
||||||
return false;
|
if (Lex.getKind() == lltok::kw_dbg) {
|
||||||
return ParseToken(lltok::kw_align, "expected 'align'") ||
|
if (ParseOptionalDbgInfo()) return true;
|
||||||
ParseUInt32(Alignment);
|
} else if (Lex.getKind() == lltok::kw_align) {
|
||||||
|
if (ParseOptionalAlignment(Alignment)) return true;
|
||||||
|
} else
|
||||||
|
return true;
|
||||||
|
} while (EatIfPresent(lltok::comma));
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// ParseIndexList
|
/// ParseIndexList
|
||||||
/// ::= (',' uint32)+
|
/// ::= (',' uint32)+
|
||||||
bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices) {
|
bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices) {
|
||||||
@ -2621,26 +2650,18 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
|
|||||||
if (ParseToken(lltok::equal, "expected '=' after instruction name"))
|
if (ParseToken(lltok::equal, "expected '=' after instruction name"))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ParseInstruction(Inst, BB, PFS)) return true;
|
if (ParseInstruction(Inst, BB, PFS)) return true;
|
||||||
|
if (EatIfPresent(lltok::comma))
|
||||||
// Parse optional debug info
|
ParseOptionalDbgInfo();
|
||||||
if (Lex.getKind() == lltok::comma) {
|
|
||||||
Lex.Lex();
|
// Set metadata attached with this instruction.
|
||||||
if (Lex.getKind() == lltok::kw_dbg) {
|
Metadata &TheMetadata = M->getContext().getMetadata();
|
||||||
Lex.Lex();
|
for (SmallVector<std::pair<MDKindID, MDNode *>, 2>::iterator
|
||||||
if (Lex.getKind() != lltok::Metadata)
|
MDI = MDsOnInst.begin(), MDE = MDsOnInst.end(); MDI != MDE; ++MDI)
|
||||||
return TokError("Expected '!' here");
|
TheMetadata.setMD(MDI->first, MDI->second, Inst);
|
||||||
Lex.Lex();
|
MDsOnInst.clear();
|
||||||
MetadataBase *N = 0;
|
|
||||||
if (ParseMDNode(N)) return true;
|
|
||||||
Metadata &TheMetadata = M->getContext().getMetadata();
|
|
||||||
unsigned MDDbgKind = TheMetadata.getMDKind("dbg");
|
|
||||||
if (!MDDbgKind)
|
|
||||||
MDDbgKind = TheMetadata.RegisterMDKind("dbg");
|
|
||||||
TheMetadata.setMD(MDDbgKind, cast<MDNode>(N), Inst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BB->getInstList().push_back(Inst);
|
BB->getInstList().push_back(Inst);
|
||||||
|
|
||||||
// Set the name on the instruction.
|
// Set the name on the instruction.
|
||||||
@ -2820,41 +2841,55 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *RV;
|
Value *RV;
|
||||||
if (ParseValue(Ty, RV, PFS)) return true;
|
if (ParseValue(Ty, RV, PFS)) return true;
|
||||||
|
|
||||||
// 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
|
|
||||||
// of 'ret {i32,i32} {i32 1, i32 2}'
|
|
||||||
SmallVector<Value*, 8> RVs;
|
|
||||||
RVs.push_back(RV);
|
|
||||||
|
|
||||||
while (EatIfPresent(lltok::comma)) {
|
|
||||||
if (ParseTypeAndValue(RV, PFS)) return true;
|
|
||||||
RVs.push_back(RV);
|
|
||||||
}
|
|
||||||
|
|
||||||
RV = UndefValue::get(PFS.getFunction().getReturnType());
|
if (EatIfPresent(lltok::comma)) {
|
||||||
for (unsigned i = 0, e = RVs.size(); i != e; ++i) {
|
// Parse optional 'dbg'
|
||||||
Instruction *I = InsertValueInst::Create(RV, RVs[i], i, "mrv");
|
if (Lex.getKind() == lltok::kw_dbg) {
|
||||||
BB->getInstList().push_back(I);
|
if (ParseOptionalDbgInfo()) return true;
|
||||||
RV = I;
|
} else {
|
||||||
|
// The normal case is one return value.
|
||||||
|
// FIXME: LLVM 3.0 remove MRV support for 'ret i32 1, i32 2', requiring use
|
||||||
|
// of 'ret {i32,i32} {i32 1, i32 2}'
|
||||||
|
SmallVector<Value*, 8> RVs;
|
||||||
|
RVs.push_back(RV);
|
||||||
|
|
||||||
|
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;
|
||||||
|
RVs.push_back(RV);
|
||||||
|
} while (EatIfPresent(lltok::comma));
|
||||||
|
|
||||||
|
RV = UndefValue::get(PFS.getFunction().getReturnType());
|
||||||
|
for (unsigned i = 0, e = RVs.size(); i != e; ++i) {
|
||||||
|
Instruction *I = InsertValueInst::Create(RV, RVs[i], i, "mrv");
|
||||||
|
BB->getInstList().push_back(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,12 +3493,14 @@ 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");
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user