mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-03 19:02:35 +00:00
Change the REG_SEQUENCE SDNode to take an explict register class ID as its first operand. This operand is lowered away by the time we reach MachineInstrs, so the actual register-allocation handling of them doesn't need to change.
This is intended to support using REG_SEQUENCE SDNode's with type MVT::untyped, and is part of the long road to eliminating some of the hacks we currently use to support register pairs and other strange constraints, particularly on ARM NEON. llvm-svn: 133178
This commit is contained in:
parent
7e56e59d68
commit
c79aec8247
@ -71,6 +71,10 @@ namespace TargetOpcode {
|
|||||||
/// REG_SEQUENCE - This variadic instruction is used to form a register that
|
/// REG_SEQUENCE - This variadic instruction is used to form a register that
|
||||||
/// represent a consecutive sequence of sub-registers. It's used as register
|
/// represent a consecutive sequence of sub-registers. It's used as register
|
||||||
/// coalescing / allocation aid and must be eliminated before code emission.
|
/// coalescing / allocation aid and must be eliminated before code emission.
|
||||||
|
// In SDNode form, the first operand encodes the register class created by
|
||||||
|
// the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index
|
||||||
|
// pair. Once it has been lowered to a MachineInstr, the regclass operand
|
||||||
|
// is no longer present.
|
||||||
/// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5
|
/// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5
|
||||||
/// After register coalescing references of v1024 should be replace with
|
/// After register coalescing references of v1024 should be replace with
|
||||||
/// v1027:3, v1025 with v1027:4, etc.
|
/// v1027:3, v1025 with v1027:4, etc.
|
||||||
|
@ -543,17 +543,18 @@ InstrEmitter::EmitCopyToRegClassNode(SDNode *Node,
|
|||||||
void InstrEmitter::EmitRegSequence(SDNode *Node,
|
void InstrEmitter::EmitRegSequence(SDNode *Node,
|
||||||
DenseMap<SDValue, unsigned> &VRBaseMap,
|
DenseMap<SDValue, unsigned> &VRBaseMap,
|
||||||
bool IsClone, bool IsCloned) {
|
bool IsClone, bool IsCloned) {
|
||||||
const TargetRegisterClass *RC = TLI->getRegClassFor(Node->getValueType(0));
|
unsigned DstRCIdx = cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue();
|
||||||
|
const TargetRegisterClass *RC = TRI->getRegClass(DstRCIdx);
|
||||||
unsigned NewVReg = MRI->createVirtualRegister(RC);
|
unsigned NewVReg = MRI->createVirtualRegister(RC);
|
||||||
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(),
|
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(),
|
||||||
TII->get(TargetOpcode::REG_SEQUENCE), NewVReg);
|
TII->get(TargetOpcode::REG_SEQUENCE), NewVReg);
|
||||||
unsigned NumOps = Node->getNumOperands();
|
unsigned NumOps = Node->getNumOperands();
|
||||||
assert((NumOps & 1) == 0 &&
|
assert((NumOps & 1) == 1 &&
|
||||||
"REG_SEQUENCE must have an even number of operands!");
|
"REG_SEQUENCE must have an odd number of operands!");
|
||||||
const TargetInstrDesc &II = TII->get(TargetOpcode::REG_SEQUENCE);
|
const TargetInstrDesc &II = TII->get(TargetOpcode::REG_SEQUENCE);
|
||||||
for (unsigned i = 0; i != NumOps; ++i) {
|
for (unsigned i = 1; i != NumOps; ++i) {
|
||||||
SDValue Op = Node->getOperand(i);
|
SDValue Op = Node->getOperand(i);
|
||||||
if (i & 1) {
|
if ((i & 1) == 0) {
|
||||||
unsigned SubIdx = cast<ConstantSDNode>(Op)->getZExtValue();
|
unsigned SubIdx = cast<ConstantSDNode>(Op)->getZExtValue();
|
||||||
unsigned SubReg = getVR(Node->getOperand(i-1), VRBaseMap);
|
unsigned SubReg = getVR(Node->getOperand(i-1), VRBaseMap);
|
||||||
const TargetRegisterClass *TRC = MRI->getRegClass(SubReg);
|
const TargetRegisterClass *TRC = MRI->getRegClass(SubReg);
|
||||||
|
@ -1354,30 +1354,34 @@ SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDNode *N) {
|
|||||||
///
|
///
|
||||||
SDNode *ARMDAGToDAGISel::PairSRegs(EVT VT, SDValue V0, SDValue V1) {
|
SDNode *ARMDAGToDAGISel::PairSRegs(EVT VT, SDValue V0, SDValue V1) {
|
||||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||||
|
SDValue RegClass =
|
||||||
|
CurDAG->getTargetConstant(ARM::DPR_VFP2RegClassID, MVT::i32);
|
||||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32);
|
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32);
|
||||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32);
|
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32);
|
||||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
|
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
|
||||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
|
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PairDRegs - Form a quad register from a pair of D registers.
|
/// PairDRegs - Form a quad register from a pair of D registers.
|
||||||
///
|
///
|
||||||
SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) {
|
SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) {
|
||||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||||
|
SDValue RegClass = CurDAG->getTargetConstant(ARM::QPRRegClassID, MVT::i32);
|
||||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32);
|
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32);
|
||||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32);
|
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32);
|
||||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
|
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
|
||||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
|
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PairQRegs - Form 4 consecutive D registers from a pair of Q registers.
|
/// PairQRegs - Form 4 consecutive D registers from a pair of Q registers.
|
||||||
///
|
///
|
||||||
SDNode *ARMDAGToDAGISel::PairQRegs(EVT VT, SDValue V0, SDValue V1) {
|
SDNode *ARMDAGToDAGISel::PairQRegs(EVT VT, SDValue V0, SDValue V1) {
|
||||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||||
|
SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, MVT::i32);
|
||||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32);
|
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32);
|
||||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32);
|
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32);
|
||||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
|
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
|
||||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
|
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// QuadSRegs - Form 4 consecutive S registers.
|
/// QuadSRegs - Form 4 consecutive S registers.
|
||||||
@ -1385,12 +1389,15 @@ SDNode *ARMDAGToDAGISel::PairQRegs(EVT VT, SDValue V0, SDValue V1) {
|
|||||||
SDNode *ARMDAGToDAGISel::QuadSRegs(EVT VT, SDValue V0, SDValue V1,
|
SDNode *ARMDAGToDAGISel::QuadSRegs(EVT VT, SDValue V0, SDValue V1,
|
||||||
SDValue V2, SDValue V3) {
|
SDValue V2, SDValue V3) {
|
||||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||||
|
SDValue RegClass =
|
||||||
|
CurDAG->getTargetConstant(ARM::QPR_VFP2RegClassID, MVT::i32);
|
||||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32);
|
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32);
|
||||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32);
|
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32);
|
||||||
SDValue SubReg2 = CurDAG->getTargetConstant(ARM::ssub_2, MVT::i32);
|
SDValue SubReg2 = CurDAG->getTargetConstant(ARM::ssub_2, MVT::i32);
|
||||||
SDValue SubReg3 = CurDAG->getTargetConstant(ARM::ssub_3, MVT::i32);
|
SDValue SubReg3 = CurDAG->getTargetConstant(ARM::ssub_3, MVT::i32);
|
||||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 };
|
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
|
||||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8);
|
V2, SubReg2, V3, SubReg3 };
|
||||||
|
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// QuadDRegs - Form 4 consecutive D registers.
|
/// QuadDRegs - Form 4 consecutive D registers.
|
||||||
@ -1398,12 +1405,14 @@ SDNode *ARMDAGToDAGISel::QuadSRegs(EVT VT, SDValue V0, SDValue V1,
|
|||||||
SDNode *ARMDAGToDAGISel::QuadDRegs(EVT VT, SDValue V0, SDValue V1,
|
SDNode *ARMDAGToDAGISel::QuadDRegs(EVT VT, SDValue V0, SDValue V1,
|
||||||
SDValue V2, SDValue V3) {
|
SDValue V2, SDValue V3) {
|
||||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||||
|
SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, MVT::i32);
|
||||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32);
|
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32);
|
||||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32);
|
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32);
|
||||||
SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, MVT::i32);
|
SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, MVT::i32);
|
||||||
SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, MVT::i32);
|
SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, MVT::i32);
|
||||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 };
|
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
|
||||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8);
|
V2, SubReg2, V3, SubReg3 };
|
||||||
|
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// QuadQRegs - Form 4 consecutive Q registers.
|
/// QuadQRegs - Form 4 consecutive Q registers.
|
||||||
@ -1411,12 +1420,14 @@ SDNode *ARMDAGToDAGISel::QuadDRegs(EVT VT, SDValue V0, SDValue V1,
|
|||||||
SDNode *ARMDAGToDAGISel::QuadQRegs(EVT VT, SDValue V0, SDValue V1,
|
SDNode *ARMDAGToDAGISel::QuadQRegs(EVT VT, SDValue V0, SDValue V1,
|
||||||
SDValue V2, SDValue V3) {
|
SDValue V2, SDValue V3) {
|
||||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||||
|
SDValue RegClass = CurDAG->getTargetConstant(ARM::QQQQPRRegClassID, MVT::i32);
|
||||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32);
|
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32);
|
||||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32);
|
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32);
|
||||||
SDValue SubReg2 = CurDAG->getTargetConstant(ARM::qsub_2, MVT::i32);
|
SDValue SubReg2 = CurDAG->getTargetConstant(ARM::qsub_2, MVT::i32);
|
||||||
SDValue SubReg3 = CurDAG->getTargetConstant(ARM::qsub_3, MVT::i32);
|
SDValue SubReg3 = CurDAG->getTargetConstant(ARM::qsub_3, MVT::i32);
|
||||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 };
|
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
|
||||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8);
|
V2, SubReg2, V3, SubReg3 };
|
||||||
|
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// GetVLDSTAlign - Get the alignment (in bytes) for the alignment operand
|
/// GetVLDSTAlign - Get the alignment (in bytes) for the alignment operand
|
||||||
|
Loading…
x
Reference in New Issue
Block a user