1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02:00

R600/SI: Adjust some instructions' out register class after ISel

This is necessary to avoid generating VGPR to SGPR copies in some
cases.

llvm-svn: 183135
This commit is contained in:
Tom Stellard 2013-06-03 17:39:58 +00:00
parent 29284f6cc9
commit c08ab0862e
2 changed files with 52 additions and 0 deletions

View File

@ -809,6 +809,7 @@ void SITargetLowering::adjustWritemask(MachineSDNode *&Node,
/// \brief Fold the instructions after slecting them
SDNode *SITargetLowering::PostISelFolding(MachineSDNode *Node,
SelectionDAG &DAG) const {
Node = AdjustRegClass(Node, DAG);
if (AMDGPU::isMIMG(Node->getMachineOpcode()) != -1)
adjustWritemask(Node, DAG);
@ -840,3 +841,53 @@ void SITargetLowering::AdjustInstrPostInstrSelection(MachineInstr *MI,
MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
MRI.setRegClass(VReg, RC);
}
MachineSDNode *SITargetLowering::AdjustRegClass(MachineSDNode *N,
SelectionDAG &DAG) const {
SDLoc DL(N);
unsigned NewOpcode = N->getMachineOpcode();
switch (N->getMachineOpcode()) {
default: return N;
case AMDGPU::REG_SEQUENCE: {
// MVT::i128 only use SGPRs, so i128 REG_SEQUENCEs don't need to be
// rewritten.
if (N->getValueType(0) == MVT::i128) {
return N;
}
const SDValue Ops[] = {
DAG.getTargetConstant(AMDGPU::VReg_64RegClassID, MVT::i32),
N->getOperand(1) , N->getOperand(2),
N->getOperand(3), N->getOperand(4)
};
return DAG.getMachineNode(AMDGPU::REG_SEQUENCE, DL, MVT::i64, Ops);
}
case AMDGPU::S_LOAD_DWORD_IMM:
NewOpcode = AMDGPU::BUFFER_LOAD_DWORD_ADDR64;
// Fall-through
case AMDGPU::S_LOAD_DWORDX2_SGPR:
if (NewOpcode == N->getMachineOpcode()) {
NewOpcode = AMDGPU::BUFFER_LOAD_DWORDX2_ADDR64;
}
// Fall-through
case AMDGPU::S_LOAD_DWORDX4_IMM:
case AMDGPU::S_LOAD_DWORDX4_SGPR: {
if (NewOpcode == N->getMachineOpcode()) {
NewOpcode = AMDGPU::BUFFER_LOAD_DWORDX4_ADDR64;
}
if (fitsRegClass(DAG, N->getOperand(0), AMDGPU::SReg_64RegClassID)) {
return N;
}
ConstantSDNode *Offset = cast<ConstantSDNode>(N->getOperand(1));
SDValue Ops[] = {
SDValue(DAG.getMachineNode(AMDGPU::SI_ADDR64_RSRC, DL, MVT::i128,
DAG.getConstant(0, MVT::i64)), 0),
N->getOperand(0),
DAG.getConstant(Offset->getSExtValue() << 2, MVT::i32)
};
return DAG.getMachineNode(NewOpcode, DL, N->getVTList(), Ops);
}
}
}

View File

@ -36,6 +36,7 @@ class SITargetLowering : public AMDGPUTargetLowering {
SDNode *foldOperands(MachineSDNode *N, SelectionDAG &DAG) const;
void adjustWritemask(MachineSDNode *&N, SelectionDAG &DAG) const;
MachineSDNode *AdjustRegClass(MachineSDNode *N, SelectionDAG &DAG) const;
public:
SITargetLowering(TargetMachine &tm);