diff options
author | Alex Lorenz <arphaman@gmail.com> | 2015-08-03 23:08:19 +0000 |
---|---|---|
committer | Alex Lorenz <arphaman@gmail.com> | 2015-08-03 23:08:19 +0000 |
commit | 4af7e610c3dc68444d8987643355f7e3a0559ef2 (patch) | |
tree | 1aa6a72adac203558a4934aa183c43ea46e83b77 /llvm/lib/CodeGen/MIRParser/MIParser.cpp | |
parent | c96516fddf3484f8690c653f8b5a45cfde9f819a (diff) | |
download | bcm5719-llvm-4af7e610c3dc68444d8987643355f7e3a0559ef2.tar.gz bcm5719-llvm-4af7e610c3dc68444d8987643355f7e3a0559ef2.zip |
MIR Serialization: Initial serialization of the machine memory operands.
Reviewers: Duncan P. N. Exon Smith
llvm-svn: 243915
Diffstat (limited to 'llvm/lib/CodeGen/MIRParser/MIParser.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 109 |
1 files changed, 106 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index da2a01366fd..e1770cd7fdb 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Constants.h" @@ -133,6 +134,8 @@ public: bool parseBlockAddressOperand(MachineOperand &Dest); bool parseTargetIndexOperand(MachineOperand &Dest); bool parseMachineOperand(MachineOperand &Dest); + bool parseIRValue(Value *&V); + bool parseMachineMemoryOperand(MachineMemOperand *&Dest); private: /// Convert the integer literal in the current token into an unsigned integer. @@ -140,6 +143,11 @@ private: /// Return true if an error occurred. bool getUnsigned(unsigned &Result); + /// Convert the integer literal in the current token into an uint64. + /// + /// Return true if an error occurred. + bool getUint64(uint64_t &Result); + /// If the current token is of the given kind, consume it and return false. /// Otherwise report an error and return true. bool expectAndConsume(MIToken::TokenKind TokenKind); @@ -256,15 +264,16 @@ bool MIParser::parse(MachineInstr *&MI) { if (Token.isError() || parseInstruction(OpCode, Flags)) return true; - // TODO: Parse the bundle instruction flags and memory operands. + // TODO: Parse the bundle instruction flags. // Parse the remaining machine operands. - while (Token.isNot(MIToken::Eof) && Token.isNot(MIToken::kw_debug_location)) { + while (Token.isNot(MIToken::Eof) && Token.isNot(MIToken::kw_debug_location) && + Token.isNot(MIToken::coloncolon)) { auto Loc = Token.location(); if (parseMachineOperand(MO)) return true; Operands.push_back(MachineOperandWithLocation(MO, Loc, Token.location())); - if (Token.is(MIToken::Eof)) + if (Token.is(MIToken::Eof) || Token.is(MIToken::coloncolon)) break; if (Token.isNot(MIToken::comma)) return error("expected ',' before the next machine operand"); @@ -282,6 +291,23 @@ bool MIParser::parse(MachineInstr *&MI) { DebugLocation = DebugLoc(Node); } + // Parse the machine memory operands. + SmallVector<MachineMemOperand *, 2> MemOperands; + if (Token.is(MIToken::coloncolon)) { + lex(); + while (Token.isNot(MIToken::Eof)) { + MachineMemOperand *MemOp = nullptr; + if (parseMachineMemoryOperand(MemOp)) + return true; + MemOperands.push_back(MemOp); + if (Token.is(MIToken::Eof)) + break; + if (Token.isNot(MIToken::comma)) + return error("expected ',' before the next machine memory operand"); + lex(); + } + } + const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode); if (!MCID.isVariadic()) { // FIXME: Move the implicit operand verification to the machine verifier. @@ -294,6 +320,12 @@ bool MIParser::parse(MachineInstr *&MI) { MI->setFlags(Flags); for (const auto &Operand : Operands) MI->addOperand(MF, Operand.Operand); + if (MemOperands.empty()) + return false; + MachineInstr::mmo_iterator MemRefs = + MF.allocateMemRefsArray(MemOperands.size()); + std::copy(MemOperands.begin(), MemOperands.end(), MemRefs); + MI->setMemRefs(MemRefs, MemRefs + MemOperands.size()); return false; } @@ -929,6 +961,77 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) { return false; } +bool MIParser::parseIRValue(Value *&V) { + switch (Token.kind()) { + case MIToken::NamedIRValue: + case MIToken::QuotedNamedIRValue: { + StringValueUtility Name(Token); + V = MF.getFunction()->getValueSymbolTable().lookup(Name); + if (!V) + return error(Twine("use of undefined IR value '%ir.") + + Token.rawStringValue() + "'"); + break; + } + // TODO: Parse unnamed IR value references. + default: + llvm_unreachable("The current token should be an IR block reference"); + } + return false; +} + +bool MIParser::getUint64(uint64_t &Result) { + assert(Token.hasIntegerValue()); + if (Token.integerValue().getActiveBits() > 64) + return error("expected 64-bit integer (too large)"); + Result = Token.integerValue().getZExtValue(); + return false; +} + +bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) { + if (expectAndConsume(MIToken::lparen)) + return true; + // TODO: Parse the operand's flags. + if (Token.isNot(MIToken::Identifier) || + (Token.stringValue() != "load" && Token.stringValue() != "store")) + return error("expected 'load' or 'store' memory operation"); + unsigned Flags = 0; + if (Token.stringValue() == "load") + Flags |= MachineMemOperand::MOLoad; + else + Flags |= MachineMemOperand::MOStore; + lex(); + + if (Token.isNot(MIToken::IntegerLiteral)) + return error("expected the size integer literal after memory operation"); + uint64_t Size; + if (getUint64(Size)) + return true; + lex(); + + const char *Word = Flags & MachineMemOperand::MOLoad ? "from" : "into"; + if (Token.isNot(MIToken::Identifier) || Token.stringValue() != Word) + return error(Twine("expected '") + Word + "'"); + lex(); + + // TODO: Parse pseudo source values. + if (Token.isNot(MIToken::NamedIRValue) && + Token.isNot(MIToken::QuotedNamedIRValue)) + return error("expected an IR value reference"); + Value *V = nullptr; + if (parseIRValue(V)) + return true; + if (!V->getType()->isPointerTy()) + return error("expected a pointer IR value"); + lex(); + // TODO: Parse the base alignment. + // TODO: Parse the attached metadata nodes. + if (expectAndConsume(MIToken::rparen)) + return true; + + Dest = MF.getMachineMemOperand(MachinePointerInfo(V), Flags, Size, Size); + return false; +} + void MIParser::initNames2InstrOpCodes() { if (!Names2InstrOpCodes.empty()) return; |