blob: 6aff4b5700d4a45f2efaa3f0dbaee839bebf3558 [file] [log] [blame]
Matt Arsenault0c90e952015-11-06 18:17:45 +00001//===----------------------- SIFrameLowering.cpp --------------------------===//
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#include "SIFrameLowering.h"
Matt Arsenault0e3d3892015-11-30 21:15:53 +000011#include "SIInstrInfo.h"
12#include "SIMachineFunctionInfo.h"
Matt Arsenault0c90e952015-11-06 18:17:45 +000013#include "SIRegisterInfo.h"
14#include "llvm/CodeGen/MachineFrameInfo.h"
15#include "llvm/CodeGen/MachineFunction.h"
Matt Arsenault0e3d3892015-11-30 21:15:53 +000016#include "llvm/CodeGen/MachineInstrBuilder.h"
Matt Arsenault0c90e952015-11-06 18:17:45 +000017#include "llvm/CodeGen/RegisterScavenging.h"
18
19using namespace llvm;
20
Matt Arsenault0e3d3892015-11-30 21:15:53 +000021
22static bool hasOnlySGPRSpills(const SIMachineFunctionInfo *FuncInfo,
23 const MachineFrameInfo *FrameInfo) {
24 if (!FuncInfo->hasSpilledSGPRs())
25 return false;
26
27 if (FuncInfo->hasSpilledVGPRs())
28 return false;
29
30 for (int I = FrameInfo->getObjectIndexBegin(),
31 E = FrameInfo->getObjectIndexEnd(); I != E; ++I) {
32 if (!FrameInfo->isSpillSlotObjectIndex(I))
33 return false;
34 }
35
36 return true;
37}
38
39void SIFrameLowering::emitPrologue(MachineFunction &MF,
40 MachineBasicBlock &MBB) const {
41 if (!MF.getFrameInfo()->hasStackObjects())
42 return;
43
44 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
45
46 const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
47
48 // If we only have SGPR spills, we won't actually be using scratch memory
49 // since these spill to VGPRs.
50 //
51 // FIXME: We should be cleaning up these unused SGPR spill frame indices
52 // somewhere.
53 if (hasOnlySGPRSpills(MFI, MF.getFrameInfo()))
54 return;
55
56 const SIInstrInfo *TII =
57 static_cast<const SIInstrInfo *>(MF.getSubtarget().getInstrInfo());
58 const SIRegisterInfo *TRI = &TII->getRegisterInfo();
59
60 // We need to insert initialization of the scratch resource descriptor.
61 unsigned ScratchRsrcReg = MFI->getScratchRSrcReg();
62 assert(ScratchRsrcReg != AMDGPU::NoRegister);
63
64 uint64_t Rsrc23 = TII->getScratchRsrcWords23();
65 MachineBasicBlock::iterator I = MBB.begin();
66 DebugLoc DL;
67
68 unsigned Rsrc0 = TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub0);
69 unsigned Rsrc1 = TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub1);
70 unsigned Rsrc2 = TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub2);
71 unsigned Rsrc3 = TRI->getSubReg(ScratchRsrcReg, AMDGPU::sub3);
72
73 BuildMI(MBB, I, DL, TII->get(AMDGPU::S_MOV_B32), Rsrc0)
74 .addExternalSymbol("SCRATCH_RSRC_DWORD0");
75
76 BuildMI(MBB, I, DL, TII->get(AMDGPU::S_MOV_B32), Rsrc1)
77 .addExternalSymbol("SCRATCH_RSRC_DWORD1");
78
79 BuildMI(MBB, I, DL, TII->get(AMDGPU::S_MOV_B32), Rsrc2)
80 .addImm(Rsrc23 & 0xffffffff);
81
82 BuildMI(MBB, I, DL, TII->get(AMDGPU::S_MOV_B32), Rsrc3)
83 .addImm(Rsrc23 >> 32);
84}
85
Matt Arsenault0c90e952015-11-06 18:17:45 +000086void SIFrameLowering::processFunctionBeforeFrameFinalized(
87 MachineFunction &MF,
88 RegScavenger *RS) const {
89 MachineFrameInfo *MFI = MF.getFrameInfo();
Matt Arsenault0e3d3892015-11-30 21:15:53 +000090
91 if (!MFI->hasStackObjects())
92 return;
93
Matt Arsenault0c90e952015-11-06 18:17:45 +000094 bool MayNeedScavengingEmergencySlot = MFI->hasStackObjects();
95
96 assert((RS || !MayNeedScavengingEmergencySlot) &&
97 "RegScavenger required if spilling");
98
99 if (MayNeedScavengingEmergencySlot) {
100 int ScavengeFI = MFI->CreateSpillStackObject(
101 AMDGPU::SGPR_32RegClass.getSize(),
102 AMDGPU::SGPR_32RegClass.getAlignment());
103 RS->addScavengingFrameIndex(ScavengeFI);
104 }
105}