diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
| commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
| tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/CodeGen/MIRParser/MIParser.cpp | |
| parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/MIRParser/MIParser.cpp')
| -rw-r--r-- | lib/CodeGen/MIRParser/MIParser.cpp | 227 |
1 files changed, 209 insertions, 18 deletions
diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index a61e7872f1ae..6f2d8bb53ac8 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" +#include "llvm/Analysis/MemoryLocation.h" #include "llvm/AsmParser/Parser.h" #include "llvm/AsmParser/SlotMapping.h" #include "llvm/CodeGen/MIRPrinter.h" @@ -54,6 +55,7 @@ #include "llvm/IR/Value.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/MC/LaneBitmask.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCRegisterInfo.h" @@ -221,8 +223,10 @@ public: bool parseSubRegisterIndexOperand(MachineOperand &Dest); bool parseJumpTableIndexOperand(MachineOperand &Dest); bool parseExternalSymbolOperand(MachineOperand &Dest); + bool parseMCSymbolOperand(MachineOperand &Dest); bool parseMDNode(MDNode *&Node); bool parseDIExpression(MDNode *&Expr); + bool parseDILocation(MDNode *&Expr); bool parseMetadataOperand(MachineOperand &Dest); bool parseCFIOffset(int &Offset); bool parseCFIRegister(unsigned &Reg); @@ -250,6 +254,7 @@ public: bool parseOptionalScope(LLVMContext &Context, SyncScope::ID &SSID); bool parseOptionalAtomicOrdering(AtomicOrdering &Order); bool parseMachineMemoryOperand(MachineMemOperand *&Dest); + bool parsePreOrPostInstrSymbol(MCSymbol *&Symbol); private: /// Convert the integer literal in the current token into an unsigned integer. @@ -346,6 +351,9 @@ private: /// Return true if the name isn't a name of a target MMO flag. bool getMMOTargetFlag(StringRef Name, MachineMemOperand::Flags &Flag); + /// Get or create an MCSymbol for a given name. + MCSymbol *getOrCreateMCSymbol(StringRef Name); + /// parseStringConstant /// ::= StringConstant bool parseStringConstant(std::string &Result); @@ -737,12 +745,16 @@ bool MIParser::parse(MachineInstr *&MI) { return true; // Parse the remaining machine operands. - while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_debug_location) && + while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_pre_instr_symbol) && + Token.isNot(MIToken::kw_post_instr_symbol) && + Token.isNot(MIToken::kw_debug_location) && Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) { auto Loc = Token.location(); Optional<unsigned> TiedDefIdx; if (parseMachineOperandAndTargetFlags(MO, TiedDefIdx)) return true; + if (OpCode == TargetOpcode::DBG_VALUE && MO.isReg()) + MO.setIsDebug(); Operands.push_back( ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx)); if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) || @@ -753,14 +765,29 @@ bool MIParser::parse(MachineInstr *&MI) { lex(); } + MCSymbol *PreInstrSymbol = nullptr; + if (Token.is(MIToken::kw_pre_instr_symbol)) + if (parsePreOrPostInstrSymbol(PreInstrSymbol)) + return true; + MCSymbol *PostInstrSymbol = nullptr; + if (Token.is(MIToken::kw_post_instr_symbol)) + if (parsePreOrPostInstrSymbol(PostInstrSymbol)) + return true; + DebugLoc DebugLocation; if (Token.is(MIToken::kw_debug_location)) { lex(); - if (Token.isNot(MIToken::exclaim)) - return error("expected a metadata node after 'debug-location'"); MDNode *Node = nullptr; - if (parseMDNode(Node)) - return true; + if (Token.is(MIToken::exclaim)) { + if (parseMDNode(Node)) + return true; + } else if (Token.is(MIToken::md_dilocation)) { + if (parseDILocation(Node)) + return true; + } else + return error("expected a metadata node after 'debug-location'"); + if (!isa<DILocation>(Node)) + return error("referenced metadata is not a DILocation"); DebugLocation = DebugLoc(Node); } @@ -795,12 +822,12 @@ bool MIParser::parse(MachineInstr *&MI) { MI->addOperand(MF, Operand.Operand); if (assignRegisterTies(*MI, Operands)) return true; - 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()); + if (PreInstrSymbol) + MI->setPreInstrSymbol(MF, PreInstrSymbol); + if (PostInstrSymbol) + MI->setPostInstrSymbol(MF, PostInstrSymbol); + if (!MemOperands.empty()) + MI->setMemRefs(MF, MemOperands); return false; } @@ -876,6 +903,9 @@ bool MIParser::parseStandaloneMDNode(MDNode *&Node) { } else if (Token.is(MIToken::md_diexpr)) { if (parseDIExpression(Node)) return true; + } else if (Token.is(MIToken::md_dilocation)) { + if (parseDILocation(Node)) + return true; } else return error("expected a metadata node"); if (Token.isNot(MIToken::Eof)) @@ -945,7 +975,10 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) { Token.is(MIToken::kw_arcp) || Token.is(MIToken::kw_contract) || Token.is(MIToken::kw_afn) || - Token.is(MIToken::kw_reassoc)) { + Token.is(MIToken::kw_reassoc) || + Token.is(MIToken::kw_nuw) || + Token.is(MIToken::kw_nsw) || + Token.is(MIToken::kw_exact)) { // Mine frame and fast math flags if (Token.is(MIToken::kw_frame_setup)) Flags |= MachineInstr::FrameSetup; @@ -965,6 +998,12 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) { Flags |= MachineInstr::FmAfn; if (Token.is(MIToken::kw_reassoc)) Flags |= MachineInstr::FmReassoc; + if (Token.is(MIToken::kw_nuw)) + Flags |= MachineInstr::NoUWrap; + if (Token.is(MIToken::kw_nsw)) + Flags |= MachineInstr::NoSWrap; + if (Token.is(MIToken::kw_exact)) + Flags |= MachineInstr::IsExact; lex(); } @@ -1573,6 +1612,16 @@ bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) { return false; } +bool MIParser::parseMCSymbolOperand(MachineOperand &Dest) { + assert(Token.is(MIToken::MCSymbol)); + MCSymbol *Symbol = getOrCreateMCSymbol(Token.stringValue()); + lex(); + Dest = MachineOperand::CreateMCSymbol(Symbol); + if (parseOperandsOffset(Dest)) + return true; + return false; +} + bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) { assert(Token.is(MIToken::SubRegisterIndex)); StringRef Name = Token.stringValue(); @@ -1643,6 +1692,109 @@ bool MIParser::parseDIExpression(MDNode *&Expr) { return false; } +bool MIParser::parseDILocation(MDNode *&Loc) { + assert(Token.is(MIToken::md_dilocation)); + lex(); + + bool HaveLine = false; + unsigned Line = 0; + unsigned Column = 0; + MDNode *Scope = nullptr; + MDNode *InlinedAt = nullptr; + bool ImplicitCode = false; + + if (expectAndConsume(MIToken::lparen)) + return true; + + if (Token.isNot(MIToken::rparen)) { + do { + if (Token.is(MIToken::Identifier)) { + if (Token.stringValue() == "line") { + lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (Token.isNot(MIToken::IntegerLiteral) || + Token.integerValue().isSigned()) + return error("expected unsigned integer"); + Line = Token.integerValue().getZExtValue(); + HaveLine = true; + lex(); + continue; + } + if (Token.stringValue() == "column") { + lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (Token.isNot(MIToken::IntegerLiteral) || + Token.integerValue().isSigned()) + return error("expected unsigned integer"); + Column = Token.integerValue().getZExtValue(); + lex(); + continue; + } + if (Token.stringValue() == "scope") { + lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (parseMDNode(Scope)) + return error("expected metadata node"); + if (!isa<DIScope>(Scope)) + return error("expected DIScope node"); + continue; + } + if (Token.stringValue() == "inlinedAt") { + lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (Token.is(MIToken::exclaim)) { + if (parseMDNode(InlinedAt)) + return true; + } else if (Token.is(MIToken::md_dilocation)) { + if (parseDILocation(InlinedAt)) + return true; + } else + return error("expected metadata node"); + if (!isa<DILocation>(InlinedAt)) + return error("expected DILocation node"); + continue; + } + if (Token.stringValue() == "isImplicitCode") { + lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (!Token.is(MIToken::Identifier)) + return error("expected true/false"); + // As far as I can see, we don't have any existing need for parsing + // true/false in MIR yet. Do it ad-hoc until there's something else + // that needs it. + if (Token.stringValue() == "true") + ImplicitCode = true; + else if (Token.stringValue() == "false") + ImplicitCode = false; + else + return error("expected true/false"); + lex(); + continue; + } + } + return error(Twine("invalid DILocation argument '") + + Token.stringValue() + "'"); + } while (consumeIfPresent(MIToken::comma)); + } + + if (expectAndConsume(MIToken::rparen)) + return true; + + if (!HaveLine) + return error("DILocation requires line number"); + if (!Scope) + return error("DILocation requires a scope"); + + Loc = DILocation::get(MF.getFunction().getContext(), Line, Column, Scope, + InlinedAt, ImplicitCode); + return false; +} + bool MIParser::parseMetadataOperand(MachineOperand &Dest) { MDNode *Node = nullptr; if (Token.is(MIToken::exclaim)) { @@ -1779,6 +1931,9 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) { case MIToken::kw_cfi_window_save: CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr)); break; + case MIToken::kw_cfi_aarch64_negate_ra_sign_state: + CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); + break; case MIToken::kw_cfi_escape: { std::string Values; if (parseCFIEscapeValues(Values)) @@ -2050,6 +2205,8 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest, return parseJumpTableIndexOperand(Dest); case MIToken::ExternalSymbol: return parseExternalSymbolOperand(Dest); + case MIToken::MCSymbol: + return parseMCSymbolOperand(Dest); case MIToken::SubRegisterIndex: return parseSubRegisterIndexOperand(Dest); case MIToken::md_diexpr: @@ -2069,6 +2226,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest, case MIToken::kw_cfi_restore_state: case MIToken::kw_cfi_undefined: case MIToken::kw_cfi_window_save: + case MIToken::kw_cfi_aarch64_negate_ra_sign_state: return parseCFIOperand(Dest); case MIToken::kw_blockaddress: return parseBlockAddressOperand(Dest); @@ -2423,7 +2581,7 @@ bool MIParser::parseOptionalAtomicOrdering(AtomicOrdering &Order) { return false; } - return error("expected an atomic scope, ordering or a size integer literal"); + return error("expected an atomic scope, ordering or a size specification"); } bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) { @@ -2462,11 +2620,17 @@ bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) { if (parseOptionalAtomicOrdering(FailureOrder)) return true; - if (Token.isNot(MIToken::IntegerLiteral)) - return error("expected the size integer literal after memory operation"); + if (Token.isNot(MIToken::IntegerLiteral) && + Token.isNot(MIToken::kw_unknown_size)) + return error("expected the size integer literal or 'unknown-size' after " + "memory operation"); uint64_t Size; - if (getUint64(Size)) - return true; + if (Token.is(MIToken::IntegerLiteral)) { + if (getUint64(Size)) + return true; + } else if (Token.is(MIToken::kw_unknown_size)) { + Size = MemoryLocation::UnknownSize; + } lex(); MachinePointerInfo Ptr = MachinePointerInfo(); @@ -2483,7 +2647,7 @@ bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) { if (parseMachinePointerInfo(Ptr)) return true; } - unsigned BaseAlignment = Size; + unsigned BaseAlignment = (Size != MemoryLocation::UnknownSize ? Size : 1); AAMDNodes AAInfo; MDNode *Range = nullptr; while (consumeIfPresent(MIToken::comma)) { @@ -2529,6 +2693,24 @@ bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) { return false; } +bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) { + assert((Token.is(MIToken::kw_pre_instr_symbol) || + Token.is(MIToken::kw_post_instr_symbol)) && + "Invalid token for a pre- post-instruction symbol!"); + lex(); + if (Token.isNot(MIToken::MCSymbol)) + return error("expected a symbol after 'pre-instr-symbol'"); + Symbol = getOrCreateMCSymbol(Token.stringValue()); + lex(); + if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) || + Token.is(MIToken::lbrace)) + return false; + if (Token.isNot(MIToken::comma)) + return error("expected ',' before the next machine operand"); + lex(); + return false; +} + void MIParser::initNames2InstrOpCodes() { if (!Names2InstrOpCodes.empty()) return; @@ -2759,6 +2941,15 @@ bool MIParser::getMMOTargetFlag(StringRef Name, return false; } +MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) { + // FIXME: Currently we can't recognize temporary or local symbols and call all + // of the appropriate forms to create them. However, this handles basic cases + // well as most of the special aspects are recognized by a prefix on their + // name, and the input names should already be unique. For test cases, keeping + // the symbol name out of the symbol table isn't terribly important. + return MF.getContext().getOrCreateSymbol(Name); +} + bool MIParser::parseStringConstant(std::string &Result) { if (Token.isNot(MIToken::StringConstant)) return error("expected string constant"); |
