diff options
Diffstat (limited to 'llvm/lib/CodeGen/MIRParser')
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.cpp | 48 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.h | 18 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 323 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.h | 38 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 103 |
5 files changed, 378 insertions, 152 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp index 25afedff973..450d318f8c8 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp +++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp @@ -79,7 +79,18 @@ MIToken &MIToken::setIntegerValue(APSInt IntVal) { /// Skip the leading whitespace characters and return the updated cursor. static Cursor skipWhitespace(Cursor C) { - while (isspace(C.peek())) + while (isblank(C.peek())) + C.advance(); + return C; +} + +static bool isNewlineChar(char C) { return C == '\n' || C == '\r'; } + +/// Skip a line comment and return the updated cursor. +static Cursor skipComment(Cursor C) { + if (C.peek() != ';') + return C; + while (!isNewlineChar(C.peek()) && !C.isEOF()) C.advance(); return C; } @@ -127,7 +138,7 @@ static Cursor lexStringConstant( function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { assert(C.peek() == '"'); for (C.advance(); C.peek() != '"'; C.advance()) { - if (C.isEOF()) { + if (C.isEOF() || isNewlineChar(C.peek())) { ErrorCallback( C.location(), "end of machine instruction reached before the closing '\"'"); @@ -206,6 +217,10 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { .Case("jump-table", MIToken::kw_jump_table) .Case("constant-pool", MIToken::kw_constant_pool) .Case("liveout", MIToken::kw_liveout) + .Case("address-taken", MIToken::kw_address_taken) + .Case("landing-pad", MIToken::kw_landing_pad) + .Case("liveins", MIToken::kw_liveins) + .Case("successors", MIToken::kw_successors) .Default(MIToken::Identifier); } @@ -224,10 +239,12 @@ static Cursor maybeLexIdentifier(Cursor C, MIToken &Token) { static Cursor maybeLexMachineBasicBlock( Cursor C, MIToken &Token, function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { - if (!C.remaining().startswith("%bb.")) + bool IsReference = C.remaining().startswith("%bb."); + if (!IsReference && !C.remaining().startswith("bb.")) return None; auto Range = C; - C.advance(4); // Skip '%bb.' + unsigned PrefixLength = IsReference ? 4 : 3; + C.advance(PrefixLength); // Skip '%bb.' or 'bb.' if (!isdigit(C.peek())) { Token.reset(MIToken::Error, C.remaining()); ErrorCallback(C.location(), "expected a number after '%bb.'"); @@ -237,14 +254,16 @@ static Cursor maybeLexMachineBasicBlock( while (isdigit(C.peek())) C.advance(); StringRef Number = NumberRange.upto(C); - unsigned StringOffset = 4 + Number.size(); // Drop '%bb.<id>' + unsigned StringOffset = PrefixLength + Number.size(); // Drop '%bb.<id>' if (C.peek() == '.') { C.advance(); // Skip '.' ++StringOffset; while (isIdentifierChar(C.peek())) C.advance(); } - Token.reset(MIToken::MachineBasicBlock, Range.upto(C)) + Token.reset(IsReference ? MIToken::MachineBasicBlock + : MIToken::MachineBasicBlockLabel, + Range.upto(C)) .setIntegerValue(APSInt(Number)) .setStringValue(Range.upto(C).drop_front(StringOffset)); return C; @@ -460,10 +479,19 @@ static Cursor maybeLexSymbol(Cursor C, MIToken &Token) { return C; } +static Cursor maybeLexNewline(Cursor C, MIToken &Token) { + if (!isNewlineChar(C.peek())) + return None; + auto Range = C; + C.advance(); + Token.reset(MIToken::Newline, Range.upto(C)); + return C; +} + StringRef llvm::lexMIToken( StringRef Source, MIToken &Token, function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { - auto C = skipWhitespace(Cursor(Source)); + auto C = skipComment(skipWhitespace(Cursor(Source))); if (C.isEOF()) { Token.reset(MIToken::Eof, C.remaining()); return C.remaining(); @@ -471,10 +499,10 @@ StringRef llvm::lexMIToken( if (Cursor R = maybeLexIntegerType(C, Token)) return R.remaining(); - if (Cursor R = maybeLexIdentifier(C, Token)) - return R.remaining(); if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback)) return R.remaining(); + if (Cursor R = maybeLexIdentifier(C, Token)) + return R.remaining(); if (Cursor R = maybeLexJumpTableIndex(C, Token)) return R.remaining(); if (Cursor R = maybeLexStackObject(C, Token)) @@ -499,6 +527,8 @@ StringRef llvm::lexMIToken( return R.remaining(); if (Cursor R = maybeLexSymbol(C, Token)) return R.remaining(); + if (Cursor R = maybeLexNewline(C, Token)) + return R.remaining(); Token.reset(MIToken::Error, C.remaining()); ErrorCallback(C.location(), diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h index d0ae379097c..07bdc3e4549 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.h +++ b/llvm/lib/CodeGen/MIRParser/MILexer.h @@ -30,6 +30,7 @@ struct MIToken { // Markers Eof, Error, + Newline, // Tokens with no info. comma, @@ -75,11 +76,16 @@ struct MIToken { kw_jump_table, kw_constant_pool, kw_liveout, + kw_address_taken, + kw_landing_pad, + kw_liveins, + kw_successors, // Identifier tokens Identifier, IntegerType, NamedRegister, + MachineBasicBlockLabel, MachineBasicBlock, StackObject, FixedStackObject, @@ -118,6 +124,10 @@ public: bool isError() const { return Kind == Error; } + bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; } + + bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; } + bool isRegister() const { return Kind == NamedRegister || Kind == underscore || Kind == VirtualRegister; @@ -149,10 +159,10 @@ public: bool hasIntegerValue() const { return Kind == IntegerLiteral || Kind == MachineBasicBlock || - Kind == StackObject || Kind == FixedStackObject || - Kind == GlobalValue || Kind == VirtualRegister || - Kind == ConstantPoolItem || Kind == JumpTableIndex || - Kind == IRBlock; + Kind == MachineBasicBlockLabel || Kind == StackObject || + Kind == FixedStackObject || Kind == GlobalValue || + Kind == VirtualRegister || Kind == ConstantPoolItem || + Kind == JumpTableIndex || Kind == IRBlock; } }; diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index 46ad8769fd3..3a0e52491ca 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -90,11 +90,19 @@ public: /// This function always return true. bool error(StringRef::iterator Loc, const Twine &Msg); + bool + parseBasicBlockDefinitions(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots); + bool parseBasicBlocks(); bool parse(MachineInstr *&MI); bool parseStandaloneMBB(MachineBasicBlock *&MBB); bool parseStandaloneNamedRegister(unsigned &Reg); bool parseStandaloneVirtualRegister(unsigned &Reg); - bool parseStandaloneIRBlockReference(const BasicBlock *&BB); + + bool + parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots); + bool parseBasicBlock(MachineBasicBlock &MBB); + bool parseBasicBlockLiveins(MachineBasicBlock &MBB); + bool parseBasicBlockSuccessors(MachineBasicBlock &MBB); bool parseRegister(unsigned &Reg); bool parseRegisterFlag(unsigned &Flags); @@ -149,6 +157,10 @@ private: /// Otherwise report an error and return true. bool expectAndConsume(MIToken::TokenKind TokenKind); + /// If the current token is of the given kind, consume it and return true. + /// Otherwise return false. + bool consumeIfPresent(MIToken::TokenKind TokenKind); + void initNames2InstrOpCodes(); /// Try to convert an instruction name to an opcode. Return true if the @@ -217,10 +229,17 @@ bool MIParser::error(const Twine &Msg) { return error(Token.location(), Msg); } bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) { assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size())); - Error = SMDiagnostic( - SM, SMLoc(), - SM.getMemoryBuffer(SM.getMainFileID())->getBufferIdentifier(), 1, - Loc - Source.data(), SourceMgr::DK_Error, Msg.str(), Source, None, None); + const MemoryBuffer &Buffer = *SM.getMemoryBuffer(SM.getMainFileID()); + if (Loc >= Buffer.getBufferStart() && Loc <= Buffer.getBufferEnd()) { + // Create an ordinary diagnostic when the source manager's buffer is the + // source string. + Error = SM.GetMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg); + return true; + } + // Create a diagnostic for a YAML string literal. + Error = SMDiagnostic(SM, SMLoc(), Buffer.getBufferIdentifier(), 1, + Loc - Source.data(), SourceMgr::DK_Error, Msg.str(), + Source, None, None); return true; } @@ -230,6 +249,8 @@ static const char *toString(MIToken::TokenKind TokenKind) { return "','"; case MIToken::equal: return "'='"; + case MIToken::colon: + return "':'"; case MIToken::lparen: return "'('"; case MIToken::rparen: @@ -246,9 +267,236 @@ bool MIParser::expectAndConsume(MIToken::TokenKind TokenKind) { return false; } -bool MIParser::parse(MachineInstr *&MI) { +bool MIParser::consumeIfPresent(MIToken::TokenKind TokenKind) { + if (Token.isNot(TokenKind)) + return false; + lex(); + return true; +} + +bool MIParser::parseBasicBlockDefinition( + DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) { + assert(Token.is(MIToken::MachineBasicBlockLabel)); + unsigned ID = 0; + if (getUnsigned(ID)) + return true; + auto Loc = Token.location(); + auto Name = Token.stringValue(); + lex(); + bool HasAddressTaken = false; + bool IsLandingPad = false; + unsigned Alignment = 0; + BasicBlock *BB = nullptr; + if (consumeIfPresent(MIToken::lparen)) { + do { + // TODO: Report an error when multiple same attributes are specified. + switch (Token.kind()) { + case MIToken::kw_address_taken: + HasAddressTaken = true; + lex(); + break; + case MIToken::kw_landing_pad: + IsLandingPad = true; + lex(); + break; + case MIToken::kw_align: + if (parseAlignment(Alignment)) + return true; + break; + case MIToken::IRBlock: + // TODO: Report an error when both name and ir block are specified. + if (parseIRBlock(BB, *MF.getFunction())) + return true; + lex(); + break; + default: + break; + } + } while (consumeIfPresent(MIToken::comma)); + if (expectAndConsume(MIToken::rparen)) + return true; + } + if (expectAndConsume(MIToken::colon)) + return true; + + if (!Name.empty()) { + BB = dyn_cast_or_null<BasicBlock>( + MF.getFunction()->getValueSymbolTable().lookup(Name)); + if (!BB) + return error(Loc, Twine("basic block '") + Name + + "' is not defined in the function '" + + MF.getName() + "'"); + } + auto *MBB = MF.CreateMachineBasicBlock(BB); + MF.insert(MF.end(), MBB); + bool WasInserted = MBBSlots.insert(std::make_pair(ID, MBB)).second; + if (!WasInserted) + return error(Loc, Twine("redefinition of machine basic block with id #") + + Twine(ID)); + if (Alignment) + MBB->setAlignment(Alignment); + if (HasAddressTaken) + MBB->setHasAddressTaken(); + MBB->setIsLandingPad(IsLandingPad); + return false; +} + +bool MIParser::parseBasicBlockDefinitions( + DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) { + lex(); + // Skip until the first machine basic block. + while (Token.is(MIToken::Newline)) + lex(); + if (Token.isErrorOrEOF()) + return Token.isError(); + if (Token.isNot(MIToken::MachineBasicBlockLabel)) + return error("expected a basic block definition before instructions"); + do { + if (parseBasicBlockDefinition(MBBSlots)) + return true; + bool IsAfterNewline = false; + // Skip until the next machine basic block. + while (true) { + if ((Token.is(MIToken::MachineBasicBlockLabel) && IsAfterNewline) || + Token.isErrorOrEOF()) + break; + else if (Token.is(MIToken::MachineBasicBlockLabel)) + return error("basic block definition should be located at the start of " + "the line"); + if (Token.is(MIToken::Newline)) + IsAfterNewline = true; + else + IsAfterNewline = false; + lex(); + } + } while (!Token.isErrorOrEOF()); + return Token.isError(); +} + +bool MIParser::parseBasicBlockLiveins(MachineBasicBlock &MBB) { + assert(Token.is(MIToken::kw_liveins)); + lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (Token.isNewlineOrEOF()) // Allow an empty list of liveins. + return false; + do { + if (Token.isNot(MIToken::NamedRegister)) + return error("expected a named register"); + unsigned Reg = 0; + if (parseRegister(Reg)) + return true; + MBB.addLiveIn(Reg); + lex(); + } while (consumeIfPresent(MIToken::comma)); + return false; +} + +bool MIParser::parseBasicBlockSuccessors(MachineBasicBlock &MBB) { + assert(Token.is(MIToken::kw_successors)); lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (Token.isNewlineOrEOF()) // Allow an empty list of successors. + return false; + do { + if (Token.isNot(MIToken::MachineBasicBlock)) + return error("expected a machine basic block reference"); + MachineBasicBlock *SuccMBB = nullptr; + if (parseMBBReference(SuccMBB)) + return true; + lex(); + unsigned Weight = 0; + if (consumeIfPresent(MIToken::lparen)) { + if (Token.isNot(MIToken::IntegerLiteral)) + return error("expected an integer literal after '('"); + if (getUnsigned(Weight)) + return true; + lex(); + if (expectAndConsume(MIToken::rparen)) + return true; + } + MBB.addSuccessor(SuccMBB, Weight); + } while (consumeIfPresent(MIToken::comma)); + return false; +} + +bool MIParser::parseBasicBlock(MachineBasicBlock &MBB) { + // Skip the definition. + assert(Token.is(MIToken::MachineBasicBlockLabel)); + lex(); + if (consumeIfPresent(MIToken::lparen)) { + while (Token.isNot(MIToken::rparen) && !Token.isErrorOrEOF()) + lex(); + consumeIfPresent(MIToken::rparen); + } + consumeIfPresent(MIToken::colon); + + // Parse the liveins and successors. + // N.B: Multiple lists of successors and liveins are allowed and they're + // merged into one. + // Example: + // liveins: %edi + // liveins: %esi + // + // is equivalent to + // liveins: %edi, %esi + while (true) { + if (Token.is(MIToken::kw_successors)) { + if (parseBasicBlockSuccessors(MBB)) + return true; + } else if (Token.is(MIToken::kw_liveins)) { + if (parseBasicBlockLiveins(MBB)) + return true; + } else if (consumeIfPresent(MIToken::Newline)) { + continue; + } else + break; + if (!Token.isNewlineOrEOF()) + return error("expected line break at the end of a list"); + lex(); + } + + // Parse the instructions. + while (true) { + if (Token.is(MIToken::MachineBasicBlockLabel) || Token.is(MIToken::Eof)) + return false; + else if (consumeIfPresent(MIToken::Newline)) + continue; + MachineInstr *MI = nullptr; + if (parse(MI)) + return true; + MBB.insert(MBB.end(), MI); + assert(Token.isNewlineOrEOF() && "MI is not fully parsed"); + lex(); + } + return false; +} + +bool MIParser::parseBasicBlocks() { + lex(); + // Skip until the first machine basic block. + while (Token.is(MIToken::Newline)) + lex(); + if (Token.isErrorOrEOF()) + return Token.isError(); + // The first parsing pass should have verified that this token is a MBB label + // in the 'parseBasicBlockDefinitions' method. + assert(Token.is(MIToken::MachineBasicBlockLabel)); + do { + MachineBasicBlock *MBB = nullptr; + if (parseMBBReference(MBB)) + return true; + if (parseBasicBlock(*MBB)) + return true; + // The method 'parseBasicBlock' should parse the whole block until the next + // block or the end of file. + assert(Token.is(MIToken::MachineBasicBlockLabel) || Token.is(MIToken::Eof)); + } while (Token.isNot(MIToken::Eof)); + return false; +} +bool MIParser::parse(MachineInstr *&MI) { // Parse any register operands before '=' MachineOperand MO = MachineOperand::CreateImm(0); SmallVector<MachineOperandWithLocation, 8> Operands; @@ -271,13 +519,13 @@ bool MIParser::parse(MachineInstr *&MI) { // TODO: Parse the bundle instruction flags. // Parse the remaining machine operands. - while (Token.isNot(MIToken::Eof) && Token.isNot(MIToken::kw_debug_location) && + while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_debug_location) && Token.isNot(MIToken::coloncolon)) { auto Loc = Token.location(); if (parseMachineOperandAndTargetFlags(MO)) return true; Operands.push_back(MachineOperandWithLocation(MO, Loc, Token.location())); - if (Token.is(MIToken::Eof) || Token.is(MIToken::coloncolon)) + if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon)) break; if (Token.isNot(MIToken::comma)) return error("expected ',' before the next machine operand"); @@ -299,12 +547,12 @@ bool MIParser::parse(MachineInstr *&MI) { SmallVector<MachineMemOperand *, 2> MemOperands; if (Token.is(MIToken::coloncolon)) { lex(); - while (Token.isNot(MIToken::Eof)) { + while (!Token.isNewlineOrEOF()) { MachineMemOperand *MemOp = nullptr; if (parseMachineMemoryOperand(MemOp)) return true; MemOperands.push_back(MemOp); - if (Token.is(MIToken::Eof)) + if (Token.isNewlineOrEOF()) break; if (Token.isNot(MIToken::comma)) return error("expected ',' before the next machine memory operand"); @@ -370,23 +618,6 @@ bool MIParser::parseStandaloneVirtualRegister(unsigned &Reg) { return false; } -bool MIParser::parseStandaloneIRBlockReference(const BasicBlock *&BB) { - lex(); - if (Token.isNot(MIToken::IRBlock)) - return error("expected an IR block reference"); - unsigned SlotNumber = 0; - if (getUnsigned(SlotNumber)) - return true; - BB = getIRBlock(SlotNumber); - if (!BB) - return error(Twine("use of undefined IR block '%ir-block.") + - Twine(SlotNumber) + "'"); - lex(); - if (Token.isNot(MIToken::Eof)) - return error("expected end of string after the IR block reference"); - return false; -} - static const char *printImplicitRegisterFlag(const MachineOperand &MO) { assert(MO.isImplicit()); return MO.isDef() ? "implicit-def" : "implicit"; @@ -621,7 +852,8 @@ bool MIParser::getUnsigned(unsigned &Result) { } bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) { - assert(Token.is(MIToken::MachineBasicBlock)); + assert(Token.is(MIToken::MachineBasicBlock) || + Token.is(MIToken::MachineBasicBlockLabel)); unsigned Number; if (getUnsigned(Number)) return true; @@ -1406,11 +1638,27 @@ bool MIParser::getDirectTargetFlag(StringRef Name, unsigned &Flag) { return false; } -bool llvm::parseMachineInstr(MachineInstr *&MI, SourceMgr &SM, - MachineFunction &MF, StringRef Src, - const PerFunctionMIParsingState &PFS, - const SlotMapping &IRSlots, SMDiagnostic &Error) { - return MIParser(SM, MF, Error, Src, PFS, IRSlots).parse(MI); +bool llvm::parseMachineBasicBlockDefinitions(MachineFunction &MF, StringRef Src, + PerFunctionMIParsingState &PFS, + const SlotMapping &IRSlots, + SMDiagnostic &Error) { + SourceMgr SM; + SM.AddNewSourceBuffer( + MemoryBuffer::getMemBuffer(Src, "", /*RequiresNullTerminator=*/false), + SMLoc()); + return MIParser(SM, MF, Error, Src, PFS, IRSlots) + .parseBasicBlockDefinitions(PFS.MBBSlots); +} + +bool llvm::parseMachineInstructions(MachineFunction &MF, StringRef Src, + const PerFunctionMIParsingState &PFS, + const SlotMapping &IRSlots, + SMDiagnostic &Error) { + SourceMgr SM; + SM.AddNewSourceBuffer( + MemoryBuffer::getMemBuffer(Src, "", /*RequiresNullTerminator=*/false), + SMLoc()); + return MIParser(SM, MF, Error, Src, PFS, IRSlots).parseBasicBlocks(); } bool llvm::parseMBBReference(MachineBasicBlock *&MBB, SourceMgr &SM, @@ -1437,12 +1685,3 @@ bool llvm::parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM, return MIParser(SM, MF, Error, Src, PFS, IRSlots) .parseStandaloneVirtualRegister(Reg); } - -bool llvm::parseIRBlockReference(const BasicBlock *&BB, SourceMgr &SM, - MachineFunction &MF, StringRef Src, - const PerFunctionMIParsingState &PFS, - const SlotMapping &IRSlots, - SMDiagnostic &Error) { - return MIParser(SM, MF, Error, Src, PFS, IRSlots) - .parseStandaloneIRBlockReference(BB); -} diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.h b/llvm/lib/CodeGen/MIRParser/MIParser.h index 92698f6e6d1..03408991f7c 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.h +++ b/llvm/lib/CodeGen/MIRParser/MIParser.h @@ -36,9 +36,36 @@ struct PerFunctionMIParsingState { DenseMap<unsigned, unsigned> JumpTableSlots; }; -bool parseMachineInstr(MachineInstr *&MI, SourceMgr &SM, MachineFunction &MF, - StringRef Src, const PerFunctionMIParsingState &PFS, - const SlotMapping &IRSlots, SMDiagnostic &Error); +/// Parse the machine basic block definitions, and skip the machine +/// instructions. +/// +/// This function runs the first parsing pass on the machine function's body. +/// It parses only the machine basic block definitions and creates the machine +/// basic blocks in the given machine function. +/// +/// The machine instructions aren't parsed during the first pass because all +/// the machine basic blocks aren't defined yet - this makes it impossible to +/// resolve the machine basic block references. +/// +/// Return true if an error occurred. +bool parseMachineBasicBlockDefinitions(MachineFunction &MF, StringRef Src, + PerFunctionMIParsingState &PFS, + const SlotMapping &IRSlots, + SMDiagnostic &Error); + +/// Parse the machine instructions. +/// +/// This function runs the second parsing pass on the machine function's body. +/// It skips the machine basic block definitions and parses only the machine +/// instructions and basic block attributes like liveins and successors. +/// +/// The second parsing pass assumes that the first parsing pass already ran +/// on the given source string. +/// +/// Return true if an error occurred. +bool parseMachineInstructions(MachineFunction &MF, StringRef Src, + const PerFunctionMIParsingState &PFS, + const SlotMapping &IRSlots, SMDiagnostic &Error); bool parseMBBReference(MachineBasicBlock *&MBB, SourceMgr &SM, MachineFunction &MF, StringRef Src, @@ -57,11 +84,6 @@ bool parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM, const SlotMapping &IRSlots, SMDiagnostic &Error); -bool parseIRBlockReference(const BasicBlock *&BB, SourceMgr &SM, - MachineFunction &MF, StringRef Src, - const PerFunctionMIParsingState &PFS, - const SlotMapping &IRSlots, SMDiagnostic &Error); - } // end namespace llvm #endif diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp index a9cbbc390d7..a0279fa7119 100644 --- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp @@ -96,13 +96,6 @@ public: /// Return true if error occurred. bool initializeMachineFunction(MachineFunction &MF); - /// Initialize the machine basic block using it's YAML representation. - /// - /// Return true if an error occurred. - bool initializeMachineBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB, - const yaml::MachineBasicBlock &YamlMBB, - const PerFunctionMIParsingState &PFS); - bool initializeRegisterInfo(MachineFunction &MF, const yaml::MachineFunction &YamlMF, PerFunctionMIParsingState &PFS); @@ -294,36 +287,15 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) { return true; } - const auto &F = *MF.getFunction(); - for (const auto &YamlMBB : YamlMF.BasicBlocks) { - const BasicBlock *BB = nullptr; - const yaml::StringValue &Name = YamlMBB.Name; - const yaml::StringValue &IRBlock = YamlMBB.IRBlock; - if (!Name.Value.empty()) { - BB = dyn_cast_or_null<BasicBlock>( - F.getValueSymbolTable().lookup(Name.Value)); - if (!BB) - return error(Name.SourceRange.Start, - Twine("basic block '") + Name.Value + - "' is not defined in the function '" + MF.getName() + - "'"); - } - if (!IRBlock.Value.empty()) { - // TODO: Report an error when both name and ir block are specified. - SMDiagnostic Error; - if (parseIRBlockReference(BB, SM, MF, IRBlock.Value, PFS, IRSlots, Error)) - return error(Error, IRBlock.SourceRange); - } - auto *MBB = MF.CreateMachineBasicBlock(BB); - MF.insert(MF.end(), MBB); - bool WasInserted = - PFS.MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second; - if (!WasInserted) - return error(Twine("redefinition of machine basic block with id #") + - Twine(YamlMBB.ID)); + SMDiagnostic Error; + if (parseMachineBasicBlockDefinitions(MF, YamlMF.Body.Value.Value, PFS, + IRSlots, Error)) { + reportDiagnostic( + diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange)); + return true; } - if (YamlMF.BasicBlocks.empty()) + if (MF.empty()) return error(Twine("machine function '") + Twine(MF.getName()) + "' requires at least one machine basic block in its body"); // Initialize the frame information after creating all the MBBs so that the @@ -335,13 +307,13 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) { if (!YamlMF.JumpTableInfo.Entries.empty() && initializeJumpTableInfo(MF, YamlMF.JumpTableInfo, PFS)) return true; - // Initialize the machine basic blocks after creating them all so that the - // machine instructions parser can resolve the MBB references. - unsigned I = 0; - for (const auto &YamlMBB : YamlMF.BasicBlocks) { - if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB, - PFS)) - return true; + // Parse the machine instructions after creating all of the MBBs so that the + // parser can resolve the MBB references. + if (parseMachineInstructions(MF, YamlMF.Body.Value.Value, PFS, IRSlots, + Error)) { + reportDiagnostic( + diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange)); + return true; } inferRegisterInfo(MF, YamlMF); // FIXME: This is a temporary workaround until the reserved registers can be @@ -351,53 +323,6 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) { return false; } -bool MIRParserImpl::initializeMachineBasicBlock( - MachineFunction &MF, MachineBasicBlock &MBB, - const yaml::MachineBasicBlock &YamlMBB, - const PerFunctionMIParsingState &PFS) { - MBB.setAlignment(YamlMBB.Alignment); - if (YamlMBB.AddressTaken) - MBB.setHasAddressTaken(); - MBB.setIsLandingPad(YamlMBB.IsLandingPad); - SMDiagnostic Error; - // Parse the successors. - const auto &Weights = YamlMBB.SuccessorWeights; - bool HasWeights = !Weights.empty(); - if (HasWeights && Weights.size() != YamlMBB.Successors.size()) { - bool IsFew = Weights.size() < YamlMBB.Successors.size(); - return error(IsFew ? Weights.back().SourceRange.End - : Weights[YamlMBB.Successors.size()].SourceRange.Start, - Twine("too ") + (IsFew ? "few" : "many") + - " successor weights, expected " + - Twine(YamlMBB.Successors.size()) + ", have " + - Twine(Weights.size())); - } - size_t SuccessorIndex = 0; - for (const auto &MBBSource : YamlMBB.Successors) { - MachineBasicBlock *SuccMBB = nullptr; - if (parseMBBReference(SuccMBB, MBBSource, MF, PFS)) - return true; - // TODO: Report an error when adding the same successor more than once. - MBB.addSuccessor(SuccMBB, HasWeights ? Weights[SuccessorIndex++].Value : 0); - } - // Parse the liveins. - for (const auto &LiveInSource : YamlMBB.LiveIns) { - unsigned Reg = 0; - if (parseNamedRegisterReference(Reg, SM, MF, LiveInSource.Value, PFS, - IRSlots, Error)) - return error(Error, LiveInSource.SourceRange); - MBB.addLiveIn(Reg); - } - // Parse the instructions. - for (const auto &MISource : YamlMBB.Instructions) { - MachineInstr *MI = nullptr; - if (parseMachineInstr(MI, SM, MF, MISource.Value, PFS, IRSlots, Error)) - return error(Error, MISource.SourceRange); - MBB.insert(MBB.end(), MI); - } - return false; -} - bool MIRParserImpl::initializeRegisterInfo(MachineFunction &MF, const yaml::MachineFunction &YamlMF, PerFunctionMIParsingState &PFS) { |