[llvm] r273514 - AMDGPU: Fix liveness when expanding m0 loop

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 22 16:40:57 PDT 2016


Author: arsenm
Date: Wed Jun 22 18:40:57 2016
New Revision: 273514

URL: http://llvm.org/viewvc/llvm-project?rev=273514&view=rev
Log:
AMDGPU: Fix liveness when expanding m0 loop

Modified:
    llvm/trunk/lib/Target/AMDGPU/SIInstructions.td
    llvm/trunk/lib/Target/AMDGPU/SILowerControlFlow.cpp
    llvm/trunk/test/CodeGen/AMDGPU/indirect-addressing-si.ll

Modified: llvm/trunk/lib/Target/AMDGPU/SIInstructions.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SIInstructions.td?rev=273514&r1=273513&r2=273514&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/SIInstructions.td (original)
+++ llvm/trunk/lib/Target/AMDGPU/SIInstructions.td Wed Jun 22 18:40:57 2016
@@ -2020,17 +2020,18 @@ def SI_RETURN : InstSI <
   let hasNoSchedulingInfo = 1;
 }
 
-let Uses = [EXEC], Defs = [EXEC, VCC, M0] in {
+let Uses = [EXEC], Defs = [EXEC, VCC, M0],
+  UseNamedOperandTable = 1 in {
 
 class SI_INDIRECT_SRC<RegisterClass rc> : InstSI <
-  (outs VGPR_32:$dst, SReg_64:$temp),
-  (ins rc:$src, VSrc_32:$idx, i32imm:$off)
+  (outs VGPR_32:$vdst, SReg_64:$sdst),
+  (ins rc:$src, VSrc_32:$idx, i32imm:$offset)
 >;
 
 class SI_INDIRECT_DST<RegisterClass rc> : InstSI <
-  (outs rc:$dst, SReg_64:$temp),
-  (ins unknown:$src, VSrc_32:$idx, i32imm:$off, VGPR_32:$val)> {
-  let Constraints = "$src = $dst";
+  (outs rc:$vdst, SReg_64:$sdst),
+  (ins unknown:$src, VSrc_32:$idx, i32imm:$offset, VGPR_32:$val)> {
+  let Constraints = "$src = $vdst";
 }
 
 // TODO: We can support indirect SGPR access.

Modified: llvm/trunk/lib/Target/AMDGPU/SILowerControlFlow.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SILowerControlFlow.cpp?rev=273514&r1=273513&r2=273514&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/SILowerControlFlow.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/SILowerControlFlow.cpp Wed Jun 22 18:40:57 2016
@@ -52,6 +52,7 @@
 #include "AMDGPUSubtarget.h"
 #include "SIInstrInfo.h"
 #include "SIMachineFunctionInfo.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
@@ -88,9 +89,15 @@ private:
   void Kill(MachineInstr &MI);
   void Branch(MachineInstr &MI);
 
+  void splitBlockLiveIns(const MachineBasicBlock &MBB,
+                         const MachineInstr &MI,
+                         MachineBasicBlock &LoopBB,
+                         MachineBasicBlock &RemainderBB,
+                         unsigned SaveReg,
+                         unsigned IdxReg);
+
   void emitLoadM0FromVGPRLoop(MachineBasicBlock &LoopBB, DebugLoc DL,
-                              MachineInstr *MovRel,
-                              unsigned SaveReg, unsigned IdxReg, int Offset);
+                              MachineInstr *MovRel, unsigned IdxReg, int Offset);
 
   bool loadM0(MachineInstr &MI, MachineInstr *MovRel, int Offset = 0);
   void computeIndirectRegAndOffset(unsigned VecReg, unsigned &Reg, int &Offset);
@@ -373,10 +380,41 @@ void SILowerControlFlow::Kill(MachineIns
   MI.eraseFromParent();
 }
 
+// All currently live registers must remain so in the remainder block.
+void SILowerControlFlow::splitBlockLiveIns(const MachineBasicBlock &MBB,
+                                           const MachineInstr &MI,
+                                           MachineBasicBlock &LoopBB,
+                                           MachineBasicBlock &RemainderBB,
+                                           unsigned SaveReg,
+                                           unsigned IdxReg) {
+  LivePhysRegs RemainderLiveRegs(TRI);
+
+  RemainderLiveRegs.addLiveOuts(MBB);
+  for (MachineBasicBlock::const_reverse_iterator I = MBB.rbegin(), E(&MI);
+       I != E; ++I) {
+    RemainderLiveRegs.stepBackward(*I);
+  }
+
+  // Add reg defined in loop body.
+  RemainderLiveRegs.addReg(SaveReg);
+
+  if (const MachineOperand *Val = TII->getNamedOperand(MI, AMDGPU::OpName::val)) {
+    RemainderLiveRegs.addReg(Val->getReg());
+    LoopBB.addLiveIn(Val->getReg());
+  }
+
+  for (unsigned Reg : RemainderLiveRegs)
+    RemainderBB.addLiveIn(Reg);
+
+  unsigned SrcReg = TII->getNamedOperand(MI, AMDGPU::OpName::src)->getReg();
+  LoopBB.addLiveIn(SrcReg);
+  LoopBB.addLiveIn(IdxReg);
+  LoopBB.sortUniqueLiveIns();
+}
+
 void SILowerControlFlow::emitLoadM0FromVGPRLoop(MachineBasicBlock &LoopBB,
                                                 DebugLoc DL,
                                                 MachineInstr *MovRel,
-                                                unsigned SaveReg,
                                                 unsigned IdxReg,
                                                 int Offset) {
   MachineBasicBlock::iterator I = LoopBB.begin();
@@ -421,9 +459,9 @@ void SILowerControlFlow::emitLoadM0FromV
 bool SILowerControlFlow::loadM0(MachineInstr &MI, MachineInstr *MovRel, int Offset) {
   MachineBasicBlock &MBB = *MI.getParent();
   DebugLoc DL = MI.getDebugLoc();
-  MachineBasicBlock::iterator I = MI;
+  MachineBasicBlock::iterator I(&MI);
 
-  unsigned Idx = MI.getOperand(3).getReg();
+  unsigned Idx = TII->getNamedOperand(MI, AMDGPU::OpName::idx)->getReg();
 
   if (AMDGPU::SReg_32RegClass.contains(Idx)) {
     if (Offset) {
@@ -441,14 +479,16 @@ bool SILowerControlFlow::loadM0(MachineI
   }
 
   MachineFunction &MF = *MBB.getParent();
-  unsigned Save = MI.getOperand(1).getReg();
+  MachineOperand *SaveOp = TII->getNamedOperand(MI, AMDGPU::OpName::sdst);
+  SaveOp->setIsDead(false);
+  unsigned Save = SaveOp->getReg();
 
   // Reading from a VGPR requires looping over all workitems in the wavefront.
   assert(AMDGPU::SReg_64RegClass.contains(Save) &&
          AMDGPU::VGPR_32RegClass.contains(Idx));
 
   // Save the EXEC mask
-  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::S_MOV_B64), Save)
+  BuildMI(MBB, I, DL, TII->get(AMDGPU::S_MOV_B64), Save)
     .addReg(AMDGPU::EXEC);
 
   // To insert the loop we need to split the block. Move everything after this
@@ -464,11 +504,14 @@ bool SILowerControlFlow::loadM0(MachineI
   LoopBB->addSuccessor(LoopBB);
   LoopBB->addSuccessor(RemainderBB);
 
+  if (TRI->trackLivenessAfterRegAlloc(MF))
+    splitBlockLiveIns(MBB, MI, *LoopBB, *RemainderBB, Save, Idx);
+
   // Move the rest of the block into a new block.
   RemainderBB->transferSuccessors(&MBB);
   RemainderBB->splice(RemainderBB->begin(), &MBB, I, MBB.end());
 
-  emitLoadM0FromVGPRLoop(*LoopBB, DL, MovRel, Save, Idx, Offset);
+  emitLoadM0FromVGPRLoop(*LoopBB, DL, MovRel, Idx, Offset);
 
   MachineBasicBlock::iterator First = RemainderBB->begin();
   BuildMI(*RemainderBB, First, DL, TII->get(AMDGPU::S_MOV_B64), AMDGPU::EXEC)
@@ -511,16 +554,16 @@ bool SILowerControlFlow::indirectSrc(Mac
   DebugLoc DL = MI.getDebugLoc();
 
   unsigned Dst = MI.getOperand(0).getReg();
-  unsigned Vec = MI.getOperand(2).getReg();
-  int Off = MI.getOperand(4).getImm();
+  unsigned Vec = TII->getNamedOperand(MI, AMDGPU::OpName::src)->getReg();
+  int Off = TII->getNamedOperand(MI, AMDGPU::OpName::offset)->getImm();
   unsigned Reg;
 
   computeIndirectRegAndOffset(Vec, Reg, Off);
 
   MachineInstr *MovRel =
     BuildMI(*MBB.getParent(), DL, TII->get(AMDGPU::V_MOVRELS_B32_e32), Dst)
-            .addReg(Reg)
-            .addReg(Vec, RegState::Implicit);
+    .addReg(Reg)
+    .addReg(Vec, RegState::Implicit);
 
   return loadM0(MI, MovRel, Off);
 }
@@ -531,17 +574,17 @@ bool SILowerControlFlow::indirectDst(Mac
   DebugLoc DL = MI.getDebugLoc();
 
   unsigned Dst = MI.getOperand(0).getReg();
-  int Off = MI.getOperand(4).getImm();
-  unsigned Val = MI.getOperand(5).getReg();
+  int Off = TII->getNamedOperand(MI, AMDGPU::OpName::offset)->getImm();
+  unsigned Val = TII->getNamedOperand(MI, AMDGPU::OpName::val)->getReg();
   unsigned Reg;
 
   computeIndirectRegAndOffset(Dst, Reg, Off);
 
   MachineInstr *MovRel =
     BuildMI(*MBB.getParent(), DL, TII->get(AMDGPU::V_MOVRELD_B32_e32))
-            .addReg(Reg, RegState::Define)
-            .addReg(Val)
-            .addReg(Dst, RegState::Implicit);
+    .addReg(Reg, RegState::Define)
+    .addReg(Val)
+    .addReg(Dst, RegState::Implicit);
 
   return loadM0(MI, MovRel, Off);
 }

Modified: llvm/trunk/test/CodeGen/AMDGPU/indirect-addressing-si.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/indirect-addressing-si.ll?rev=273514&r1=273513&r2=273514&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AMDGPU/indirect-addressing-si.ll (original)
+++ llvm/trunk/test/CodeGen/AMDGPU/indirect-addressing-si.ll Wed Jun 22 18:40:57 2016
@@ -220,9 +220,18 @@ entry:
   %idx0 = load volatile i32, i32 addrspace(1)* %gep
   %idx1 = add i32 %idx0, 1
   %val0 = extractelement <4 x i32> <i32 7, i32 9, i32 11, i32 13>, i32 %idx0
+  %live.out.reg = call i32 asm sideeffect "s_mov_b32 $0, 17", "={SGPR4}" ()
   %val1 = extractelement <4 x i32> <i32 7, i32 9, i32 11, i32 13>, i32 %idx1
   store volatile i32 %val0, i32 addrspace(1)* %out0
   store volatile i32 %val1, i32 addrspace(1)* %out0
+  %cmp = icmp eq i32 %id, 0
+  br i1 %cmp, label %bb1, label %bb2
+
+bb1:
+  store volatile i32 %live.out.reg, i32 addrspace(1)* undef
+  br label %bb2
+
+bb2:
   ret void
 }
 
@@ -230,7 +239,7 @@ entry:
 ; CHECK-DAG: s_load_dwordx4 s{{\[}}[[S_ELT0:[0-9]+]]:[[S_ELT3:[0-9]+]]{{\]}}
 ; CHECK-DAG: {{buffer|flat}}_load_dword [[IDX0:v[0-9]+]]
 ; CHECK-DAG: v_mov_b32_e32 [[VEC_ELT0:v[0-9]+]], s[[S_ELT0]]
-; CHECK-DAG: v_mov_b32_e32 [[INS0:v[0-9]+]], 62
+; CHECK-DAG: v_mov_b32 [[INS0:v[0-9]+]], 62
 ; CHECK-DAG: s_waitcnt vmcnt(0)
 
 ; CHECK: s_mov_b64 [[MASK:s\[[0-9]+:[0-9]+\]]], exec
@@ -259,6 +268,8 @@ entry:
 ; CHECK: s_cbranch_execnz [[LOOP1]]
 
 ; CHECK: buffer_store_dwordx4 v{{\[}}[[MOVREL0]]:
+
+; CHECK: buffer_store_dword [[INS0]]
 define void @insert_vgpr_offset_multiple_in_block(<4 x i32> addrspace(1)* %out0, <4 x i32> addrspace(1)* %out1, i32 addrspace(1)* %in, <4 x i32> %vec0) #0 {
 entry:
   %id = call i32 @llvm.amdgcn.workitem.id.x() #1
@@ -266,9 +277,18 @@ entry:
   %gep = getelementptr inbounds i32, i32 addrspace(1)* %in, i64 %id.ext
   %idx0 = load volatile i32, i32 addrspace(1)* %gep
   %idx1 = add i32 %idx0, 1
-  %vec1 = insertelement <4 x i32> %vec0, i32 62, i32 %idx0
+  %live.out.val = call i32 asm sideeffect "v_mov_b32 $0, 62", "=v"()
+  %vec1 = insertelement <4 x i32> %vec0, i32 %live.out.val, i32 %idx0
   %vec2 = insertelement <4 x i32> %vec1, i32 63, i32 %idx1
   store volatile <4 x i32> %vec2, <4 x i32> addrspace(1)* %out0
+  %cmp = icmp eq i32 %id, 0
+  br i1 %cmp, label %bb1, label %bb2
+
+bb1:
+  store volatile i32 %live.out.val, i32 addrspace(1)* undef
+  br label %bb2
+
+bb2:
   ret void
 }
 




More information about the llvm-commits mailing list