Don't use MRI liveouts in R600.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 5 Feb 2013 17:53:52 +0000 (17:53 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 5 Feb 2013 17:53:52 +0000 (17:53 +0000)
Something very strange is going on with the output registers in this
target. Its ISelLowering code is inserting dangling CopyToReg nodes,
hoping that those physregs won't get clobbered before the RETURN.

This patch adds the output registers as implicit uses on RETURN
instructions in the custom emission pass. I'd much prefer to have those
CopyToReg nodes glued to the RETURNs, but I don't see how.

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

lib/Target/R600/R600ISelLowering.cpp
lib/Target/R600/R600Instructions.td
lib/Target/R600/R600MachineFunctionInfo.h

index 8fe31e0509ba39df01beae03d7dcc521de7ee32e..110dcc18876a9379a19cc300c47c6fecc3c963d8 100644 (file)
@@ -266,6 +266,15 @@ MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
             .addImm(EOP);
     break;
   }
+  case AMDGPU::RETURN: {
+    // RETURN instructions must have the live-out registers as implicit uses,
+    // otherwise they appear dead.
+    R600MachineFunctionInfo *MFI = MF->getInfo<R600MachineFunctionInfo>();
+    MachineInstrBuilder MIB(*MF, MI);
+    for (unsigned i = 0, e = MFI->LiveOuts.size(); i != e; ++i)
+      MIB.addReg(MFI->LiveOuts[i], RegState::Implicit);
+    return BB;
+  }
   }
 
   MI->eraseFromParent();
@@ -348,12 +357,10 @@ SDValue R600TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
     switch (IntrinsicID) {
     case AMDGPUIntrinsic::AMDGPU_store_output: {
       MachineFunction &MF = DAG.getMachineFunction();
-      MachineRegisterInfo &MRI = MF.getRegInfo();
+      R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
       int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue();
       unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister(RegIndex);
-      if (!MRI.isLiveOut(Reg)) {
-        MRI.addLiveOut(Reg);
-      }
+      MFI->LiveOuts.push_back(Reg);
       return DAG.getCopyToReg(Chain, Op.getDebugLoc(), Reg, Op.getOperand(2));
     }
     case AMDGPUIntrinsic::R600_store_pixel_color: {
index bcbb5a107b98bca0ca63d0c65cc36a74fca3a8c1..f935313fe9b3fd0e1c2ae43081be66e97a3720af 100644 (file)
@@ -1580,7 +1580,8 @@ def FNEG_R600 : FNEG<R600_Reg32>;
 //===---------------------------------------------------------------------===//
 // Return instruction
 //===---------------------------------------------------------------------===//
-let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in {
+let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1,
+    usesCustomInserter = 1 in {
   def RETURN          : ILFormat<(outs), (ins variable_ops),
       "RETURN", [(IL_retflag)]>;
 }
index 0cea2117427b8f901f852d5890f51435d891cfc9..ad7b4da45ae81be5b69f893202e37b95dbd5a1c2 100644 (file)
@@ -23,6 +23,7 @@ class R600MachineFunctionInfo : public MachineFunctionInfo {
 
 public:
   R600MachineFunctionInfo(const MachineFunction &MF);
+  SmallVector<unsigned, 4> LiveOuts;
   SDNode *Outputs[16];
 };