summaryrefslogtreecommitdiff
path: root/lib/CodeGen/MIRParser/MIParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/MIRParser/MIParser.cpp')
-rw-r--r--lib/CodeGen/MIRParser/MIParser.cpp150
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))