1 //===-- HexagonFrameLowering.cpp - Define frame lowering ------------------===//
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
11 #include "HexagonFrameLowering.h"
12 #include "Hexagon.h"
13 #include "HexagonInstrInfo.h"
14 #include "HexagonMachineFunctionInfo.h"
15 #include "HexagonRegisterInfo.h"
16 #include "HexagonSubtarget.h"
17 #include "HexagonTargetMachine.h"
18 #include "llvm/ADT/BitVector.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/CodeGen/AsmPrinter.h"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineModuleInfo.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/CodeGen/RegisterScavenging.h"
28 #include "llvm/IR/Function.h"
29 #include "llvm/IR/Type.h"
30 #include "llvm/MC/MCAsmInfo.h"
31 #include "llvm/MC/MachineLocation.h"
32 #include "llvm/Support/CommandLine.h"
33 #include "llvm/Target/TargetInstrInfo.h"
34 #include "llvm/Target/TargetMachine.h"
35 #include "llvm/Target/TargetOptions.h"
36
37 using namespace llvm;
38
39 static cl::opt<bool> DisableDeallocRet(
40 "disable-hexagon-dealloc-ret",
41 cl::Hidden,
42 cl::desc("Disable Dealloc Return for Hexagon target"));
43
44 /// determineFrameLayout - Determine the size of the frame and maximum call
45 /// frame size.
determineFrameLayout(MachineFunction & MF) const46 void HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const {
47 MachineFrameInfo *MFI = MF.getFrameInfo();
48
49 // Get the number of bytes to allocate from the FrameInfo.
50 unsigned FrameSize = MFI->getStackSize();
51
52 // Get the alignments provided by the target.
53 unsigned TargetAlign =
54 MF.getSubtarget().getFrameLowering()->getStackAlignment();
55 // Get the maximum call frame size of all the calls.
56 unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
57
58 // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
59 // that allocations will be aligned.
60 if (MFI->hasVarSizedObjects())
61 maxCallFrameSize = RoundUpToAlignment(maxCallFrameSize, TargetAlign);
62
63 // Update maximum call frame size.
64 MFI->setMaxCallFrameSize(maxCallFrameSize);
65
66 // Include call frame size in total.
67 FrameSize += maxCallFrameSize;
68
69 // Make sure the frame is aligned.
70 FrameSize = RoundUpToAlignment(FrameSize, TargetAlign);
71
72 // Update frame info.
73 MFI->setStackSize(FrameSize);
74 }
75
76
emitPrologue(MachineFunction & MF) const77 void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
78 MachineBasicBlock &MBB = MF.front();
79 MachineFrameInfo *MFI = MF.getFrameInfo();
80 MachineBasicBlock::iterator MBBI = MBB.begin();
81 const HexagonRegisterInfo *QRI =
82 MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
83 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
84 determineFrameLayout(MF);
85
86 // Get the number of bytes to allocate from the FrameInfo.
87 int NumBytes = (int) MFI->getStackSize();
88
89 // LLVM expects allocframe not to be the first instruction in the
90 // basic block.
91 MachineBasicBlock::iterator InsertPt = MBB.begin();
92
93 //
94 // ALLOCA adjust regs. Iterate over ADJDYNALLOC nodes and change the offset.
95 //
96 HexagonMachineFunctionInfo *FuncInfo =
97 MF.getInfo<HexagonMachineFunctionInfo>();
98 const std::vector<MachineInstr*>& AdjustRegs =
99 FuncInfo->getAllocaAdjustInsts();
100 for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(),
101 e = AdjustRegs.end();
102 i != e; ++i) {
103 MachineInstr* MI = *i;
104 assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) &&
105 "Expected adjust alloca node");
106
107 MachineOperand& MO = MI->getOperand(2);
108 assert(MO.isImm() && "Expected immediate");
109 MO.setImm(MFI->getMaxCallFrameSize());
110 }
111
112 //
113 // Only insert ALLOCFRAME if we need to.
114 //
115 if (hasFP(MF)) {
116 // Check for overflow.
117 // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
118 const int ALLOCFRAME_MAX = 16384;
119 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
120
121 if (NumBytes >= ALLOCFRAME_MAX) {
122 // Emit allocframe(#0).
123 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(0);
124
125 // Subtract offset from frame pointer.
126 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
127 HEXAGON_RESERVED_REG_1).addImm(NumBytes);
128 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::A2_sub),
129 QRI->getStackRegister()).
130 addReg(QRI->getStackRegister()).
131 addReg(HEXAGON_RESERVED_REG_1);
132 } else {
133 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(NumBytes);
134 }
135 }
136 }
137 // Returns true if MBB has a machine instructions that indicates a tail call
138 // in the block.
hasTailCall(MachineBasicBlock & MBB) const139 bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
140 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
141 unsigned RetOpcode = MBBI->getOpcode();
142
143 return RetOpcode == Hexagon::TCRETURNi || RetOpcode == Hexagon::TCRETURNr;
144 }
145
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const146 void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
147 MachineBasicBlock &MBB) const {
148 MachineBasicBlock::iterator MBBI = std::prev(MBB.end());
149 DebugLoc dl = MBBI->getDebugLoc();
150 //
151 // Only insert deallocframe if we need to. Also at -O0. See comment
152 // in emitPrologue above.
153 //
154 if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) {
155 MachineBasicBlock::iterator MBBI = std::prev(MBB.end());
156 MachineBasicBlock::iterator MBBI_end = MBB.end();
157
158 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
159 // Handle EH_RETURN.
160 if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
161 assert(MBBI->getOperand(0).isReg() && "Offset should be in register!");
162 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::L2_deallocframe));
163 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::A2_add),
164 Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28);
165 return;
166 }
167 // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
168 // versions.
169 if (MBBI->getOpcode() == Hexagon::JMPret && !DisableDeallocRet) {
170 // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC
171 // instruction if we encounter it.
172 MachineBasicBlock::iterator BeforeJMPR =
173 MBB.begin() == MBBI ? MBBI : std::prev(MBBI);
174 if (BeforeJMPR != MBBI &&
175 BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) {
176 // Remove the JMPR node.
177 MBB.erase(MBBI);
178 return;
179 }
180
181 // Add dealloc_return.
182 MachineInstrBuilder MIB =
183 BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::L4_return));
184 // Transfer the function live-out registers.
185 MIB->copyImplicitOps(*MBB.getParent(), &*MBBI);
186 // Remove the JUMPR node.
187 MBB.erase(MBBI);
188 } else { // Add deallocframe for V2 and V3, and V4 tail calls.
189 // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra
190 // DEALLOCFRAME instruction after it.
191 MachineBasicBlock::iterator Term = MBB.getFirstTerminator();
192 MachineBasicBlock::iterator I =
193 Term == MBB.begin() ? MBB.end() : std::prev(Term);
194 if (I != MBB.end() &&
195 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4)
196 return;
197
198 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::L2_deallocframe));
199 }
200 }
201 }
202
hasFP(const MachineFunction & MF) const203 bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
204 const MachineFrameInfo *MFI = MF.getFrameInfo();
205 const HexagonMachineFunctionInfo *FuncInfo =
206 MF.getInfo<HexagonMachineFunctionInfo>();
207 return (MFI->hasCalls() || (MFI->getStackSize() > 0) ||
208 FuncInfo->hasClobberLR() );
209 }
210
211 static inline
uniqueSuperReg(unsigned Reg,const TargetRegisterInfo * TRI)212 unsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI) {
213 MCSuperRegIterator SRI(Reg, TRI);
214 assert(SRI.isValid() && "Expected a superreg");
215 unsigned SuperReg = *SRI;
216 ++SRI;
217 assert(!SRI.isValid() && "Expected exactly one superreg");
218 return SuperReg;
219 }
220
221 bool
spillCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const std::vector<CalleeSavedInfo> & CSI,const TargetRegisterInfo * TRI) const222 HexagonFrameLowering::spillCalleeSavedRegisters(
223 MachineBasicBlock &MBB,
224 MachineBasicBlock::iterator MI,
225 const std::vector<CalleeSavedInfo> &CSI,
226 const TargetRegisterInfo *TRI) const {
227 MachineFunction *MF = MBB.getParent();
228 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
229
230 if (CSI.empty()) {
231 return false;
232 }
233
234 // We can only schedule double loads if we spill contiguous callee-saved regs
235 // For instance, we cannot scheduled double-word loads if we spill r24,
236 // r26, and r27.
237 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
238 // above.
239 bool ContiguousRegs = true;
240
241 for (unsigned i = 0; i < CSI.size(); ++i) {
242 unsigned Reg = CSI[i].getReg();
243
244 //
245 // Check if we can use a double-word store.
246 //
247 unsigned SuperReg = uniqueSuperReg(Reg, TRI);
248 bool CanUseDblStore = false;
249 const TargetRegisterClass* SuperRegClass = nullptr;
250
251 if (ContiguousRegs && (i < CSI.size()-1)) {
252 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
253 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
254 CanUseDblStore = (SuperRegNext == SuperReg);
255 }
256
257
258 if (CanUseDblStore) {
259 TII.storeRegToStackSlot(MBB, MI, SuperReg, true,
260 CSI[i+1].getFrameIdx(), SuperRegClass, TRI);
261 MBB.addLiveIn(SuperReg);
262 ++i;
263 } else {
264 // Cannot use a double-word store.
265 ContiguousRegs = false;
266 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
267 TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC,
268 TRI);
269 MBB.addLiveIn(Reg);
270 }
271 }
272 return true;
273 }
274
275
restoreCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const std::vector<CalleeSavedInfo> & CSI,const TargetRegisterInfo * TRI) const276 bool HexagonFrameLowering::restoreCalleeSavedRegisters(
277 MachineBasicBlock &MBB,
278 MachineBasicBlock::iterator MI,
279 const std::vector<CalleeSavedInfo> &CSI,
280 const TargetRegisterInfo *TRI) const {
281
282 MachineFunction *MF = MBB.getParent();
283 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
284
285 if (CSI.empty()) {
286 return false;
287 }
288
289 // We can only schedule double loads if we spill contiguous callee-saved regs
290 // For instance, we cannot scheduled double-word loads if we spill r24,
291 // r26, and r27.
292 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
293 // above.
294 bool ContiguousRegs = true;
295
296 for (unsigned i = 0; i < CSI.size(); ++i) {
297 unsigned Reg = CSI[i].getReg();
298
299 //
300 // Check if we can use a double-word load.
301 //
302 unsigned SuperReg = uniqueSuperReg(Reg, TRI);
303 const TargetRegisterClass* SuperRegClass = nullptr;
304 bool CanUseDblLoad = false;
305 if (ContiguousRegs && (i < CSI.size()-1)) {
306 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
307 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
308 CanUseDblLoad = (SuperRegNext == SuperReg);
309 }
310
311
312 if (CanUseDblLoad) {
313 TII.loadRegFromStackSlot(MBB, MI, SuperReg, CSI[i+1].getFrameIdx(),
314 SuperRegClass, TRI);
315 MBB.addLiveIn(SuperReg);
316 ++i;
317 } else {
318 // Cannot use a double-word load.
319 ContiguousRegs = false;
320 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
321 TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI);
322 MBB.addLiveIn(Reg);
323 }
324 }
325 return true;
326 }
327
328 void HexagonFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const329 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
330 MachineBasicBlock::iterator I) const {
331 MachineInstr &MI = *I;
332
333 if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) {
334 // Hexagon_TODO: add code
335 } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) {
336 // Hexagon_TODO: add code
337 } else {
338 llvm_unreachable("Cannot handle this call frame pseudo instruction");
339 }
340 MBB.erase(I);
341 }
342
getFrameIndexOffset(const MachineFunction & MF,int FI) const343 int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
344 int FI) const {
345 return MF.getFrameInfo()->getObjectOffset(FI);
346 }
347