forked from OSchip/llvm-project
Model some vld3 instructions with REG_SEQUENCE.
llvm-svn: 103437
This commit is contained in:
parent
d6908dc4a2
commit
630063aa0d
|
@ -1044,7 +1044,40 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs,
|
||||||
const SDValue Ops[] = { MemAddr, Align, Pred, Reg0, Chain };
|
const SDValue Ops[] = { MemAddr, Align, Pred, Reg0, Chain };
|
||||||
std::vector<EVT> ResTys(NumVecs, VT);
|
std::vector<EVT> ResTys(NumVecs, VT);
|
||||||
ResTys.push_back(MVT::Other);
|
ResTys.push_back(MVT::Other);
|
||||||
return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5);
|
SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5);
|
||||||
|
if (!llvm::ModelWithRegSequence() || NumVecs < 2)
|
||||||
|
return VLd;
|
||||||
|
|
||||||
|
assert(NumVecs <= 4);
|
||||||
|
SDValue V0 = SDValue(VLd, 0);
|
||||||
|
SDValue V1 = SDValue(VLd, 1);
|
||||||
|
SDValue RegSeq;
|
||||||
|
|
||||||
|
if (NumVecs == 2)
|
||||||
|
RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0);
|
||||||
|
else {
|
||||||
|
SDValue V2 = SDValue(VLd, 2);
|
||||||
|
SDValue V3 = (NumVecs == 3)
|
||||||
|
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
|
||||||
|
: SDValue(VLd, 3);
|
||||||
|
RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDValue D0 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, VT, RegSeq);
|
||||||
|
ReplaceUses(SDValue(N, 0), D0);
|
||||||
|
SDValue D1 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, VT, RegSeq);
|
||||||
|
ReplaceUses(SDValue(N, 1), D1);
|
||||||
|
|
||||||
|
if (NumVecs > 2) {
|
||||||
|
SDValue D2 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_2, dl, VT, RegSeq);
|
||||||
|
ReplaceUses(SDValue(N, 2), D2);
|
||||||
|
}
|
||||||
|
if (NumVecs > 3) {
|
||||||
|
SDValue D3 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_3, dl, VT, RegSeq);
|
||||||
|
ReplaceUses(SDValue(N, 3), D3);
|
||||||
|
}
|
||||||
|
ReplaceUses(SDValue(N, NumVecs), SDValue(VLd, NumVecs));
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVT RegVT = GetNEONSubregVT(VT);
|
EVT RegVT = GetNEONSubregVT(VT);
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool FormsRegSequence(MachineInstr *MI,
|
bool FormsRegSequence(MachineInstr *MI,
|
||||||
unsigned FirstOpnd, unsigned NumRegs);
|
unsigned FirstOpnd, unsigned NumRegs) const;
|
||||||
bool PreAllocNEONRegisters(MachineBasicBlock &MBB);
|
bool PreAllocNEONRegisters(MachineBasicBlock &MBB);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -338,18 +338,22 @@ static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
|
bool
|
||||||
unsigned FirstOpnd, unsigned NumRegs) {
|
NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
|
||||||
MachineInstr *RegSeq = 0;
|
unsigned FirstOpnd, unsigned NumRegs) const {
|
||||||
unsigned LastSrcReg = 0;
|
MachineOperand &FMO = MI->getOperand(FirstOpnd);
|
||||||
unsigned LastSubIdx = 0;
|
assert(FMO.isReg() && FMO.getSubReg() == 0 && "unexpected operand");
|
||||||
for (unsigned R = 0; R < NumRegs; ++R) {
|
unsigned VirtReg = FMO.getReg();
|
||||||
MachineOperand &MO = MI->getOperand(FirstOpnd + R);
|
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
||||||
assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
|
"expected a virtual register");
|
||||||
unsigned VirtReg = MO.getReg();
|
if (FMO.isDef()) {
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
MachineInstr *RegSeq = 0;
|
||||||
"expected a virtual register");
|
for (unsigned R = 0; R < NumRegs; ++R) {
|
||||||
if (MO.isDef()) {
|
const MachineOperand &MO = MI->getOperand(FirstOpnd + R);
|
||||||
|
assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
|
||||||
|
unsigned VirtReg = MO.getReg();
|
||||||
|
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
||||||
|
"expected a virtual register");
|
||||||
// Feeding into a REG_SEQUENCE.
|
// Feeding into a REG_SEQUENCE.
|
||||||
if (!MRI->hasOneNonDBGUse(VirtReg))
|
if (!MRI->hasOneNonDBGUse(VirtReg))
|
||||||
return false;
|
return false;
|
||||||
|
@ -359,25 +363,45 @@ bool NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
|
||||||
if (RegSeq && RegSeq != UseMI)
|
if (RegSeq && RegSeq != UseMI)
|
||||||
return false;
|
return false;
|
||||||
RegSeq = UseMI;
|
RegSeq = UseMI;
|
||||||
} else {
|
|
||||||
// Extracting from a Q or QQ register.
|
|
||||||
MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
|
|
||||||
if (!DefMI || !DefMI->isExtractSubreg())
|
|
||||||
return false;
|
|
||||||
VirtReg = DefMI->getOperand(1).getReg();
|
|
||||||
if (LastSrcReg && LastSrcReg != VirtReg)
|
|
||||||
return false;
|
|
||||||
const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
|
|
||||||
if (NumRegs == 2) {
|
|
||||||
if (RC != ARM::QPRRegisterClass)
|
|
||||||
return false;
|
|
||||||
} else if (RC != ARM::QQPRRegisterClass)
|
|
||||||
return false;
|
|
||||||
unsigned SubIdx = DefMI->getOperand(2).getImm();
|
|
||||||
if (LastSubIdx && LastSubIdx != SubIdx-1)
|
|
||||||
return false;
|
|
||||||
LastSubIdx = SubIdx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure trailing operands of REG_SEQUENCE are undef.
|
||||||
|
unsigned NumExps = (RegSeq->getNumOperands() - 1) / 2;
|
||||||
|
for (unsigned i = NumRegs * 2 + 1; i < NumExps; i += 2) {
|
||||||
|
const MachineOperand &MO = RegSeq->getOperand(i);
|
||||||
|
unsigned VirtReg = MO.getReg();
|
||||||
|
MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
|
||||||
|
if (!DefMI || !DefMI->isImplicitDef())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned LastSrcReg = 0;
|
||||||
|
unsigned LastSubIdx = 0;
|
||||||
|
for (unsigned R = 0; R < NumRegs; ++R) {
|
||||||
|
const MachineOperand &MO = MI->getOperand(FirstOpnd + R);
|
||||||
|
assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
|
||||||
|
unsigned VirtReg = MO.getReg();
|
||||||
|
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
||||||
|
"expected a virtual register");
|
||||||
|
// Extracting from a Q or QQ register.
|
||||||
|
MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
|
||||||
|
if (!DefMI || !DefMI->isExtractSubreg())
|
||||||
|
return false;
|
||||||
|
VirtReg = DefMI->getOperand(1).getReg();
|
||||||
|
if (LastSrcReg && LastSrcReg != VirtReg)
|
||||||
|
return false;
|
||||||
|
const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
|
||||||
|
if (NumRegs == 2) {
|
||||||
|
if (RC != ARM::QPRRegisterClass)
|
||||||
|
return false;
|
||||||
|
} else if (RC != ARM::QQPRRegisterClass)
|
||||||
|
return false;
|
||||||
|
unsigned SubIdx = DefMI->getOperand(2).getImm();
|
||||||
|
if (LastSubIdx && LastSubIdx != SubIdx-1)
|
||||||
|
return false;
|
||||||
|
LastSubIdx = SubIdx;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue