R600/SI: Fix SIRegisterInfo::getPhysRegSubReg()
[oota-llvm.git] / lib / Target / R600 / SIRegisterInfo.cpp
1 //===-- SIRegisterInfo.cpp - SI Register Information ---------------------===//
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 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// \brief SI implementation of the TargetRegisterInfo class.
12 //
13 //===----------------------------------------------------------------------===//
14
15
16 #include "SIRegisterInfo.h"
17 #include "AMDGPUSubtarget.h"
18 #include "SIInstrInfo.h"
19 #include "SIMachineFunctionInfo.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/RegisterScavenging.h"
23 #include "llvm/IR/Function.h"
24 #include "llvm/IR/LLVMContext.h"
25
26 using namespace llvm;
27
28 SIRegisterInfo::SIRegisterInfo(const AMDGPUSubtarget &st)
29 : AMDGPURegisterInfo(st)
30   { }
31
32 BitVector SIRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
33   BitVector Reserved(getNumRegs());
34   Reserved.set(AMDGPU::EXEC);
35   Reserved.set(AMDGPU::INDIRECT_BASE_ADDR);
36   Reserved.set(AMDGPU::FLAT_SCR);
37
38   // Reserve some VGPRs to use as temp registers in case we have to spill VGPRs
39   Reserved.set(AMDGPU::VGPR255);
40   Reserved.set(AMDGPU::VGPR254);
41
42   return Reserved;
43 }
44
45 unsigned SIRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
46                                              MachineFunction &MF) const {
47   return RC->getNumRegs();
48 }
49
50 bool SIRegisterInfo::requiresRegisterScavenging(const MachineFunction &Fn) const {
51   return Fn.getFrameInfo()->hasStackObjects();
52 }
53
54 static unsigned getNumSubRegsForSpillOp(unsigned Op) {
55
56   switch (Op) {
57   case AMDGPU::SI_SPILL_S512_SAVE:
58   case AMDGPU::SI_SPILL_S512_RESTORE:
59   case AMDGPU::SI_SPILL_V512_SAVE:
60   case AMDGPU::SI_SPILL_V512_RESTORE:
61     return 16;
62   case AMDGPU::SI_SPILL_S256_SAVE:
63   case AMDGPU::SI_SPILL_S256_RESTORE:
64   case AMDGPU::SI_SPILL_V256_SAVE:
65   case AMDGPU::SI_SPILL_V256_RESTORE:
66     return 8;
67   case AMDGPU::SI_SPILL_S128_SAVE:
68   case AMDGPU::SI_SPILL_S128_RESTORE:
69   case AMDGPU::SI_SPILL_V128_SAVE:
70   case AMDGPU::SI_SPILL_V128_RESTORE:
71     return 4;
72   case AMDGPU::SI_SPILL_V96_SAVE:
73   case AMDGPU::SI_SPILL_V96_RESTORE:
74     return 3;
75   case AMDGPU::SI_SPILL_S64_SAVE:
76   case AMDGPU::SI_SPILL_S64_RESTORE:
77   case AMDGPU::SI_SPILL_V64_SAVE:
78   case AMDGPU::SI_SPILL_V64_RESTORE:
79     return 2;
80   case AMDGPU::SI_SPILL_S32_SAVE:
81   case AMDGPU::SI_SPILL_S32_RESTORE:
82   case AMDGPU::SI_SPILL_V32_SAVE:
83   case AMDGPU::SI_SPILL_V32_RESTORE:
84     return 1;
85   default: llvm_unreachable("Invalid spill opcode");
86   }
87 }
88
89 void SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
90                                         int SPAdj, unsigned FIOperandNum,
91                                         RegScavenger *RS) const {
92   MachineFunction *MF = MI->getParent()->getParent();
93   MachineBasicBlock *MBB = MI->getParent();
94   SIMachineFunctionInfo *MFI = MF->getInfo<SIMachineFunctionInfo>();
95   MachineFrameInfo *FrameInfo = MF->getFrameInfo();
96   const SIInstrInfo *TII = static_cast<const SIInstrInfo*>(ST.getInstrInfo());
97   DebugLoc DL = MI->getDebugLoc();
98
99   MachineOperand &FIOp = MI->getOperand(FIOperandNum);
100   int Index = MI->getOperand(FIOperandNum).getIndex();
101
102   switch (MI->getOpcode()) {
103     // SGPR register spill
104     case AMDGPU::SI_SPILL_S512_SAVE:
105     case AMDGPU::SI_SPILL_S256_SAVE:
106     case AMDGPU::SI_SPILL_S128_SAVE:
107     case AMDGPU::SI_SPILL_S64_SAVE:
108     case AMDGPU::SI_SPILL_S32_SAVE: {
109       unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode());
110
111       for (unsigned i = 0, e = NumSubRegs; i < e; ++i) {
112         unsigned SubReg = getPhysRegSubReg(MI->getOperand(0).getReg(),
113                                            &AMDGPU::SGPR_32RegClass, i);
114         struct SIMachineFunctionInfo::SpilledReg Spill =
115             MFI->getSpilledReg(MF, Index, i);
116
117         if (Spill.VGPR == AMDGPU::NoRegister) {
118            LLVMContext &Ctx = MF->getFunction()->getContext();
119            Ctx.emitError("Ran out of VGPRs for spilling SGPR");
120         }
121
122         BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_WRITELANE_B32), Spill.VGPR)
123                 .addReg(SubReg)
124                 .addImm(Spill.Lane);
125
126       }
127       MI->eraseFromParent();
128       break;
129     }
130
131     // SGPR register restore
132     case AMDGPU::SI_SPILL_S512_RESTORE:
133     case AMDGPU::SI_SPILL_S256_RESTORE:
134     case AMDGPU::SI_SPILL_S128_RESTORE:
135     case AMDGPU::SI_SPILL_S64_RESTORE:
136     case AMDGPU::SI_SPILL_S32_RESTORE: {
137       unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode());
138
139       for (unsigned i = 0, e = NumSubRegs; i < e; ++i) {
140         unsigned SubReg = getPhysRegSubReg(MI->getOperand(0).getReg(),
141                                            &AMDGPU::SGPR_32RegClass, i);
142         struct SIMachineFunctionInfo::SpilledReg Spill =
143             MFI->getSpilledReg(MF, Index, i);
144
145         if (Spill.VGPR == AMDGPU::NoRegister) {
146            LLVMContext &Ctx = MF->getFunction()->getContext();
147            Ctx.emitError("Ran out of VGPRs for spilling SGPR");
148         }
149
150         BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_READLANE_B32), SubReg)
151                 .addReg(Spill.VGPR)
152                 .addImm(Spill.Lane);
153
154       }
155       TII->insertNOPs(MI, 3);
156       MI->eraseFromParent();
157       break;
158     }
159
160     // VGPR register spill
161     case AMDGPU::SI_SPILL_V512_SAVE:
162     case AMDGPU::SI_SPILL_V256_SAVE:
163     case AMDGPU::SI_SPILL_V128_SAVE:
164     case AMDGPU::SI_SPILL_V96_SAVE:
165     case AMDGPU::SI_SPILL_V64_SAVE:
166     case AMDGPU::SI_SPILL_V32_SAVE: {
167       unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode());
168       unsigned SrcReg = MI->getOperand(0).getReg();
169       int64_t Offset = FrameInfo->getObjectOffset(Index);
170       unsigned Size = NumSubRegs * 4;
171       unsigned TmpReg = RS->scavengeRegister(&AMDGPU::VGPR_32RegClass, MI, 0);
172
173       for (unsigned i = 0, e = NumSubRegs; i != e; ++i) {
174         unsigned SubReg = NumSubRegs > 1 ?
175             getPhysRegSubReg(SrcReg, &AMDGPU::VGPR_32RegClass, i) :
176             SrcReg;
177         Offset += (i * 4);
178         MFI->LDSWaveSpillSize = std::max((unsigned)Offset + 4, (unsigned)MFI->LDSWaveSpillSize);
179
180         unsigned AddrReg = TII->calculateLDSSpillAddress(*MBB, MI, RS, TmpReg,
181                                                          Offset, Size);
182
183         if (AddrReg == AMDGPU::NoRegister) {
184            LLVMContext &Ctx = MF->getFunction()->getContext();
185            Ctx.emitError("Ran out of VGPRs for spilling VGPRS");
186            AddrReg = AMDGPU::VGPR0;
187         }
188
189         // Store the value in LDS
190         BuildMI(*MBB, MI, DL, TII->get(AMDGPU::DS_WRITE_B32))
191                 .addImm(0) // gds
192                 .addReg(AddrReg, RegState::Kill) // addr
193                 .addReg(SubReg) // data0
194                 .addImm(0); // offset
195       }
196
197       MI->eraseFromParent();
198       break;
199     }
200     case AMDGPU::SI_SPILL_V32_RESTORE:
201     case AMDGPU::SI_SPILL_V64_RESTORE:
202     case AMDGPU::SI_SPILL_V128_RESTORE:
203     case AMDGPU::SI_SPILL_V256_RESTORE:
204     case AMDGPU::SI_SPILL_V512_RESTORE: {
205       unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode());
206       unsigned DstReg = MI->getOperand(0).getReg();
207       int64_t Offset = FrameInfo->getObjectOffset(Index);
208       unsigned Size = NumSubRegs * 4;
209       unsigned TmpReg = RS->scavengeRegister(&AMDGPU::VGPR_32RegClass, MI, 0);
210
211       // FIXME: We could use DS_READ_B64 here to optimize for larger registers.
212       for (unsigned i = 0, e = NumSubRegs; i != e; ++i) {
213         unsigned SubReg = NumSubRegs > 1 ?
214             getPhysRegSubReg(DstReg, &AMDGPU::VGPR_32RegClass, i) :
215             DstReg;
216
217         Offset += (i * 4);
218         unsigned AddrReg = TII->calculateLDSSpillAddress(*MBB, MI, RS, TmpReg,
219                                                           Offset, Size);
220         if (AddrReg == AMDGPU::NoRegister) {
221            LLVMContext &Ctx = MF->getFunction()->getContext();
222            Ctx.emitError("Ran out of VGPRs for spilling VGPRs");
223            AddrReg = AMDGPU::VGPR0;
224         }
225
226         BuildMI(*MBB, MI, DL, TII->get(AMDGPU::DS_READ_B32), SubReg)
227                 .addImm(0) // gds
228                 .addReg(AddrReg, RegState::Kill) // addr
229                 .addImm(0); //offset
230       }
231       MI->eraseFromParent();
232       break;
233     }
234
235     default: {
236       int64_t Offset = FrameInfo->getObjectOffset(Index);
237       FIOp.ChangeToImmediate(Offset);
238       if (!TII->isImmOperandLegal(MI, FIOperandNum, FIOp)) {
239         unsigned TmpReg = RS->scavengeRegister(&AMDGPU::VReg_32RegClass, MI, SPAdj);
240         BuildMI(*MBB, MI, MI->getDebugLoc(),
241                 TII->get(AMDGPU::V_MOV_B32_e32), TmpReg)
242                 .addImm(Offset);
243         FIOp.ChangeToRegister(TmpReg, false);
244       }
245     }
246   }
247 }
248
249 const TargetRegisterClass * SIRegisterInfo::getCFGStructurizerRegClass(
250                                                                    MVT VT) const {
251   switch(VT.SimpleTy) {
252     default:
253     case MVT::i32: return &AMDGPU::VReg_32RegClass;
254   }
255 }
256
257 unsigned SIRegisterInfo::getHWRegIndex(unsigned Reg) const {
258   return getEncodingValue(Reg) & 0xff;
259 }
260
261 const TargetRegisterClass *SIRegisterInfo::getPhysRegClass(unsigned Reg) const {
262   assert(!TargetRegisterInfo::isVirtualRegister(Reg));
263
264   const TargetRegisterClass *BaseClasses[] = {
265     &AMDGPU::VReg_32RegClass,
266     &AMDGPU::SReg_32RegClass,
267     &AMDGPU::VReg_64RegClass,
268     &AMDGPU::SReg_64RegClass,
269     &AMDGPU::VReg_96RegClass,
270     &AMDGPU::VReg_128RegClass,
271     &AMDGPU::SReg_128RegClass,
272     &AMDGPU::VReg_256RegClass,
273     &AMDGPU::SReg_256RegClass,
274     &AMDGPU::VReg_512RegClass
275   };
276
277   for (const TargetRegisterClass *BaseClass : BaseClasses) {
278     if (BaseClass->contains(Reg)) {
279       return BaseClass;
280     }
281   }
282   return nullptr;
283 }
284
285 bool SIRegisterInfo::isSGPRClass(const TargetRegisterClass *RC) const {
286   if (!RC) {
287     return false;
288   }
289   return !hasVGPRs(RC);
290 }
291
292 bool SIRegisterInfo::hasVGPRs(const TargetRegisterClass *RC) const {
293   return getCommonSubClass(&AMDGPU::VReg_32RegClass, RC) ||
294          getCommonSubClass(&AMDGPU::VReg_64RegClass, RC) ||
295          getCommonSubClass(&AMDGPU::VReg_96RegClass, RC) ||
296          getCommonSubClass(&AMDGPU::VReg_128RegClass, RC) ||
297          getCommonSubClass(&AMDGPU::VReg_256RegClass, RC) ||
298          getCommonSubClass(&AMDGPU::VReg_512RegClass, RC);
299 }
300
301 const TargetRegisterClass *SIRegisterInfo::getEquivalentVGPRClass(
302                                          const TargetRegisterClass *SRC) const {
303     if (hasVGPRs(SRC)) {
304       return SRC;
305     } else if (SRC == &AMDGPU::SCCRegRegClass) {
306       return &AMDGPU::VCCRegRegClass;
307     } else if (getCommonSubClass(SRC, &AMDGPU::SGPR_32RegClass)) {
308       return &AMDGPU::VReg_32RegClass;
309     } else if (getCommonSubClass(SRC, &AMDGPU::SGPR_64RegClass)) {
310       return &AMDGPU::VReg_64RegClass;
311     } else if (getCommonSubClass(SRC, &AMDGPU::SReg_128RegClass)) {
312       return &AMDGPU::VReg_128RegClass;
313     } else if (getCommonSubClass(SRC, &AMDGPU::SReg_256RegClass)) {
314       return &AMDGPU::VReg_256RegClass;
315     } else if (getCommonSubClass(SRC, &AMDGPU::SReg_512RegClass)) {
316       return &AMDGPU::VReg_512RegClass;
317     }
318     return nullptr;
319 }
320
321 const TargetRegisterClass *SIRegisterInfo::getSubRegClass(
322                          const TargetRegisterClass *RC, unsigned SubIdx) const {
323   if (SubIdx == AMDGPU::NoSubRegister)
324     return RC;
325
326   // If this register has a sub-register, we can safely assume it is a 32-bit
327   // register, because all of SI's sub-registers are 32-bit.
328   if (isSGPRClass(RC)) {
329     return &AMDGPU::SGPR_32RegClass;
330   } else {
331     return &AMDGPU::VGPR_32RegClass;
332   }
333 }
334
335 unsigned SIRegisterInfo::getPhysRegSubReg(unsigned Reg,
336                                           const TargetRegisterClass *SubRC,
337                                           unsigned Channel) const {
338
339   switch (Reg) {
340     case AMDGPU::VCC:
341       switch(Channel) {
342         case 0: return AMDGPU::VCC_LO;
343         case 1: return AMDGPU::VCC_HI;
344         default: llvm_unreachable("Invalid SubIdx for VCC");
345       }
346
347   case AMDGPU::FLAT_SCR:
348     switch (Channel) {
349     case 0:
350       return AMDGPU::FLAT_SCR_LO;
351     case 1:
352       return AMDGPU::FLAT_SCR_HI;
353     default:
354       llvm_unreachable("Invalid SubIdx for FLAT_SCR");
355     }
356     break;
357
358   case AMDGPU::EXEC:
359     switch (Channel) {
360     case 0:
361       return AMDGPU::EXEC_LO;
362     case 1:
363       return AMDGPU::EXEC_HI;
364     default:
365       llvm_unreachable("Invalid SubIdx for EXEC");
366     }
367     break;
368   }
369
370   const TargetRegisterClass *RC = getPhysRegClass(Reg);
371   // 32-bit registers don't have sub-registers, so we can just return the
372   // Reg.  We need to have this check here, because the calculation below
373   // using getHWRegIndex() will fail with special 32-bit registers like
374   // VCC_LO, VCC_HI, EXEC_LO, EXEC_HI and M0.
375   if (RC->getSize() == 4) {
376     assert(Channel == 0);
377     return Reg;
378   }
379
380   unsigned Index = getHWRegIndex(Reg);
381   return SubRC->getRegister(Index + Channel);
382 }
383
384 bool SIRegisterInfo::regClassCanUseLiteralConstant(int RCID) const {
385   switch (RCID) {
386   default: return false;
387   case AMDGPU::SSrc_32RegClassID:
388   case AMDGPU::SSrc_64RegClassID:
389   case AMDGPU::VSrc_32RegClassID:
390   case AMDGPU::VSrc_64RegClassID:
391     return true;
392   }
393 }
394
395 bool SIRegisterInfo::regClassCanUseLiteralConstant(
396                              const TargetRegisterClass *RC) const {
397   return regClassCanUseLiteralConstant(RC->getID());
398 }
399
400 bool SIRegisterInfo::regClassCanUseInlineConstant(int RCID) const {
401   if (regClassCanUseLiteralConstant(RCID))
402     return true;
403
404   switch (RCID) {
405   default: return false;
406   case AMDGPU::VCSrc_32RegClassID:
407   case AMDGPU::VCSrc_64RegClassID:
408     return true;
409   }
410 }
411
412 bool SIRegisterInfo::regClassCanUseInlineConstant(
413                             const TargetRegisterClass *RC) const {
414   return regClassCanUseInlineConstant(RC->getID());
415 }
416
417
418 unsigned SIRegisterInfo::getPreloadedValue(const MachineFunction &MF,
419                                            enum PreloadedValue Value) const {
420
421   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
422   switch (Value) {
423   case SIRegisterInfo::TGID_X:
424     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 0);
425   case SIRegisterInfo::TGID_Y:
426     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 1);
427   case SIRegisterInfo::TGID_Z:
428     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 2);
429   case SIRegisterInfo::SCRATCH_WAVE_OFFSET:
430     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 4);
431   case SIRegisterInfo::SCRATCH_PTR:
432     return AMDGPU::SGPR2_SGPR3;
433   case SIRegisterInfo::INPUT_PTR:
434     return AMDGPU::SGPR0_SGPR1;
435   case SIRegisterInfo::TIDIG_X:
436     return AMDGPU::VGPR0;
437   case SIRegisterInfo::TIDIG_Y:
438     return AMDGPU::VGPR1;
439   case SIRegisterInfo::TIDIG_Z:
440     return AMDGPU::VGPR2;
441   }
442   llvm_unreachable("unexpected preloaded value type");
443 }
444
445 /// \brief Returns a register that is not used at any point in the function.
446 ///        If all registers are used, then this function will return
447 //         AMDGPU::NoRegister.
448 unsigned SIRegisterInfo::findUnusedVGPR(const MachineRegisterInfo &MRI) const {
449
450   const TargetRegisterClass *RC = &AMDGPU::VGPR_32RegClass;
451
452   for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end();
453        I != E; ++I) {
454     if (!MRI.isPhysRegUsed(*I))
455       return *I;
456   }
457   return AMDGPU::NoRegister;
458 }
459