llvm.org GIT mirror llvm / 32fc460
Merging r266244: ------------------------------------------------------------------------ r266244 | thomas.stellard | 2016-04-13 13:44:16 -0700 (Wed, 13 Apr 2016) | 13 lines AMDGPU/SI: Add support for spilling VGPRs without having to scavenge registers Summary: When we are spilling SGPRs to scratch memory, we usually don't have free SGPRs to do the address calculation, so we need to re-use the ScratchOffset register for the calculation. Reviewers: arsenm Subscribers: arsenm, llvm-commits Differential Revision: http://reviews.llvm.org/D18917 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_38@271765 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 3 years ago
2 changed file(s) with 29 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
226226 unsigned Value,
227227 unsigned ScratchRsrcReg,
228228 unsigned ScratchOffset,
229 int64_t Offset) const {
229 int64_t Offset,
230 RegScavenger *RS) const {
230231
231232 MachineBasicBlock *MBB = MI->getParent();
232233 MachineFunction *MF = MI->getParent()->getParent();
233 MachineRegisterInfo &MRI = MF->getRegInfo();
234234 const SIInstrInfo *TII =
235235 static_cast(MF->getSubtarget().getInstrInfo());
236 LLVMContext &Ctx = MF->getFunction()->getContext();
237236 DebugLoc DL = MI->getDebugLoc();
238237 bool IsLoad = TII->get(LoadStoreOp).mayLoad();
239238
240239 bool RanOutOfSGPRs = false;
241240 bool Scavenged = false;
242241 unsigned SOffset = ScratchOffset;
242 unsigned OriginalImmOffset = Offset;
243243
244244 unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode());
245245 unsigned Size = NumSubRegs * 4;
246246
247247 if (!isUInt<12>(Offset + Size)) {
248 SOffset = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
248 SOffset = AMDGPU::NoRegister;
249
250 // We don't have access to the register scavenger if this function is called
251 // during PEI::scavengeFrameVirtualRegs().
252 if (RS)
253 SOffset = RS->FindUnusedReg(&AMDGPU::SGPR_32RegClass);
254
249255 if (SOffset == AMDGPU::NoRegister) {
256 // There are no free SGPRs, and since we are in the process of spilling
257 // VGPRs too. Since we need a VGPR in order to spill SGPRs (this is true
258 // on SI/CI and on VI it is true until we implement spilling using scalar
259 // stores), we have no way to free up an SGPR. Our solution here is to
260 // add the offset directly to the ScratchOffset register, and then
261 // subtract the offset after the spill to return ScratchOffset to it's
262 // original value.
250263 RanOutOfSGPRs = true;
251 SOffset = AMDGPU::SGPR0;
264 SOffset = ScratchOffset;
252265 } else {
253266 Scavenged = true;
254267 }
257270 .addImm(Offset);
258271 Offset = 0;
259272 }
260
261 if (RanOutOfSGPRs)
262 Ctx.emitError("Ran out of SGPRs for spilling VGPRS");
263273
264274 for (unsigned i = 0, e = NumSubRegs; i != e; ++i, Offset += 4) {
265275 unsigned SubReg = NumSubRegs > 1 ?
280290 .addImm(0) // tfe
281291 .addReg(Value, RegState::Implicit | getDefRegState(IsLoad))
282292 .setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
293 }
294
295 if (RanOutOfSGPRs) {
296 // Subtract the offset we added to the ScratchOffset register.
297 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_SUB_U32), ScratchOffset)
298 .addReg(ScratchOffset)
299 .addImm(OriginalImmOffset);
283300 }
284301 }
285302
431448 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_rsrc)->getReg(),
432449 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_offset)->getReg(),
433450 FrameInfo->getObjectOffset(Index) +
434 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm());
451 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm(), RS);
435452 MI->eraseFromParent();
436453 break;
437454 case AMDGPU::SI_SPILL_V32_RESTORE:
445462 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_rsrc)->getReg(),
446463 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_offset)->getReg(),
447464 FrameInfo->getObjectOffset(Index) +
448 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm());
465 TII->getNamedOperand(*MI, AMDGPU::OpName::offset)->getImm(), RS);
449466 MI->eraseFromParent();
450467 break;
451468 }
163163 void buildScratchLoadStore(MachineBasicBlock::iterator MI,
164164 unsigned LoadStoreOp, unsigned Value,
165165 unsigned ScratchRsrcReg, unsigned ScratchOffset,
166 int64_t Offset) const;
166 int64_t Offset,
167 RegScavenger *RS) const;
167168 };
168169
169170 } // End namespace llvm