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/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
index 26342a1..489f9ab 100644
--- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -49,7 +49,8 @@
const AArch64RegisterBankInfo &RBI,
const MachineRegisterInfo &MRI,
const AArch64RegisterInfo &TRI) {
- if (!I.getType().isSized()) {
+ LLT Ty = MRI.getType(I.getOperand(0).getReg());
+ if (!Ty.isSized()) {
DEBUG(dbgs() << "Generic binop should be sized\n");
return true;
}
@@ -219,38 +220,35 @@
return false;
}
- const LLT Ty = I.getType();
+ const LLT Ty = I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg())
+ : LLT::unsized();
assert(Ty.isValid() && "Generic instruction doesn't have a type");
switch (I.getOpcode()) {
case TargetOpcode::G_BR: {
I.setDesc(TII.get(AArch64::B));
- I.removeTypes();
return true;
}
case TargetOpcode::G_TYPE: {
I.setDesc(TII.get(TargetOpcode::COPY));
- I.removeTypes();
return true;
}
case TargetOpcode::G_PHI: {
I.setDesc(TII.get(TargetOpcode::PHI));
- I.removeTypes();
return true;
}
case TargetOpcode::G_FRAME_INDEX: {
// allocas and G_FRAME_INDEX are only supported in addrspace(0).
- if (I.getType() != LLT::pointer(0)) {
- DEBUG(dbgs() << "G_FRAME_INDEX pointer has type: " << I.getType()
+ if (Ty != LLT::pointer(0)) {
+ DEBUG(dbgs() << "G_FRAME_INDEX pointer has type: " << Ty
<< ", expected: " << LLT::pointer(0) << '\n');
return false;
}
I.setDesc(TII.get(AArch64::ADDXri));
- I.removeTypes();
// MOs for a #0 shifted immediate.
I.addOperand(MachineOperand::CreateImm(0));
@@ -260,8 +258,8 @@
}
case TargetOpcode::G_LOAD:
case TargetOpcode::G_STORE: {
- LLT MemTy = I.getType(0);
- LLT PtrTy = I.getType(1);
+ LLT MemTy = Ty;
+ LLT PtrTy = MRI.getType(I.getOperand(1).getReg());
if (PtrTy != LLT::pointer(0)) {
DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
@@ -275,8 +273,8 @@
const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI);
assert(PtrRB.getID() == AArch64::GPRRegBankID &&
"Load/Store pointer operand isn't a GPR");
- assert(MRI.getSize(PtrReg) == 64 &&
- "Load/Store pointer operand isn't 64-bit");
+ assert(MRI.getType(PtrReg).isPointer() &&
+ "Load/Store pointer operand isn't a pointer");
#endif
const unsigned ValReg = I.getOperand(0).getReg();
@@ -288,7 +286,6 @@
return false;
I.setDesc(TII.get(NewOpc));
- I.removeTypes();
I.addOperand(MachineOperand::CreateImm(0));
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
@@ -322,7 +319,6 @@
}
I.setDesc(TII.get(NewOpc));
- I.removeTypes();
I.addOperand(MachineOperand::CreateReg(ZeroReg, /*isDef=*/false));
@@ -361,7 +357,6 @@
I.setDesc(TII.get(NewOpc));
// FIXME: Should the type be always reset in setDesc?
- I.removeTypes();
// Now that we selected an opcode, we need to constrain the register
// operands to use appropriate classes.