R600/SI: Use eliminateFrameIndex() to expand SGPR spill pseudos
[oota-llvm.git] / lib / Target / R600 / SIMachineFunctionInfo.cpp
1 //===-- SIMachineFunctionInfo.cpp - SI Machine Function Info -------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 /// \file
9 //===----------------------------------------------------------------------===//
10
11
12 #include "SIMachineFunctionInfo.h"
13 #include "SIInstrInfo.h"
14 #include "SIRegisterInfo.h"
15 #include "llvm/CodeGen/MachineFrameInfo.h"
16 #include "llvm/CodeGen/MachineRegisterInfo.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/LLVMContext.h"
19
20 #define MAX_LANES 64
21
22 using namespace llvm;
23
24
25 // Pin the vtable to this file.
26 void SIMachineFunctionInfo::anchor() {}
27
28 SIMachineFunctionInfo::SIMachineFunctionInfo(const MachineFunction &MF)
29   : AMDGPUMachineFunction(MF),
30     PSInputAddr(0),
31     SpillTracker(),
32     NumUserSGPRs(0) { }
33
34 static unsigned createLaneVGPR(MachineRegisterInfo &MRI, MachineFunction *MF) {
35   unsigned VGPR = MRI.createVirtualRegister(&AMDGPU::VReg_32RegClass);
36
37   // We need to add this register as live out for the function, in order to
38   // have the live range calculated directly.
39   //
40   // When register spilling begins, we have already calculated the live
41   // live intervals for all the registers.  Since we are spilling SGPRs to
42   // VGPRs, we need to update the Lane VGPR's live interval every time we
43   // spill or restore a register.
44   //
45   // Unfortunately, there is no good way to update the live interval as
46   // the TargetInstrInfo callbacks for spilling and restoring don't give
47   // us access to the live interval information.
48   //
49   // We are lucky, though, because the InlineSpiller calls
50   // LiveRangeEdit::calculateRegClassAndHint() which iterates through
51   // all the new register that have been created when restoring a register
52   // and calls LiveIntervals::getInterval(), which creates and computes
53   // the live interval for the newly created register.  However, once this
54   // live intervals is created, it doesn't change and since we usually reuse
55   // the Lane VGPR multiple times, this means any uses after the first aren't
56   // added to the live interval.
57   //
58   // To work around this, we add Lane VGPRs to the functions live out list,
59   // so that we can guarantee its live range will cover all of its uses.
60
61   for (MachineBasicBlock &MBB : *MF) {
62     if (MBB.back().getOpcode() == AMDGPU::S_ENDPGM) {
63       MBB.back().addOperand(*MF, MachineOperand::CreateReg(VGPR, false, true));
64       return VGPR;
65     }
66   }
67
68   LLVMContext &Ctx = MF->getFunction()->getContext();
69   Ctx.emitError("Could not find S_ENDPGM instruction.");
70
71   return VGPR;
72 }
73
74 unsigned SIMachineFunctionInfo::RegSpillTracker::reserveLanes(
75     MachineRegisterInfo &MRI, MachineFunction *MF, unsigned NumRegs) {
76   unsigned StartLane = CurrentLane;
77   CurrentLane += NumRegs;
78   if (!LaneVGPR) {
79     LaneVGPR = createLaneVGPR(MRI, MF);
80   } else {
81     if (CurrentLane >= MAX_LANES) {
82       StartLane = CurrentLane = 0;
83       LaneVGPR = createLaneVGPR(MRI, MF);
84     }
85   }
86   return StartLane;
87 }
88
89 void SIMachineFunctionInfo::RegSpillTracker::addSpilledReg(unsigned FrameIndex,
90                                                            unsigned Reg,
91                                                            int Lane) {
92   SpilledRegisters[FrameIndex] = SpilledReg(Reg, Lane);
93 }
94 /// \brief Returns a register that is not used at any point in the function.
95 ///        If all registers are used, then this function will return
96 //         AMDGPU::NoRegister.
97 static unsigned findUnusedVGPR(const MachineRegisterInfo &MRI) {
98
99   const TargetRegisterClass *RC = &AMDGPU::VGPR_32RegClass;
100
101   for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end();
102        I != E; ++I) {
103     if (!MRI.isPhysRegUsed(*I))
104       return *I;
105   }
106   return AMDGPU::NoRegister;
107 }
108
109 SIMachineFunctionInfo::SpilledReg SIMachineFunctionInfo::getSpilledReg(
110                                                        MachineFunction *MF,
111                                                        unsigned FrameIndex,
112                                                        unsigned SubIdx) {
113   const MachineFrameInfo *FrameInfo = MF->getFrameInfo();
114   MachineRegisterInfo &MRI = MF->getRegInfo();
115   int64_t Offset = FrameInfo->getObjectOffset(FrameIndex);
116   Offset += SubIdx * 4;
117
118   unsigned LaneVGPRIdx = Offset / (64 * 4);
119   unsigned Lane = (Offset / 4) % 64;
120
121   struct SpilledReg Spill;
122
123   if (!LaneVGPRs.count(LaneVGPRIdx)) {
124     unsigned LaneVGPR = findUnusedVGPR(MRI);
125     LaneVGPRs[LaneVGPRIdx] = LaneVGPR;
126     MRI.setPhysRegUsed(LaneVGPR);
127
128     // Add this register as live-in to all blocks to avoid machine verifer
129     // complaining about use of an undefined physical register.
130     for (MachineFunction::iterator BI = MF->begin(), BE = MF->end();
131          BI != BE; ++BI) {
132       BI->addLiveIn(LaneVGPR);
133     }
134   }
135
136   Spill.VGPR = LaneVGPRs[LaneVGPRIdx];
137   Spill.Lane = Lane;
138   return Spill;
139 }