mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-24 21:05:23 +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
|
||||
/// represent a consecutive sequence of sub-registers. It's used as register
|
||||
/// 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
|
||||
/// After register coalescing references of v1024 should be replace with
|
||||
/// v1027:3, v1025 with v1027:4, etc.
|
||||
|
@ -543,17 +543,18 @@ InstrEmitter::EmitCopyToRegClassNode(SDNode *Node,
|
||||
void InstrEmitter::EmitRegSequence(SDNode *Node,
|
||||
DenseMap<SDValue, unsigned> &VRBaseMap,
|
||||
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);
|
||||
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(),
|
||||
TII->get(TargetOpcode::REG_SEQUENCE), NewVReg);
|
||||
unsigned NumOps = Node->getNumOperands();
|
||||
assert((NumOps & 1) == 0 &&
|
||||
"REG_SEQUENCE must have an even number of operands!");
|
||||
assert((NumOps & 1) == 1 &&
|
||||
"REG_SEQUENCE must have an odd number of operands!");
|
||||
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);
|
||||
if (i & 1) {
|
||||
if ((i & 1) == 0) {
|
||||
unsigned SubIdx = cast<ConstantSDNode>(Op)->getZExtValue();
|
||||
unsigned SubReg = getVR(Node->getOperand(i-1), VRBaseMap);
|
||||
const TargetRegisterClass *TRC = MRI->getRegClass(SubReg);
|
||||
|
@ -1354,30 +1354,34 @@ SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDNode *N) {
|
||||
///
|
||||
SDNode *ARMDAGToDAGISel::PairSRegs(EVT VT, SDValue V0, SDValue V1) {
|
||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||
SDValue RegClass =
|
||||
CurDAG->getTargetConstant(ARM::DPR_VFP2RegClassID, MVT::i32);
|
||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32);
|
||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32);
|
||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
|
||||
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 5);
|
||||
}
|
||||
|
||||
/// PairDRegs - Form a quad register from a pair of D registers.
|
||||
///
|
||||
SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) {
|
||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||
SDValue RegClass = CurDAG->getTargetConstant(ARM::QPRRegClassID, MVT::i32);
|
||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32);
|
||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32);
|
||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
|
||||
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 5);
|
||||
}
|
||||
|
||||
/// PairQRegs - Form 4 consecutive D registers from a pair of Q registers.
|
||||
///
|
||||
SDNode *ARMDAGToDAGISel::PairQRegs(EVT VT, SDValue V0, SDValue V1) {
|
||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||
SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, MVT::i32);
|
||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32);
|
||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32);
|
||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
|
||||
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 5);
|
||||
}
|
||||
|
||||
/// 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,
|
||||
SDValue V2, SDValue V3) {
|
||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||
SDValue RegClass =
|
||||
CurDAG->getTargetConstant(ARM::QPR_VFP2RegClassID, MVT::i32);
|
||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32);
|
||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32);
|
||||
SDValue SubReg2 = CurDAG->getTargetConstant(ARM::ssub_2, MVT::i32);
|
||||
SDValue SubReg3 = CurDAG->getTargetConstant(ARM::ssub_3, MVT::i32);
|
||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8);
|
||||
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
|
||||
V2, SubReg2, V3, SubReg3 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 9);
|
||||
}
|
||||
|
||||
/// 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,
|
||||
SDValue V2, SDValue V3) {
|
||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||
SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, MVT::i32);
|
||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32);
|
||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32);
|
||||
SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, MVT::i32);
|
||||
SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, MVT::i32);
|
||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8);
|
||||
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
|
||||
V2, SubReg2, V3, SubReg3 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 9);
|
||||
}
|
||||
|
||||
/// 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,
|
||||
SDValue V2, SDValue V3) {
|
||||
DebugLoc dl = V0.getNode()->getDebugLoc();
|
||||
SDValue RegClass = CurDAG->getTargetConstant(ARM::QQQQPRRegClassID, MVT::i32);
|
||||
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32);
|
||||
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32);
|
||||
SDValue SubReg2 = CurDAG->getTargetConstant(ARM::qsub_2, MVT::i32);
|
||||
SDValue SubReg3 = CurDAG->getTargetConstant(ARM::qsub_3, MVT::i32);
|
||||
const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8);
|
||||
const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
|
||||
V2, SubReg2, V3, SubReg3 };
|
||||
return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 9);
|
||||
}
|
||||
|
||||
/// GetVLDSTAlign - Get the alignment (in bytes) for the alignment operand
|
||||
|
Loading…
x
Reference in New Issue
Block a user