diff options
Diffstat (limited to 'llvm/lib/CodeGen/MIRParser')
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.h | 5 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 109 |
3 files changed, 130 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp index 2104f002b1f..81cb9e7d6f9 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp +++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp @@ -260,6 +260,16 @@ static Cursor maybeLexIRBlock( Rule.size(), ErrorCallback); } +static Cursor maybeLexIRValue( + Cursor C, MIToken &Token, + function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { + const StringRef Rule = "%ir."; + if (!C.remaining().startswith(Rule)) + return None; + return lexName(C, Token, MIToken::NamedIRValue, MIToken::QuotedNamedIRValue, + Rule.size(), ErrorCallback); +} + static Cursor lexVirtualRegister(Cursor C, MIToken &Token) { auto Range = C; C.advance(); // Skip '%' @@ -381,11 +391,17 @@ static MIToken::TokenKind symbolToken(char C) { } static Cursor maybeLexSymbol(Cursor C, MIToken &Token) { - auto Kind = symbolToken(C.peek()); + MIToken::TokenKind Kind; + unsigned Length = 1; + if (C.peek() == ':' && C.peek(1) == ':') { + Kind = MIToken::coloncolon; + Length = 2; + } else + Kind = symbolToken(C.peek()); if (Kind == MIToken::Error) return None; auto Range = C; - C.advance(); + C.advance(Length); Token = MIToken(Kind, Range.upto(C)); return C; } @@ -413,6 +429,8 @@ StringRef llvm::lexMIToken( return R.remaining(); if (Cursor R = maybeLexIRBlock(C, Token, ErrorCallback)) return R.remaining(); + if (Cursor R = maybeLexIRValue(C, Token, ErrorCallback)) + return R.remaining(); if (Cursor R = maybeLexRegister(C, Token)) return R.remaining(); if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback)) diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h index 2b06f13c9db..d33e0499f27 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.h +++ b/llvm/lib/CodeGen/MIRParser/MILexer.h @@ -36,6 +36,7 @@ struct MIToken { equal, underscore, colon, + coloncolon, exclaim, lparen, rparen, @@ -82,6 +83,8 @@ struct MIToken { NamedIRBlock, QuotedNamedIRBlock, IRBlock, + NamedIRValue, + QuotedNamedIRValue, }; private: @@ -120,7 +123,7 @@ public: bool isStringValueQuoted() const { return Kind == QuotedNamedGlobalValue || Kind == QuotedExternalSymbol || - Kind == QuotedNamedIRBlock; + Kind == QuotedNamedIRBlock || Kind == QuotedNamedIRValue; } /// Return the token's raw string value. 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; |