[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,
|
const TargetRegisterClass *DstRC,
|
||||||
unsigned Scalar,
|
unsigned Scalar,
|
||||||
MachineIRBuilder &MIRBuilder) const;
|
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 selectBuildVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
||||||
bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
||||||
bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
||||||
|
|
@ -2304,6 +2315,37 @@ bool AArch64InstructionSelector::selectShuffleVector(
|
||||||
return true;
|
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(
|
bool AArch64InstructionSelector::selectBuildVector(
|
||||||
MachineInstr &I, MachineRegisterInfo &MRI) const {
|
MachineInstr &I, MachineRegisterInfo &MRI) const {
|
||||||
assert(I.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
|
assert(I.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
|
||||||
|
|
@ -2315,11 +2357,6 @@ bool AArch64InstructionSelector::selectBuildVector(
|
||||||
if (EltSize < 16 || EltSize > 64)
|
if (EltSize < 16 || EltSize > 64)
|
||||||
return false; // Don't support all element types yet.
|
return false; // Don't support all element types yet.
|
||||||
const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
|
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);
|
MachineIRBuilder MIRBuilder(I);
|
||||||
|
|
||||||
const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
|
const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
|
||||||
|
|
@ -2336,34 +2373,11 @@ bool AArch64InstructionSelector::selectBuildVector(
|
||||||
// a copy using it.
|
// a copy using it.
|
||||||
MachineInstr *PrevMI = nullptr;
|
MachineInstr *PrevMI = nullptr;
|
||||||
for (unsigned i = 2, e = DstSize / EltSize + 1; i < e; ++i) {
|
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
|
// Note that if we don't do a subregister copy, we can end up making an
|
||||||
// of these than we need.
|
// extra register.
|
||||||
unsigned InsDef = MRI.createVirtualRegister(DstRC);
|
PrevMI = &*emitLaneInsert(None, DstVec, I.getOperand(i).getReg(), i - 1, RB,
|
||||||
unsigned LaneIdx = i - 1;
|
MIRBuilder);
|
||||||
if (RB.getID() == AArch64::FPRRegBankID) {
|
DstVec = PrevMI->getOperand(0).getReg();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If DstTy's size in bits is less than 128, then emit a subregister copy
|
// If DstTy's size in bits is less than 128, then emit a subregister copy
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue