summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp')
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp485
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);
}
OpenPOWER on IntegriCloud