R600/SI: Adjust some instructions' out register class after ISel
authorTom Stellard <thomas.stellard@amd.com>
Mon, 3 Jun 2013 17:39:58 +0000 (17:39 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Mon, 3 Jun 2013 17:39:58 +0000 (17:39 +0000)
This is necessary to avoid generating VGPR to SGPR copies in some
cases.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183135 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/R600/SIISelLowering.cpp
lib/Target/R600/SIISelLowering.h

index 2526536e49788324dd7a1d2be8ffd3f59f907809..8726bf346d1ef2a7c4f1cc3dc5e666ed892d075e 100644 (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);
+  }
+  }
+}
index 98236aac8fcd9e636b14682e960e06220b7f4bfb..f37f0a573eb565a8647e5a193ea926c4f5fdf9d2 100644 (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);