diff options
Diffstat (limited to 'lib/CodeGen/MIRParser/MIParser.cpp')
-rw-r--r-- | lib/CodeGen/MIRParser/MIParser.cpp | 150 |
1 files changed, 122 insertions, 28 deletions
diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index 1a78ae3aad07..a61e7872f1ae 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -98,6 +98,18 @@ VRegInfo &PerFunctionMIParsingState::getVRegInfo(unsigned Num) { return *I.first->second; } +VRegInfo &PerFunctionMIParsingState::getVRegInfoNamed(StringRef RegName) { + assert(RegName != "" && "Expected named reg."); + + auto I = VRegInfosNamed.insert(std::make_pair(RegName.str(), nullptr)); + if (I.second) { + VRegInfo *Info = new (Allocator) VRegInfo; + Info->VReg = MF.getRegInfo().createIncompleteVirtualRegister(RegName); + I.first->second = Info; + } + return *I.first->second; +} + namespace { /// A wrapper struct around the 'MachineOperand' struct that includes a source @@ -182,6 +194,7 @@ public: bool parseNamedRegister(unsigned &Reg); bool parseVirtualRegister(VRegInfo *&Info); + bool parseNamedVirtualRegister(VRegInfo *&Info); bool parseRegister(unsigned &Reg, VRegInfo *&VRegInfo); bool parseRegisterFlag(unsigned &Flags); bool parseRegisterClassOrBank(VRegInfo &RegInfo); @@ -190,7 +203,7 @@ public: bool parseRegisterOperand(MachineOperand &Dest, Optional<unsigned> &TiedDefIdx, bool IsDef = false); bool parseImmediateOperand(MachineOperand &Dest); - bool parseIRConstant(StringRef::iterator Loc, StringRef Source, + bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue, const Constant *&C); bool parseIRConstant(StringRef::iterator Loc, const Constant *&C); bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty); @@ -209,7 +222,7 @@ public: bool parseJumpTableIndexOperand(MachineOperand &Dest); bool parseExternalSymbolOperand(MachineOperand &Dest); bool parseMDNode(MDNode *&Node); - bool parseDIExpression(MDNode *&Node); + bool parseDIExpression(MDNode *&Expr); bool parseMetadataOperand(MachineOperand &Dest); bool parseCFIOffset(int &Offset); bool parseCFIRegister(unsigned &Reg); @@ -228,6 +241,7 @@ public: Optional<unsigned> &TiedDefIdx); bool parseOffset(int64_t &Offset); bool parseAlignment(unsigned &Alignment); + bool parseAddrspace(unsigned &Addrspace); bool parseOperandsOffset(MachineOperand &Op); bool parseIRValue(const Value *&V); bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags); @@ -915,15 +929,43 @@ bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands, continue; return error(Operands.empty() ? Token.location() : Operands.back().End, Twine("missing implicit register operand '") + - printImplicitRegisterFlag(I) + " %" + + printImplicitRegisterFlag(I) + " $" + getRegisterName(TRI, I.getReg()) + "'"); } return false; } bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) { - if (Token.is(MIToken::kw_frame_setup)) { - Flags |= MachineInstr::FrameSetup; + // Allow frame and fast math flags for OPCODE + while (Token.is(MIToken::kw_frame_setup) || + Token.is(MIToken::kw_frame_destroy) || + Token.is(MIToken::kw_nnan) || + Token.is(MIToken::kw_ninf) || + Token.is(MIToken::kw_nsz) || + Token.is(MIToken::kw_arcp) || + Token.is(MIToken::kw_contract) || + Token.is(MIToken::kw_afn) || + Token.is(MIToken::kw_reassoc)) { + // Mine frame and fast math flags + if (Token.is(MIToken::kw_frame_setup)) + Flags |= MachineInstr::FrameSetup; + if (Token.is(MIToken::kw_frame_destroy)) + Flags |= MachineInstr::FrameDestroy; + if (Token.is(MIToken::kw_nnan)) + Flags |= MachineInstr::FmNoNans; + if (Token.is(MIToken::kw_ninf)) + Flags |= MachineInstr::FmNoInfs; + if (Token.is(MIToken::kw_nsz)) + Flags |= MachineInstr::FmNsz; + if (Token.is(MIToken::kw_arcp)) + Flags |= MachineInstr::FmArcp; + if (Token.is(MIToken::kw_contract)) + Flags |= MachineInstr::FmContract; + if (Token.is(MIToken::kw_afn)) + Flags |= MachineInstr::FmAfn; + if (Token.is(MIToken::kw_reassoc)) + Flags |= MachineInstr::FmReassoc; + lex(); } if (Token.isNot(MIToken::Identifier)) @@ -943,7 +985,18 @@ bool MIParser::parseNamedRegister(unsigned &Reg) { return false; } +bool MIParser::parseNamedVirtualRegister(VRegInfo *&Info) { + assert(Token.is(MIToken::NamedVirtualRegister) && "Expected NamedVReg token"); + StringRef Name = Token.stringValue(); + // TODO: Check that the VReg name is not the same as a physical register name. + // If it is, then print a warning (when warnings are implemented). + Info = &PFS.getVRegInfoNamed(Name); + return false; +} + bool MIParser::parseVirtualRegister(VRegInfo *&Info) { + if (Token.is(MIToken::NamedVirtualRegister)) + return parseNamedVirtualRegister(Info); assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token"); unsigned ID; if (getUnsigned(ID)) @@ -959,6 +1012,7 @@ bool MIParser::parseRegister(unsigned &Reg, VRegInfo *&Info) { return false; case MIToken::NamedRegister: return parseNamedRegister(Reg); + case MIToken::NamedVirtualRegister: case MIToken::VirtualRegister: if (parseVirtualRegister(Info)) return true; @@ -1249,11 +1303,17 @@ bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) { } bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) { - if (Token.is(MIToken::ScalarType)) { + if (Token.range().front() == 's' || Token.range().front() == 'p') { + StringRef SizeStr = Token.range().drop_front(); + if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) + return error("expected integers after 's'/'p' type character"); + } + + if (Token.range().front() == 's') { Ty = LLT::scalar(APSInt(Token.range().drop_front()).getZExtValue()); lex(); return false; - } else if (Token.is(MIToken::PointerType)) { + } else if (Token.range().front() == 'p') { const DataLayout &DL = MF.getDataLayout(); unsigned AS = APSInt(Token.range().drop_front()).getZExtValue(); Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS)); @@ -1264,38 +1324,60 @@ bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) { // Now we're looking for a vector. if (Token.isNot(MIToken::less)) return error(Loc, - "expected unsized, pN, sN or <N x sM> for GlobalISel type"); - + "expected sN, pA, <M x sN>, or <M x pA> for GlobalISel type"); lex(); if (Token.isNot(MIToken::IntegerLiteral)) - return error(Loc, "expected <N x sM> for vctor type"); + return error(Loc, "expected <M x sN> or <M x pA> for vector type"); uint64_t NumElements = Token.integerValue().getZExtValue(); lex(); if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x") - return error(Loc, "expected '<N x sM>' for vector type"); + return error(Loc, "expected <M x sN> or <M x pA> for vector type"); lex(); - if (Token.isNot(MIToken::ScalarType)) - return error(Loc, "expected '<N x sM>' for vector type"); - uint64_t ScalarSize = APSInt(Token.range().drop_front()).getZExtValue(); + if (Token.range().front() != 's' && Token.range().front() != 'p') + return error(Loc, "expected <M x sN> or <M x pA> for vector type"); + StringRef SizeStr = Token.range().drop_front(); + if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) + return error("expected integers after 's'/'p' type character"); + + if (Token.range().front() == 's') + Ty = LLT::scalar(APSInt(Token.range().drop_front()).getZExtValue()); + else if (Token.range().front() == 'p') { + const DataLayout &DL = MF.getDataLayout(); + unsigned AS = APSInt(Token.range().drop_front()).getZExtValue(); + Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS)); + } else + return error(Loc, "expected <M x sN> or <M x pA> for vector type"); lex(); if (Token.isNot(MIToken::greater)) - return error(Loc, "expected '<N x sM>' for vector type"); + return error(Loc, "expected <M x sN> or <M x pA> for vector type"); lex(); - Ty = LLT::vector(NumElements, ScalarSize); + Ty = LLT::vector(NumElements, Ty); return false; } bool MIParser::parseTypedImmediateOperand(MachineOperand &Dest) { - assert(Token.is(MIToken::IntegerType)); + assert(Token.is(MIToken::Identifier)); + StringRef TypeStr = Token.range(); + if (TypeStr.front() != 'i' && TypeStr.front() != 's' && + TypeStr.front() != 'p') + return error( + "a typed immediate operand should start with one of 'i', 's', or 'p'"); + StringRef SizeStr = Token.range().drop_front(); + if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) + return error("expected integers after 'i'/'s'/'p' type character"); + auto Loc = Token.location(); lex(); - if (Token.isNot(MIToken::IntegerLiteral)) - return error("expected an integer literal"); + if (Token.isNot(MIToken::IntegerLiteral)) { + if (Token.isNot(MIToken::Identifier) || + !(Token.range() == "true" || Token.range() == "false")) + return error("expected an integer literal"); + } const Constant *C = nullptr; if (parseIRConstant(Loc, C)) return true; @@ -1876,13 +1958,11 @@ bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) { bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) { assert(Token.stringValue() == "CustomRegMask" && "Expected a custom RegMask"); - const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); - assert(TRI && "Expected target register info"); lex(); if (expectAndConsume(MIToken::lparen)) return true; - uint32_t *Mask = MF.allocateRegisterMask(TRI->getNumRegs()); + uint32_t *Mask = MF.allocateRegMask(); while (true) { if (Token.isNot(MIToken::NamedRegister)) return error("expected a named register"); @@ -1905,9 +1985,7 @@ bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) { bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) { assert(Token.is(MIToken::kw_liveout)); - const auto *TRI = MF.getSubtarget().getRegisterInfo(); - assert(TRI && "Expected target register info"); - uint32_t *Mask = MF.allocateRegisterMask(TRI->getNumRegs()); + uint32_t *Mask = MF.allocateRegMask(); lex(); if (expectAndConsume(MIToken::lparen)) return true; @@ -1946,11 +2024,10 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest, case MIToken::underscore: case MIToken::NamedRegister: case MIToken::VirtualRegister: + case MIToken::NamedVirtualRegister: return parseRegisterOperand(Dest, TiedDefIdx); case MIToken::IntegerLiteral: return parseImmediateOperand(Dest); - case MIToken::IntegerType: - return parseTypedImmediateOperand(Dest); case MIToken::kw_half: case MIToken::kw_float: case MIToken::kw_double: @@ -2011,8 +2088,10 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest, Dest = MachineOperand::CreateRegMask(RegMask); lex(); break; - } else + } else if (Token.stringValue() == "CustomRegMask") { return parseCustomRegisterMaskOperand(Dest); + } else + return parseTypedImmediateOperand(Dest); default: // FIXME: Parse the MCSymbol machine operand. return error("expected a machine operand"); @@ -2091,6 +2170,17 @@ bool MIParser::parseAlignment(unsigned &Alignment) { return false; } +bool MIParser::parseAddrspace(unsigned &Addrspace) { + assert(Token.is(MIToken::kw_addrspace)); + lex(); + if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) + return error("expected an integer literal after 'addrspace'"); + if (getUnsigned(Addrspace)) + return true; + lex(); + return false; +} + bool MIParser::parseOperandsOffset(MachineOperand &Op) { int64_t Offset = 0; if (parseOffset(Offset)) @@ -2402,6 +2492,10 @@ bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) { if (parseAlignment(BaseAlignment)) return true; break; + case MIToken::kw_addrspace: + if (parseAddrspace(Ptr.AddrSpace)) + return true; + break; case MIToken::md_tbaa: lex(); if (parseMDNode(AAInfo.TBAA)) |