[GlobalISel][AArch64] Gardening: Factor out vector inserts
Factor out the vector insert code in `selectBuildVector`. Replace part of it with `emitScalarToVector`, since it was pretty much equivalent. This will make implementing G_INSERT_VECTOR_ELT easier. Differential Revision: https://reviews.llvm.org/D59322 llvm-svn: 356106
This commit is contained in:
parent
42bc1e241c
commit
16d67a3e32
|
|
@ -71,6 +71,17 @@ private:
|
|||
const TargetRegisterClass *DstRC,
|
||||
unsigned Scalar,
|
||||
MachineIRBuilder &MIRBuilder) const;
|
||||
|
||||
/// Emit a lane insert into \p DstReg, or a new vector register if None is
|
||||
/// provided.
|
||||
///
|
||||
/// The lane inserted into is defined by \p LaneIdx. The vector source
|
||||
/// register is given by \p SrcReg. The register containing the element is
|
||||
/// given by \p EltReg.
|
||||
MachineInstr *emitLaneInsert(Optional<unsigned> DstReg, unsigned SrcReg,
|
||||
unsigned EltReg, unsigned LaneIdx,
|
||||
const RegisterBank &RB,
|
||||
MachineIRBuilder &MIRBuilder) const;
|
||||
bool selectBuildVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
||||
bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
||||
bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
||||
|
|
@ -2304,6 +2315,37 @@ bool AArch64InstructionSelector::selectShuffleVector(
|
|||
return true;
|
||||
}
|
||||
|
||||
MachineInstr *AArch64InstructionSelector::emitLaneInsert(
|
||||
Optional<unsigned> DstReg, unsigned SrcReg, unsigned EltReg,
|
||||
unsigned LaneIdx, const RegisterBank &RB,
|
||||
MachineIRBuilder &MIRBuilder) const {
|
||||
MachineInstr *InsElt = nullptr;
|
||||
const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
|
||||
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
|
||||
|
||||
// Create a register to define with the insert if one wasn't passed in.
|
||||
if (!DstReg)
|
||||
DstReg = MRI.createVirtualRegister(DstRC);
|
||||
|
||||
unsigned EltSize = MRI.getType(EltReg).getSizeInBits();
|
||||
unsigned Opc = getInsertVecEltOpInfo(RB, EltSize).first;
|
||||
|
||||
if (RB.getID() == AArch64::FPRRegBankID) {
|
||||
auto InsSub = emitScalarToVector(EltSize, DstRC, EltReg, MIRBuilder);
|
||||
InsElt = MIRBuilder.buildInstr(Opc, {*DstReg}, {SrcReg})
|
||||
.addImm(LaneIdx)
|
||||
.addUse(InsSub->getOperand(0).getReg())
|
||||
.addImm(0);
|
||||
} else {
|
||||
InsElt = MIRBuilder.buildInstr(Opc, {*DstReg}, {SrcReg})
|
||||
.addImm(LaneIdx)
|
||||
.addUse(EltReg);
|
||||
}
|
||||
|
||||
constrainSelectedInstRegOperands(*InsElt, TII, TRI, RBI);
|
||||
return InsElt;
|
||||
}
|
||||
|
||||
bool AArch64InstructionSelector::selectBuildVector(
|
||||
MachineInstr &I, MachineRegisterInfo &MRI) const {
|
||||
assert(I.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
|
||||
|
|
@ -2315,11 +2357,6 @@ bool AArch64InstructionSelector::selectBuildVector(
|
|||
if (EltSize < 16 || EltSize > 64)
|
||||
return false; // Don't support all element types yet.
|
||||
const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
|
||||
unsigned Opc;
|
||||
unsigned SubregIdx;
|
||||
|
||||
std::tie(Opc, SubregIdx) = getInsertVecEltOpInfo(RB, EltSize);
|
||||
|
||||
MachineIRBuilder MIRBuilder(I);
|
||||
|
||||
const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
|
||||
|
|
@ -2336,34 +2373,11 @@ bool AArch64InstructionSelector::selectBuildVector(
|
|||
// a copy using it.
|
||||
MachineInstr *PrevMI = nullptr;
|
||||
for (unsigned i = 2, e = DstSize / EltSize + 1; i < e; ++i) {
|
||||
// Note that if we don't do a subregister copy, we end up making one more
|
||||
// of these than we need.
|
||||
unsigned InsDef = MRI.createVirtualRegister(DstRC);
|
||||
unsigned LaneIdx = i - 1;
|
||||
if (RB.getID() == AArch64::FPRRegBankID) {
|
||||
auto ImpDef =
|
||||
MIRBuilder.buildInstr(TargetOpcode::IMPLICIT_DEF, {DstRC}, {});
|
||||
auto InsSub = MIRBuilder
|
||||
.buildInstr(TargetOpcode::INSERT_SUBREG, {DstRC},
|
||||
{ImpDef, I.getOperand(i)})
|
||||
.addImm(SubregIdx);
|
||||
auto InsElt = MIRBuilder.buildInstr(Opc, {InsDef}, {DstVec})
|
||||
.addImm(LaneIdx)
|
||||
.addUse(InsSub.getReg(0))
|
||||
.addImm(0);
|
||||
constrainSelectedInstRegOperands(*ImpDef, TII, TRI, RBI);
|
||||
constrainSelectedInstRegOperands(*InsSub, TII, TRI, RBI);
|
||||
constrainSelectedInstRegOperands(*InsElt, TII, TRI, RBI);
|
||||
DstVec = InsDef;
|
||||
PrevMI = &*InsElt;
|
||||
} else {
|
||||
auto Ins = MIRBuilder.buildInstr(Opc, {InsDef}, {DstVec})
|
||||
.addImm(LaneIdx)
|
||||
.addUse(I.getOperand(i).getReg());
|
||||
constrainSelectedInstRegOperands(*Ins, TII, TRI, RBI);
|
||||
DstVec = InsDef;
|
||||
PrevMI = &*Ins;
|
||||
}
|
||||
// Note that if we don't do a subregister copy, we can end up making an
|
||||
// extra register.
|
||||
PrevMI = &*emitLaneInsert(None, DstVec, I.getOperand(i).getReg(), i - 1, RB,
|
||||
MIRBuilder);
|
||||
DstVec = PrevMI->getOperand(0).getReg();
|
||||
}
|
||||
|
||||
// If DstTy's size in bits is less than 128, then emit a subregister copy
|
||||
|
|
|
|||
Loading…
Reference in New Issue