GlobalISel: move type information to MachineRegisterInfo.
We want each register to have a canonical type, which means the best place to
store this is in MachineRegisterInfo rather than on every MachineInstr that
happens to use or define that register.
Most changes following from this are pretty simple (you need an MRI anyway if
you're going to be doing any transformations, so just check the type there).
But legalization doesn't really want to check redundant operands (when, for
example, a G_ADD only ever has one type) so I've made use of MCInstrDesc's
operand type field to encode these constraints and limit legalization's work.
As an added bonus, more validation is possible, both in MachineVerifier and
MachineIRBuilder (coming soon).
llvm-svn: 281035
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 91943ea..4dc964e 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -599,25 +599,6 @@
if (Token.isError() || parseInstruction(OpCode, Flags))
return true;
- SmallVector<LLT, 1> Tys;
- if (isPreISelGenericOpcode(OpCode)) {
- // For generic opcode, at least one type is mandatory.
- auto Loc = Token.location();
- bool ManyTypes = Token.is(MIToken::lbrace);
- if (ManyTypes)
- lex();
-
- // Now actually parse the type(s).
- do {
- Tys.resize(Tys.size() + 1);
- if (parseLowLevelType(Loc, Tys[Tys.size() - 1]))
- return true;
- } while (ManyTypes && consumeIfPresent(MIToken::comma));
-
- if (ManyTypes)
- expectAndConsume(MIToken::rbrace);
- }
-
// Parse the remaining machine operands.
while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_debug_location) &&
Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) {
@@ -673,10 +654,6 @@
// TODO: Check for extraneous machine operands.
MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
MI->setFlags(Flags);
- if (Tys.size() > 0) {
- for (unsigned i = 0; i < Tys.size(); ++i)
- MI->setType(Tys[i], i);
- }
for (const auto &Operand : Operands)
MI->addOperand(MF, Operand.Operand);
if (assignRegisterTies(*MI, Operands))
@@ -996,11 +973,14 @@
if (MRI.getRegClassOrRegBank(Reg).is<const TargetRegisterClass *>())
return error("unexpected size on non-generic virtual register");
- unsigned Size;
- if (parseSize(Size))
+ LLT Ty;
+ if (parseLowLevelType(Token.location(), Ty))
return true;
- MRI.setSize(Reg, Size);
+ if (expectAndConsume(MIToken::rparen))
+ return true;
+
+ MRI.setType(Reg, Ty);
} 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
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 9a36405..e7fdcc0 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -415,7 +415,7 @@
if (StringRef(VReg.Class.Value).equals("_")) {
// This is a generic virtual register.
// The size will be set appropriately when we reach the definition.
- Reg = RegInfo.createGenericVirtualRegister(/*Size*/ 1);
+ Reg = RegInfo.createGenericVirtualRegister(LLT::scalar(1));
PFS.GenericVRegs.insert(Reg);
} else {
const auto *RC = getRegClass(MF, VReg.Class.Value);
@@ -428,7 +428,7 @@
VReg.Class.SourceRange.Start,
Twine("use of undefined register class or register bank '") +
VReg.Class.Value + "'");
- Reg = RegInfo.createGenericVirtualRegister(/*Size*/ 1);
+ Reg = RegInfo.createGenericVirtualRegister(LLT::scalar(1));
RegInfo.setRegBank(Reg, *RegBank);
PFS.GenericVRegs.insert(Reg);
}