R600/SI: Fix assertion from copying a TargetGlobalAddress
[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   return Reserved;
37 }
38
39 unsigned SIRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
40                                              MachineFunction &MF) const {
41   return RC->getNumRegs();
42 }
43
44 bool SIRegisterInfo::requiresRegisterScavenging(const MachineFunction &Fn) const {
45   return Fn.getFrameInfo()->hasStackObjects();
46 }
47
48 static unsigned getNumSubRegsForSpillOp(unsigned Op) {
49
50   switch (Op) {
51   case AMDGPU::SI_SPILL_S512_SAVE:
52   case AMDGPU::SI_SPILL_S512_RESTORE:
53     return 16;
54   case AMDGPU::SI_SPILL_S256_SAVE:
55   case AMDGPU::SI_SPILL_S256_RESTORE:
56     return 8;
57   case AMDGPU::SI_SPILL_S128_SAVE:
58   case AMDGPU::SI_SPILL_S128_RESTORE:
59     return 4;
60   case AMDGPU::SI_SPILL_S64_SAVE:
61   case AMDGPU::SI_SPILL_S64_RESTORE:
62     return 2;
63   case AMDGPU::SI_SPILL_S32_SAVE:
64   case AMDGPU::SI_SPILL_S32_RESTORE:
65     return 1;
66   default: llvm_unreachable("Invalid spill opcode");
67   }
68 }
69
70 void SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
71                                         int SPAdj, unsigned FIOperandNum,
72                                         RegScavenger *RS) const {
73   MachineFunction *MF = MI->getParent()->getParent();
74   MachineBasicBlock *MBB = MI->getParent();
75   SIMachineFunctionInfo *MFI = MF->getInfo<SIMachineFunctionInfo>();
76   MachineFrameInfo *FrameInfo = MF->getFrameInfo();
77   const SIInstrInfo *TII = static_cast<const SIInstrInfo*>(ST.getInstrInfo());
78   DebugLoc DL = MI->getDebugLoc();
79
80   MachineOperand &FIOp = MI->getOperand(FIOperandNum);
81   int Index = MI->getOperand(FIOperandNum).getIndex();
82
83   switch (MI->getOpcode()) {
84     // SGPR register spill
85     case AMDGPU::SI_SPILL_S512_SAVE:
86     case AMDGPU::SI_SPILL_S256_SAVE:
87     case AMDGPU::SI_SPILL_S128_SAVE:
88     case AMDGPU::SI_SPILL_S64_SAVE:
89     case AMDGPU::SI_SPILL_S32_SAVE: {
90       unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode());
91
92       for (unsigned i = 0, e = NumSubRegs; i < e; ++i) {
93         unsigned SubReg = getPhysRegSubReg(MI->getOperand(0).getReg(),
94                                            &AMDGPU::SGPR_32RegClass, i);
95         struct SIMachineFunctionInfo::SpilledReg Spill =
96             MFI->getSpilledReg(MF, Index, i);
97
98         if (Spill.VGPR == AMDGPU::NoRegister) {
99            LLVMContext &Ctx = MF->getFunction()->getContext();
100            Ctx.emitError("Ran out of VGPRs for spilling SGPR");
101         }
102
103         BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_WRITELANE_B32), Spill.VGPR)
104                 .addReg(SubReg)
105                 .addImm(Spill.Lane);
106
107       }
108       MI->eraseFromParent();
109       break;
110     }
111
112     // SGPR register restore
113     case AMDGPU::SI_SPILL_S512_RESTORE:
114     case AMDGPU::SI_SPILL_S256_RESTORE:
115     case AMDGPU::SI_SPILL_S128_RESTORE:
116     case AMDGPU::SI_SPILL_S64_RESTORE:
117     case AMDGPU::SI_SPILL_S32_RESTORE: {
118       unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode());
119
120       for (unsigned i = 0, e = NumSubRegs; i < e; ++i) {
121         unsigned SubReg = getPhysRegSubReg(MI->getOperand(0).getReg(),
122                                            &AMDGPU::SGPR_32RegClass, i);
123         struct SIMachineFunctionInfo::SpilledReg Spill =
124             MFI->getSpilledReg(MF, Index, i);
125
126         if (Spill.VGPR == AMDGPU::NoRegister) {
127            LLVMContext &Ctx = MF->getFunction()->getContext();
128            Ctx.emitError("Ran out of VGPRs for spilling SGPR");
129         }
130
131         BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_READLANE_B32), SubReg)
132                 .addReg(Spill.VGPR)
133                 .addImm(Spill.Lane);
134
135       }
136       TII->insertNOPs(MI, 3);
137       MI->eraseFromParent();
138       break;
139     }
140
141     default: {
142       int64_t Offset = FrameInfo->getObjectOffset(Index);
143       FIOp.ChangeToImmediate(Offset);
144       if (!TII->isImmOperandLegal(MI, FIOperandNum, FIOp)) {
145         unsigned TmpReg = RS->scavengeRegister(&AMDGPU::VReg_32RegClass, MI, SPAdj);
146         BuildMI(*MBB, MI, MI->getDebugLoc(),
147                 TII->get(AMDGPU::V_MOV_B32_e32), TmpReg)
148                 .addImm(Offset);
149         FIOp.ChangeToRegister(TmpReg, false);
150       }
151     }
152   }
153 }
154
155 const TargetRegisterClass * SIRegisterInfo::getCFGStructurizerRegClass(
156                                                                    MVT VT) const {
157   switch(VT.SimpleTy) {
158     default:
159     case MVT::i32: return &AMDGPU::VReg_32RegClass;
160   }
161 }
162
163 unsigned SIRegisterInfo::getHWRegIndex(unsigned Reg) const {
164   return getEncodingValue(Reg) & 0xff;
165 }
166
167 const TargetRegisterClass *SIRegisterInfo::getPhysRegClass(unsigned Reg) const {
168   assert(!TargetRegisterInfo::isVirtualRegister(Reg));
169
170   const TargetRegisterClass *BaseClasses[] = {
171     &AMDGPU::VReg_32RegClass,
172     &AMDGPU::SReg_32RegClass,
173     &AMDGPU::VReg_64RegClass,
174     &AMDGPU::SReg_64RegClass,
175     &AMDGPU::SReg_128RegClass,
176     &AMDGPU::SReg_256RegClass
177   };
178
179   for (const TargetRegisterClass *BaseClass : BaseClasses) {
180     if (BaseClass->contains(Reg)) {
181       return BaseClass;
182     }
183   }
184   return nullptr;
185 }
186
187 bool SIRegisterInfo::isSGPRClass(const TargetRegisterClass *RC) const {
188   if (!RC) {
189     return false;
190   }
191   return !hasVGPRs(RC);
192 }
193
194 bool SIRegisterInfo::hasVGPRs(const TargetRegisterClass *RC) const {
195   return getCommonSubClass(&AMDGPU::VReg_32RegClass, RC) ||
196          getCommonSubClass(&AMDGPU::VReg_64RegClass, RC) ||
197          getCommonSubClass(&AMDGPU::VReg_96RegClass, RC) ||
198          getCommonSubClass(&AMDGPU::VReg_128RegClass, RC) ||
199          getCommonSubClass(&AMDGPU::VReg_256RegClass, RC) ||
200          getCommonSubClass(&AMDGPU::VReg_512RegClass, RC);
201 }
202
203 const TargetRegisterClass *SIRegisterInfo::getEquivalentVGPRClass(
204                                          const TargetRegisterClass *SRC) const {
205     if (hasVGPRs(SRC)) {
206       return SRC;
207     } else if (SRC == &AMDGPU::SCCRegRegClass) {
208       return &AMDGPU::VCCRegRegClass;
209     } else if (getCommonSubClass(SRC, &AMDGPU::SGPR_32RegClass)) {
210       return &AMDGPU::VReg_32RegClass;
211     } else if (getCommonSubClass(SRC, &AMDGPU::SGPR_64RegClass)) {
212       return &AMDGPU::VReg_64RegClass;
213     } else if (getCommonSubClass(SRC, &AMDGPU::SReg_128RegClass)) {
214       return &AMDGPU::VReg_128RegClass;
215     } else if (getCommonSubClass(SRC, &AMDGPU::SReg_256RegClass)) {
216       return &AMDGPU::VReg_256RegClass;
217     } else if (getCommonSubClass(SRC, &AMDGPU::SReg_512RegClass)) {
218       return &AMDGPU::VReg_512RegClass;
219     }
220     return nullptr;
221 }
222
223 const TargetRegisterClass *SIRegisterInfo::getSubRegClass(
224                          const TargetRegisterClass *RC, unsigned SubIdx) const {
225   if (SubIdx == AMDGPU::NoSubRegister)
226     return RC;
227
228   // If this register has a sub-register, we can safely assume it is a 32-bit
229   // register, because all of SI's sub-registers are 32-bit.
230   if (isSGPRClass(RC)) {
231     return &AMDGPU::SGPR_32RegClass;
232   } else {
233     return &AMDGPU::VGPR_32RegClass;
234   }
235 }
236
237 unsigned SIRegisterInfo::getPhysRegSubReg(unsigned Reg,
238                                           const TargetRegisterClass *SubRC,
239                                           unsigned Channel) const {
240
241   switch (Reg) {
242     case AMDGPU::VCC:
243       switch(Channel) {
244         case 0: return AMDGPU::VCC_LO;
245         case 1: return AMDGPU::VCC_HI;
246         default: llvm_unreachable("Invalid SubIdx for VCC");
247       }
248       break;
249   }
250
251   unsigned Index = getHWRegIndex(Reg);
252   return SubRC->getRegister(Index + Channel);
253 }
254
255 bool SIRegisterInfo::regClassCanUseImmediate(int RCID) const {
256   switch (RCID) {
257   default: return false;
258   case AMDGPU::SSrc_32RegClassID:
259   case AMDGPU::SSrc_64RegClassID:
260   case AMDGPU::VSrc_32RegClassID:
261   case AMDGPU::VSrc_64RegClassID:
262     return true;
263   }
264 }
265
266 bool SIRegisterInfo::regClassCanUseImmediate(
267                              const TargetRegisterClass *RC) const {
268   return regClassCanUseImmediate(RC->getID());
269 }
270
271 unsigned SIRegisterInfo::getPreloadedValue(const MachineFunction &MF,
272                                            enum PreloadedValue Value) const {
273
274   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
275   switch (Value) {
276   case SIRegisterInfo::TGID_X:
277     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 0);
278   case SIRegisterInfo::TGID_Y:
279     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 1);
280   case SIRegisterInfo::TGID_Z:
281     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 2);
282   case SIRegisterInfo::SCRATCH_WAVE_OFFSET:
283     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 4);
284   case SIRegisterInfo::SCRATCH_PTR:
285     return AMDGPU::SGPR2_SGPR3;
286   }
287   llvm_unreachable("unexpected preloaded value type");
288 }