diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp')
-rw-r--r-- | contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp | 485 |
1 files changed, 346 insertions, 139 deletions
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp index b3fd16f..c8bed08 100644 --- a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -14,6 +14,7 @@ #include "MIParser.h" #include "MILexer.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/AsmParser/Parser.h" #include "llvm/AsmParser/SlotMapping.h" #include "llvm/CodeGen/MachineBasicBlock.h" @@ -26,13 +27,16 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/IR/ModuleSlotTracker.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetIntrinsicInfo.h" #include "llvm/Target/TargetSubtargetInfo.h" +#include <cctype> using namespace llvm; @@ -41,6 +45,17 @@ PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF, : MF(MF), SM(&SM), IRSlots(IRSlots) { } +VRegInfo &PerFunctionMIParsingState::getVRegInfo(unsigned Num) { + auto I = VRegInfos.insert(std::make_pair(Num, nullptr)); + if (I.second) { + MachineRegisterInfo &MRI = MF.getRegInfo(); + VRegInfo *Info = new (Allocator) VRegInfo; + Info->VReg = MRI.createIncompleteVirtualRegister(); + I.first->second = Info; + } + return *I.first->second; +} + namespace { /// A wrapper struct around the 'MachineOperand' struct that includes a source @@ -65,7 +80,7 @@ class MIParser { SMDiagnostic &Error; StringRef Source, CurrentSource; MIToken Token; - const PerFunctionMIParsingState &PFS; + PerFunctionMIParsingState &PFS; /// Maps from instruction names to op codes. StringMap<unsigned> Names2InstrOpCodes; /// Maps from register names to registers. @@ -86,7 +101,7 @@ class MIParser { StringMap<unsigned> Names2BitmaskTargetFlags; public: - MIParser(const PerFunctionMIParsingState &PFS, SMDiagnostic &Error, + MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, StringRef Source); /// \p SkipChar gives the number of characters to skip before looking @@ -109,7 +124,8 @@ public: bool parse(MachineInstr *&MI); bool parseStandaloneMBB(MachineBasicBlock *&MBB); bool parseStandaloneNamedRegister(unsigned &Reg); - bool parseStandaloneVirtualRegister(unsigned &Reg); + bool parseStandaloneVirtualRegister(VRegInfo *&Info); + bool parseStandaloneRegister(unsigned &Reg); bool parseStandaloneStackObject(int &FI); bool parseStandaloneMDNode(MDNode *&Node); @@ -119,21 +135,19 @@ public: bool parseBasicBlockLiveins(MachineBasicBlock &MBB); bool parseBasicBlockSuccessors(MachineBasicBlock &MBB); - bool parseRegister(unsigned &Reg); + bool parseNamedRegister(unsigned &Reg); + bool parseVirtualRegister(VRegInfo *&Info); + bool parseRegister(unsigned &Reg, VRegInfo *&VRegInfo); bool parseRegisterFlag(unsigned &Flags); bool parseSubRegisterIndex(unsigned &SubReg); bool parseRegisterTiedDefIndex(unsigned &TiedDefIdx); - bool parseSize(unsigned &Size); bool parseRegisterOperand(MachineOperand &Dest, Optional<unsigned> &TiedDefIdx, bool IsDef = false); bool parseImmediateOperand(MachineOperand &Dest); bool parseIRConstant(StringRef::iterator Loc, StringRef Source, const Constant *&C); bool parseIRConstant(StringRef::iterator Loc, const Constant *&C); - bool parseIRType(StringRef::iterator Loc, StringRef Source, unsigned &Read, - Type *&Ty); - // \p MustBeSized defines whether or not \p Ty must be sized. - bool parseIRType(StringRef::iterator Loc, Type *&Ty, bool MustBeSized = true); + bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty); bool parseTypedImmediateOperand(MachineOperand &Dest); bool parseFPImmediateOperand(MachineOperand &Dest); bool parseMBBReference(MachineBasicBlock *&MBB); @@ -155,6 +169,8 @@ public: bool parseCFIOperand(MachineOperand &Dest); bool parseIRBlock(BasicBlock *&BB, const Function &F); bool parseBlockAddressOperand(MachineOperand &Dest); + bool parseIntrinsicOperand(MachineOperand &Dest); + bool parsePredicateOperand(MachineOperand &Dest); bool parseTargetIndexOperand(MachineOperand &Dest); bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest); bool parseMachineOperand(MachineOperand &Dest, @@ -181,6 +197,12 @@ private: /// Return true if an error occurred. bool getUint64(uint64_t &Result); + /// Convert the hexadecimal literal in the current token into an unsigned + /// APInt with a minimum bitwidth required to represent the value. + /// + /// Return true if the literal does not represent an integer value. + bool getHexUint(APInt &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); @@ -254,7 +276,7 @@ private: } // end anonymous namespace -MIParser::MIParser(const PerFunctionMIParsingState &PFS, SMDiagnostic &Error, +MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, StringRef Source) : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), PFS(PFS) {} @@ -362,7 +384,7 @@ bool MIParser::parseBasicBlockDefinition( if (!Name.empty()) { BB = dyn_cast_or_null<BasicBlock>( - MF.getFunction()->getValueSymbolTable().lookup(Name)); + MF.getFunction()->getValueSymbolTable()->lookup(Name)); if (!BB) return error(Loc, Twine("basic block '") + Name + "' is not defined in the function '" + @@ -437,10 +459,24 @@ bool MIParser::parseBasicBlockLiveins(MachineBasicBlock &MBB) { if (Token.isNot(MIToken::NamedRegister)) return error("expected a named register"); unsigned Reg = 0; - if (parseRegister(Reg)) + if (parseNamedRegister(Reg)) return true; - MBB.addLiveIn(Reg); lex(); + LaneBitmask Mask = LaneBitmask::getAll(); + if (consumeIfPresent(MIToken::colon)) { + // Parse lane mask. + if (Token.isNot(MIToken::IntegerLiteral) && + Token.isNot(MIToken::HexLiteral)) + return error("expected a lane mask"); + static_assert(sizeof(LaneBitmask::Type) == sizeof(unsigned), + "Use correct get-function for lane mask"); + LaneBitmask::Type V; + if (getUnsigned(V)) + return error("invalid lane mask value"); + Mask = LaneBitmask(V); + lex(); + } + MBB.addLiveIn(Reg, Mask); } while (consumeIfPresent(MIToken::comma)); return false; } @@ -461,7 +497,8 @@ bool MIParser::parseBasicBlockSuccessors(MachineBasicBlock &MBB) { lex(); unsigned Weight = 0; if (consumeIfPresent(MIToken::lparen)) { - if (Token.isNot(MIToken::IntegerLiteral)) + if (Token.isNot(MIToken::IntegerLiteral) && + Token.isNot(MIToken::HexLiteral)) return error("expected an integer literal after '('"); if (getUnsigned(Weight)) return true; @@ -597,14 +634,6 @@ bool MIParser::parse(MachineInstr *&MI) { if (Token.isError() || parseInstruction(OpCode, Flags)) return true; - Type *Ty = nullptr; - if (isPreISelGenericOpcode(OpCode)) { - // For generic opcode, a type is mandatory. - auto Loc = Token.location(); - if (parseIRType(Loc, Ty)) - return true; - } - // Parse the remaining machine operands. while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_debug_location) && Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) { @@ -660,8 +689,6 @@ bool MIParser::parse(MachineInstr *&MI) { // TODO: Check for extraneous machine operands. MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true); MI->setFlags(Flags); - if (Ty) - MI->setType(Ty); for (const auto &Operand : Operands) MI->addOperand(MF, Operand.Operand); if (assignRegisterTies(*MI, Operands)) @@ -692,7 +719,7 @@ bool MIParser::parseStandaloneNamedRegister(unsigned &Reg) { lex(); if (Token.isNot(MIToken::NamedRegister)) return error("expected a named register"); - if (parseRegister(Reg)) + if (parseNamedRegister(Reg)) return true; lex(); if (Token.isNot(MIToken::Eof)) @@ -700,12 +727,28 @@ bool MIParser::parseStandaloneNamedRegister(unsigned &Reg) { return false; } -bool MIParser::parseStandaloneVirtualRegister(unsigned &Reg) { +bool MIParser::parseStandaloneVirtualRegister(VRegInfo *&Info) { lex(); if (Token.isNot(MIToken::VirtualRegister)) return error("expected a virtual register"); - if (parseRegister(Reg)) + if (parseVirtualRegister(Info)) + return true; + lex(); + if (Token.isNot(MIToken::Eof)) + return error("expected end of string after the register reference"); + return false; +} + +bool MIParser::parseStandaloneRegister(unsigned &Reg) { + lex(); + if (Token.isNot(MIToken::NamedRegister) && + Token.isNot(MIToken::VirtualRegister)) + return error("expected either a named or virtual register"); + + VRegInfo *Info; + if (parseRegister(Reg, Info)) return true; + lex(); if (Token.isNot(MIToken::Eof)) return error("expected end of string after the register reference"); @@ -800,33 +843,39 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) { return false; } -bool MIParser::parseRegister(unsigned &Reg) { +bool MIParser::parseNamedRegister(unsigned &Reg) { + assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token"); + StringRef Name = Token.stringValue(); + if (getRegisterByName(Name, Reg)) + return error(Twine("unknown register name '") + Name + "'"); + return false; +} + +bool MIParser::parseVirtualRegister(VRegInfo *&Info) { + assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token"); + unsigned ID; + if (getUnsigned(ID)) + return true; + Info = &PFS.getVRegInfo(ID); + return false; +} + +bool MIParser::parseRegister(unsigned &Reg, VRegInfo *&Info) { switch (Token.kind()) { case MIToken::underscore: Reg = 0; - break; - case MIToken::NamedRegister: { - StringRef Name = Token.stringValue(); - if (getRegisterByName(Name, Reg)) - return error(Twine("unknown register name '") + Name + "'"); - break; - } - case MIToken::VirtualRegister: { - unsigned ID; - if (getUnsigned(ID)) + return false; + case MIToken::NamedRegister: + return parseNamedRegister(Reg); + case MIToken::VirtualRegister: + if (parseVirtualRegister(Info)) return true; - const auto RegInfo = PFS.VirtualRegisterSlots.find(ID); - if (RegInfo == PFS.VirtualRegisterSlots.end()) - return error(Twine("use of undefined virtual register '%") + Twine(ID) + - "'"); - Reg = RegInfo->second; - break; - } + Reg = Info->VReg; + return false; // TODO: Parse other register kinds. default: llvm_unreachable("The current token should be a register"); } - return false; } bool MIParser::parseRegisterFlag(unsigned &Flags) { @@ -871,10 +920,10 @@ bool MIParser::parseRegisterFlag(unsigned &Flags) { } bool MIParser::parseSubRegisterIndex(unsigned &SubReg) { - assert(Token.is(MIToken::colon)); + assert(Token.is(MIToken::dot)); lex(); if (Token.isNot(MIToken::Identifier)) - return error("expected a subregister index after ':'"); + return error("expected a subregister index after '.'"); auto Name = Token.stringValue(); SubReg = getSubRegIndex(Name); if (!SubReg) @@ -885,7 +934,7 @@ bool MIParser::parseSubRegisterIndex(unsigned &SubReg) { bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) { if (!consumeIfPresent(MIToken::kw_tied_def)) - return error("expected 'tied-def' after '('"); + return true; if (Token.isNot(MIToken::IntegerLiteral)) return error("expected an integer literal after 'tied-def'"); if (getUnsigned(TiedDefIdx)) @@ -896,17 +945,6 @@ bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) { return false; } -bool MIParser::parseSize(unsigned &Size) { - if (Token.isNot(MIToken::IntegerLiteral)) - return error("expected an integer literal for the size"); - if (getUnsigned(Size)) - return true; - lex(); - if (expectAndConsume(MIToken::rparen)) - return true; - return false; -} - bool MIParser::assignRegisterTies(MachineInstr &MI, ArrayRef<ParsedMachineOperand> Operands) { SmallVector<std::pair<unsigned, unsigned>, 4> TiedRegisterPairs; @@ -947,7 +985,6 @@ bool MIParser::assignRegisterTies(MachineInstr &MI, bool MIParser::parseRegisterOperand(MachineOperand &Dest, Optional<unsigned> &TiedDefIdx, bool IsDef) { - unsigned Reg; unsigned Flags = IsDef ? RegState::Define : 0; while (Token.isRegisterFlag()) { if (parseRegisterFlag(Flags)) @@ -955,38 +992,62 @@ bool MIParser::parseRegisterOperand(MachineOperand &Dest, } if (!Token.isRegister()) return error("expected a register after register flags"); - if (parseRegister(Reg)) + unsigned Reg; + VRegInfo *RegInfo; + if (parseRegister(Reg, RegInfo)) return true; lex(); unsigned SubReg = 0; - if (Token.is(MIToken::colon)) { + if (Token.is(MIToken::dot)) { if (parseSubRegisterIndex(SubReg)) return true; if (!TargetRegisterInfo::isVirtualRegister(Reg)) return error("subregister index expects a virtual register"); } + MachineRegisterInfo &MRI = MF.getRegInfo(); if ((Flags & RegState::Define) == 0) { if (consumeIfPresent(MIToken::lparen)) { unsigned Idx; - if (parseRegisterTiedDefIndex(Idx)) - return true; - TiedDefIdx = Idx; + if (!parseRegisterTiedDefIndex(Idx)) + TiedDefIdx = Idx; + else { + // Try a redundant low-level type. + LLT Ty; + if (parseLowLevelType(Token.location(), Ty)) + return error("expected tied-def or low-level type after '('"); + + if (expectAndConsume(MIToken::rparen)) + return true; + + if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty) + return error("inconsistent type for generic virtual register"); + + MRI.setType(Reg, Ty); + } } } else if (consumeIfPresent(MIToken::lparen)) { - // Virtual registers may have a size with GlobalISel. + // Virtual registers may have a tpe with GlobalISel. if (!TargetRegisterInfo::isVirtualRegister(Reg)) - return error("unexpected size on physical register"); - unsigned Size; - if (parseSize(Size)) + return error("unexpected type on physical register"); + + LLT Ty; + if (parseLowLevelType(Token.location(), Ty)) return true; - MachineRegisterInfo &MRI = MF.getRegInfo(); - MRI.setSize(Reg, Size); - } else if (PFS.GenericVRegs.count(Reg)) { - // Generic virtual registers must have a size. - // If we end up here this means the size hasn't been specified and + if (expectAndConsume(MIToken::rparen)) + return true; + + if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty) + return error("inconsistent type for generic virtual register"); + + MRI.setType(Reg, Ty); + } else if (TargetRegisterInfo::isVirtualRegister(Reg)) { + // Generic virtual registers must have a type. + // If we end up here this means the type hasn't been specified and // this is bad! - return error("generic virtual registers must have a size"); + if (RegInfo->Kind == VRegInfo::GENERIC || + RegInfo->Kind == VRegInfo::REGBANK) + return error("generic virtual registers must have a type"); } Dest = MachineOperand::CreateReg( Reg, Flags & RegState::Define, Flags & RegState::Implicit, @@ -1010,7 +1071,7 @@ bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue, const Constant *&C) { auto Source = StringValue.str(); // The source has to be null terminated. SMDiagnostic Err; - C = parseConstantValue(Source.c_str(), Err, *MF.getFunction()->getParent(), + C = parseConstantValue(Source, Err, *MF.getFunction()->getParent(), &PFS.IRSlots); if (!C) return error(Loc + Err.getColumnNo(), Err.getMessage()); @@ -1024,35 +1085,45 @@ bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) { return false; } -bool MIParser::parseIRType(StringRef::iterator Loc, StringRef StringValue, - unsigned &Read, Type *&Ty) { - auto Source = StringValue.str(); // The source has to be null terminated. - SMDiagnostic Err; - Ty = parseTypeAtBeginning(Source.c_str(), Read, Err, - *MF.getFunction()->getParent(), &PFS.IRSlots); - if (!Ty) - return error(Loc + Err.getColumnNo(), Err.getMessage()); - return false; -} +bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) { + if (Token.is(MIToken::ScalarType)) { + Ty = LLT::scalar(APSInt(Token.range().drop_front()).getZExtValue()); + lex(); + return false; + } else if (Token.is(MIToken::PointerType)) { + const DataLayout &DL = MF.getFunction()->getParent()->getDataLayout(); + unsigned AS = APSInt(Token.range().drop_front()).getZExtValue(); + Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS)); + lex(); + return false; + } -bool MIParser::parseIRType(StringRef::iterator Loc, Type *&Ty, - bool MustBeSized) { - // At this point we enter in the IR world, i.e., to get the correct type, - // we need to hand off the whole string, not just the current token. - // E.g., <4 x i64> would give '<' as a token and there is not much - // the IR parser can do with that. - unsigned Read = 0; - if (parseIRType(Loc, StringRef(Loc), Read, Ty)) - return true; - // The type must be sized, otherwise there is not much the backend - // can do with it. - if (MustBeSized && !Ty->isSized()) - return error("expected a sized type"); - // The next token is Read characters from the Loc. - // However, the current location is not Loc, but Loc + the length of Token. - // Therefore, subtract the length of Token (range().end() - Loc) to the - // number of characters to skip before the next token. - lex(Read - (Token.range().end() - Loc)); + // 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"); + + lex(); + + if (Token.isNot(MIToken::IntegerLiteral)) + return error(Loc, "expected <N x sM> for vctor 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"); + 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(); + lex(); + + if (Token.isNot(MIToken::greater)) + return error(Loc, "expected '<N x sM>' for vector type"); + lex(); + + Ty = LLT::vector(NumElements, ScalarSize); return false; } @@ -1072,7 +1143,8 @@ bool MIParser::parseTypedImmediateOperand(MachineOperand &Dest) { bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) { auto Loc = Token.location(); lex(); - if (Token.isNot(MIToken::FloatingPointLiteral)) + if (Token.isNot(MIToken::FloatingPointLiteral) && + Token.isNot(MIToken::HexLiteral)) return error("expected a floating point literal"); const Constant *C = nullptr; if (parseIRConstant(Loc, C)) @@ -1082,13 +1154,24 @@ bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) { } bool MIParser::getUnsigned(unsigned &Result) { - assert(Token.hasIntegerValue() && "Expected a token with an integer value"); - const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1; - uint64_t Val64 = Token.integerValue().getLimitedValue(Limit); - if (Val64 == Limit) - return error("expected 32-bit integer (too large)"); - Result = Val64; - return false; + if (Token.hasIntegerValue()) { + const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1; + uint64_t Val64 = Token.integerValue().getLimitedValue(Limit); + if (Val64 == Limit) + return error("expected 32-bit integer (too large)"); + Result = Val64; + return false; + } + if (Token.is(MIToken::HexLiteral)) { + APInt A; + if (getHexUint(A)) + return true; + if (A.getBitWidth() > 32) + return error("expected 32-bit integer (too large)"); + Result = A.getZExtValue(); + return false; + } + return true; } bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) { @@ -1128,7 +1211,7 @@ bool MIParser::parseStackFrameIndex(int &FI) { "'"); StringRef Name; if (const auto *Alloca = - MF.getFrameInfo()->getObjectAllocation(ObjectInfo->second)) + MF.getFrameInfo().getObjectAllocation(ObjectInfo->second)) Name = Alloca->getName(); if (!Token.stringValue().empty() && Token.stringValue() != Name) return error(Twine("the name of the stack object '%stack.") + Twine(ID) + @@ -1293,7 +1376,7 @@ bool MIParser::parseCFIRegister(unsigned &Reg) { if (Token.isNot(MIToken::NamedRegister)) return error("expected a cfi register"); unsigned LLVMReg; - if (parseRegister(LLVMReg)) + if (parseNamedRegister(LLVMReg)) return true; const auto *TRI = MF.getSubtarget().getRegisterInfo(); assert(TRI && "Expected target register info"); @@ -1308,7 +1391,6 @@ bool MIParser::parseCFIRegister(unsigned &Reg) { bool MIParser::parseCFIOperand(MachineOperand &Dest) { auto Kind = Token.kind(); lex(); - auto &MMI = MF.getMMI(); int Offset; unsigned Reg; unsigned CFIIndex; @@ -1316,27 +1398,26 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) { case MIToken::kw_cfi_same_value: if (parseCFIRegister(Reg)) return true; - CFIIndex = - MMI.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg)); + CFIIndex = MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg)); break; case MIToken::kw_cfi_offset: if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || parseCFIOffset(Offset)) return true; CFIIndex = - MMI.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset)); + MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset)); break; case MIToken::kw_cfi_def_cfa_register: if (parseCFIRegister(Reg)) return true; CFIIndex = - MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg)); + MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg)); break; case MIToken::kw_cfi_def_cfa_offset: if (parseCFIOffset(Offset)) return true; // NB: MCCFIInstruction::createDefCfaOffset negates the offset. - CFIIndex = MMI.addFrameInst( + CFIIndex = MF.addFrameInst( MCCFIInstruction::createDefCfaOffset(nullptr, -Offset)); break; case MIToken::kw_cfi_def_cfa: @@ -1345,7 +1426,7 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) { return true; // NB: MCCFIInstruction::createDefCfa negates the offset. CFIIndex = - MMI.addFrameInst(MCCFIInstruction::createDefCfa(nullptr, Reg, -Offset)); + MF.addFrameInst(MCCFIInstruction::createDefCfa(nullptr, Reg, -Offset)); break; default: // TODO: Parse the other CFI operands. @@ -1359,7 +1440,7 @@ bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) { switch (Token.kind()) { case MIToken::NamedIRBlock: { BB = dyn_cast_or_null<BasicBlock>( - F.getValueSymbolTable().lookup(Token.stringValue())); + F.getValueSymbolTable()->lookup(Token.stringValue())); if (!BB) return error(Twine("use of undefined IR block '") + Token.range() + "'"); break; @@ -1411,6 +1492,93 @@ bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) { return false; } +bool MIParser::parseIntrinsicOperand(MachineOperand &Dest) { + assert(Token.is(MIToken::kw_intrinsic)); + lex(); + if (expectAndConsume(MIToken::lparen)) + return error("expected syntax intrinsic(@llvm.whatever)"); + + if (Token.isNot(MIToken::NamedGlobalValue)) + return error("expected syntax intrinsic(@llvm.whatever)"); + + std::string Name = Token.stringValue(); + lex(); + + if (expectAndConsume(MIToken::rparen)) + return error("expected ')' to terminate intrinsic name"); + + // Find out what intrinsic we're dealing with, first try the global namespace + // and then the target's private intrinsics if that fails. + const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo(); + Intrinsic::ID ID = Function::lookupIntrinsicID(Name); + if (ID == Intrinsic::not_intrinsic && TII) + ID = static_cast<Intrinsic::ID>(TII->lookupName(Name)); + + if (ID == Intrinsic::not_intrinsic) + return error("unknown intrinsic name"); + Dest = MachineOperand::CreateIntrinsicID(ID); + + return false; +} + +bool MIParser::parsePredicateOperand(MachineOperand &Dest) { + assert(Token.is(MIToken::kw_intpred) || Token.is(MIToken::kw_floatpred)); + bool IsFloat = Token.is(MIToken::kw_floatpred); + lex(); + + if (expectAndConsume(MIToken::lparen)) + return error("expected syntax intpred(whatever) or floatpred(whatever"); + + if (Token.isNot(MIToken::Identifier)) + return error("whatever"); + + CmpInst::Predicate Pred; + if (IsFloat) { + Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue()) + .Case("false", CmpInst::FCMP_FALSE) + .Case("oeq", CmpInst::FCMP_OEQ) + .Case("ogt", CmpInst::FCMP_OGT) + .Case("oge", CmpInst::FCMP_OGE) + .Case("olt", CmpInst::FCMP_OLT) + .Case("ole", CmpInst::FCMP_OLE) + .Case("one", CmpInst::FCMP_ONE) + .Case("ord", CmpInst::FCMP_ORD) + .Case("uno", CmpInst::FCMP_UNO) + .Case("ueq", CmpInst::FCMP_UEQ) + .Case("ugt", CmpInst::FCMP_UGT) + .Case("uge", CmpInst::FCMP_UGE) + .Case("ult", CmpInst::FCMP_ULT) + .Case("ule", CmpInst::FCMP_ULE) + .Case("une", CmpInst::FCMP_UNE) + .Case("true", CmpInst::FCMP_TRUE) + .Default(CmpInst::BAD_FCMP_PREDICATE); + if (!CmpInst::isFPPredicate(Pred)) + return error("invalid floating-point predicate"); + } else { + Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue()) + .Case("eq", CmpInst::ICMP_EQ) + .Case("ne", CmpInst::ICMP_NE) + .Case("sgt", CmpInst::ICMP_SGT) + .Case("sge", CmpInst::ICMP_SGE) + .Case("slt", CmpInst::ICMP_SLT) + .Case("sle", CmpInst::ICMP_SLE) + .Case("ugt", CmpInst::ICMP_UGT) + .Case("uge", CmpInst::ICMP_UGE) + .Case("ult", CmpInst::ICMP_ULT) + .Case("ule", CmpInst::ICMP_ULE) + .Default(CmpInst::BAD_ICMP_PREDICATE); + if (!CmpInst::isIntPredicate(Pred)) + return error("invalid integer predicate"); + } + + lex(); + Dest = MachineOperand::CreatePredicate(Pred); + if (expectAndConsume(MIToken::rparen)) + return error("predicate should be terminated by ')'."); + + return false; +} + bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) { assert(Token.is(MIToken::kw_target_index)); lex(); @@ -1441,8 +1609,8 @@ bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) { while (true) { if (Token.isNot(MIToken::NamedRegister)) return error("expected a named register"); - unsigned Reg = 0; - if (parseRegister(Reg)) + unsigned Reg; + if (parseNamedRegister(Reg)) return true; lex(); Mask[Reg / 32] |= 1U << (Reg % 32); @@ -1511,10 +1679,15 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest, return parseCFIOperand(Dest); case MIToken::kw_blockaddress: return parseBlockAddressOperand(Dest); + case MIToken::kw_intrinsic: + return parseIntrinsicOperand(Dest); case MIToken::kw_target_index: return parseTargetIndexOperand(Dest); case MIToken::kw_liveout: return parseLiveoutRegisterMaskOperand(Dest); + case MIToken::kw_floatpred: + case MIToken::kw_intpred: + return parsePredicateOperand(Dest); case MIToken::Error: return true; case MIToken::Identifier: @@ -1523,7 +1696,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest, lex(); break; } - // fallthrough + LLVM_FALLTHROUGH; default: // FIXME: Parse the MCSymbol machine operand. return error("expected a machine operand"); @@ -1613,7 +1786,7 @@ bool MIParser::parseOperandsOffset(MachineOperand &Op) { bool MIParser::parseIRValue(const Value *&V) { switch (Token.kind()) { case MIToken::NamedIRValue: { - V = MF.getFunction()->getValueSymbolTable().lookup(Token.stringValue()); + V = MF.getFunction()->getValueSymbolTable()->lookup(Token.stringValue()); break; } case MIToken::IRValue: { @@ -1647,10 +1820,35 @@ bool MIParser::parseIRValue(const Value *&V) { } 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(); + if (Token.hasIntegerValue()) { + if (Token.integerValue().getActiveBits() > 64) + return error("expected 64-bit integer (too large)"); + Result = Token.integerValue().getZExtValue(); + return false; + } + if (Token.is(MIToken::HexLiteral)) { + APInt A; + if (getHexUint(A)) + return true; + if (A.getBitWidth() > 64) + return error("expected 64-bit integer (too large)"); + Result = A.getZExtValue(); + return false; + } + return true; +} + +bool MIParser::getHexUint(APInt &Result) { + assert(Token.is(MIToken::HexLiteral)); + StringRef S = Token.range(); + assert(S[0] == '0' && tolower(S[1]) == 'x'); + // This could be a floating point literal with a special prefix. + if (!isxdigit(S[2])) + return true; + StringRef V = S.substr(2); + APInt A(V.size()*4, V, 16); + Result = APInt(A.getActiveBits(), + ArrayRef<uint64_t>(A.getRawData(), A.getNumWords())); return false; } @@ -1663,6 +1861,9 @@ bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) { case MIToken::kw_non_temporal: Flags |= MachineMemOperand::MONonTemporal; break; + case MIToken::kw_dereferenceable: + Flags |= MachineMemOperand::MODereferenceable; + break; case MIToken::kw_invariant: Flags |= MachineMemOperand::MOInvariant; break; @@ -2059,36 +2260,42 @@ bool llvm::parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS, return MIParser(PFS, Error, Src).parseBasicBlockDefinitions(PFS.MBBSlots); } -bool llvm::parseMachineInstructions(const PerFunctionMIParsingState &PFS, +bool llvm::parseMachineInstructions(PerFunctionMIParsingState &PFS, StringRef Src, SMDiagnostic &Error) { return MIParser(PFS, Error, Src).parseBasicBlocks(); } -bool llvm::parseMBBReference(const PerFunctionMIParsingState &PFS, +bool llvm::parseMBBReference(PerFunctionMIParsingState &PFS, MachineBasicBlock *&MBB, StringRef Src, SMDiagnostic &Error) { return MIParser(PFS, Error, Src).parseStandaloneMBB(MBB); } -bool llvm::parseNamedRegisterReference(const PerFunctionMIParsingState &PFS, +bool llvm::parseRegisterReference(PerFunctionMIParsingState &PFS, + unsigned &Reg, StringRef Src, + SMDiagnostic &Error) { + return MIParser(PFS, Error, Src).parseStandaloneRegister(Reg); +} + +bool llvm::parseNamedRegisterReference(PerFunctionMIParsingState &PFS, unsigned &Reg, StringRef Src, SMDiagnostic &Error) { return MIParser(PFS, Error, Src).parseStandaloneNamedRegister(Reg); } -bool llvm::parseVirtualRegisterReference(const PerFunctionMIParsingState &PFS, - unsigned &Reg, StringRef Src, +bool llvm::parseVirtualRegisterReference(PerFunctionMIParsingState &PFS, + VRegInfo *&Info, StringRef Src, SMDiagnostic &Error) { - return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Reg); + return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Info); } -bool llvm::parseStackObjectReference(const PerFunctionMIParsingState &PFS, +bool llvm::parseStackObjectReference(PerFunctionMIParsingState &PFS, int &FI, StringRef Src, SMDiagnostic &Error) { return MIParser(PFS, Error, Src).parseStandaloneStackObject(FI); } -bool llvm::parseMDNode(const PerFunctionMIParsingState &PFS, +bool llvm::parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node, StringRef Src, SMDiagnostic &Error) { return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node); } |