Hexagon backend support
[oota-llvm.git] / lib / Target / Hexagon / HexagonFrameLowering.cpp
1 //==-- HexagonFrameLowering.cpp - Define frame lowering         --*- C++ -*-==//
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 "Hexagon.h"
11 #include "HexagonInstrInfo.h"
12 #include "HexagonRegisterInfo.h"
13 #include "HexagonSubtarget.h"
14 #include "HexagonTargetMachine.h"
15 #include "HexagonMachineFunctionInfo.h"
16 #include "HexagonFrameLowering.h"
17
18 #include "llvm/CodeGen/AsmPrinter.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineModuleInfo.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/MC/MachineLocation.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/CodeGen/RegisterScavenging.h"
27 #include "llvm/Target/TargetInstrInfo.h"
28 #include "llvm/Type.h"
29 #include "llvm/ADT/BitVector.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/Support/CommandLine.h"
32 #include "llvm/Target/TargetMachine.h"
33 #include "llvm/Target/TargetOptions.h"
34 #include <iostream>
35
36 #include "llvm/CodeGen/MachineFunctionPass.h"
37 #include "llvm/Function.h"
38 using namespace llvm;
39
40 static cl::opt<bool> DisableDeallocRet(
41                        "disable-hexagon-dealloc-ret",
42                        cl::Hidden,
43                        cl::desc("Disable Dealloc Return for Hexagon target"));
44
45 /// determineFrameLayout - Determine the size of the frame and maximum call
46 /// frame size.
47 void HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const {
48   MachineFrameInfo *MFI = MF.getFrameInfo();
49
50   // Get the number of bytes to allocate from the FrameInfo.
51   unsigned FrameSize = MFI->getStackSize();
52
53   // Get the alignments provided by the target.
54   unsigned TargetAlign = MF.getTarget().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
77 void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
78   MachineBasicBlock &MBB = MF.front();
79   MachineFrameInfo *MFI = MF.getFrameInfo();
80   MachineModuleInfo &MMI = MF.getMMI();
81   MachineBasicBlock::iterator MBBI = MBB.begin();
82   const HexagonRegisterInfo *QRI =
83     static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
84   DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
85   determineFrameLayout(MF);
86
87   // Check if frame moves are needed for EH.
88   bool needsFrameMoves = MMI.hasDebugInfo() ||
89     !MF.getFunction()->needsUnwindTableEntry();
90
91   // Get the number of bytes to allocate from the FrameInfo.
92   int NumBytes = (int) MFI->getStackSize();
93
94   // LLVM expects allocframe not to be the first instruction in the
95   // basic block.
96   MachineBasicBlock::iterator InsertPt = MBB.begin();
97
98   //
99   // ALLOCA adjust regs.  Iterate over ADJDYNALLOC nodes and change the offset.
100   //
101   HexagonMachineFunctionInfo *FuncInfo =
102     MF.getInfo<HexagonMachineFunctionInfo>();
103   const std::vector<MachineInstr*>& AdjustRegs =
104     FuncInfo->getAllocaAdjustInsts();
105   for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(),
106          e = AdjustRegs.end();
107        i != e; ++i) {
108     MachineInstr* MI = *i;
109     assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) &&
110            "Expected adjust alloca node");
111
112     MachineOperand& MO = MI->getOperand(2);
113     assert(MO.isImm() && "Expected immediate");
114     MO.setImm(MFI->getMaxCallFrameSize());
115   }
116
117  std::vector<MachineMove> &Moves = MMI.getFrameMoves();
118
119  if (needsFrameMoves) {
120    // Advance CFA. DW_CFA_def_cfa
121    unsigned FPReg = QRI->getFrameRegister();
122    unsigned RAReg = QRI->getRARegister();
123
124    MachineLocation Dst(MachineLocation::VirtualFP);
125    MachineLocation Src(FPReg, -8);
126    Moves.push_back(MachineMove(0, Dst, Src));
127
128    // R31 = (R31 - #4)
129    MachineLocation LRDst(RAReg, -4);
130    MachineLocation LRSrc(RAReg);
131    Moves.push_back(MachineMove(0, LRDst, LRSrc));
132
133    // R30 = (R30 - #8)
134    MachineLocation SPDst(FPReg, -8);
135    MachineLocation SPSrc(FPReg);
136    Moves.push_back(MachineMove(0, SPDst, SPSrc));
137  }
138
139   //
140   // Only insert ALLOCFRAME if we need to.
141   //
142   if (hasFP(MF)) {
143     // Check for overflow.
144     // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
145     const unsigned int ALLOCFRAME_MAX = 16384;
146     const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
147
148     if (NumBytes >= ALLOCFRAME_MAX) {
149       // Emit allocframe(#0).
150       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0);
151
152       // Subtract offset from frame pointer.
153       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
154                                       HEXAGON_RESERVED_REG_1).addImm(NumBytes);
155       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr),
156                                       QRI->getStackRegister()).
157                                       addReg(QRI->getStackRegister()).
158                                       addReg(HEXAGON_RESERVED_REG_1);
159     } else {
160       BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes);
161     }
162   }
163 }
164 // Returns true if MBB has a machine instructions that indicates a tail call
165 // in the block.
166 bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
167   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
168   unsigned RetOpcode = MBBI->getOpcode();
169
170   return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;}
171
172 void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
173                                      MachineBasicBlock &MBB) const {
174   MachineBasicBlock::iterator MBBI = prior(MBB.end());
175   DebugLoc dl = MBBI->getDebugLoc();
176   //
177   // Only insert deallocframe if we need to.
178   //
179   if (hasFP(MF)) {
180     MachineBasicBlock::iterator MBBI = prior(MBB.end());
181     MachineBasicBlock::iterator MBBI_end = MBB.end();
182     //
183     // For Hexagon, we don't need the frame size.
184     //
185     MachineFrameInfo *MFI = MF.getFrameInfo();
186     int NumBytes = (int) MFI->getStackSize();
187
188     const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
189
190     // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
191     // versions.
192     if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPR
193                         && !DisableDeallocRet) {
194       // Remove jumpr node.
195       MBB.erase(MBBI);
196       // Add dealloc_return.
197       BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4))
198         .addImm(NumBytes);
199     } else { // Add deallocframe for V2 and V3.
200       BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)).addImm(NumBytes);
201     }
202   }
203 }
204
205 bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
206   const MachineFrameInfo *MFI = MF.getFrameInfo();
207   const HexagonMachineFunctionInfo *FuncInfo =
208     MF.getInfo<HexagonMachineFunctionInfo>();
209   return (MFI->hasCalls() || (MFI->getStackSize() > 0) ||
210           FuncInfo->hasClobberLR() );
211 }
212
213 bool
214 HexagonFrameLowering::spillCalleeSavedRegisters(
215                                         MachineBasicBlock &MBB,
216                                         MachineBasicBlock::iterator MI,
217                                         const std::vector<CalleeSavedInfo> &CSI,
218                                         const TargetRegisterInfo *TRI) const {
219   MachineFunction *MF = MBB.getParent();
220   const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
221
222   if (CSI.empty()) {
223     return false;
224   }
225
226   // We can only schedule double loads if we spill contiguous callee-saved regs
227   // For instance, we cannot scheduled double-word loads if we spill r24,
228   // r26, and r27.
229   // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
230   // above.
231   bool ContiguousRegs = true;
232
233   for (unsigned i = 0; i < CSI.size(); ++i) {
234     unsigned Reg = CSI[i].getReg();
235
236     //
237     // Check if we can use a double-word store.
238     //
239     const unsigned* SuperReg = TRI->getSuperRegisters(Reg);
240
241     // Assume that there is exactly one superreg.
242     assert(SuperReg[0] && !SuperReg[1] && "Expected exactly one superreg");
243     bool CanUseDblStore = false;
244     const TargetRegisterClass* SuperRegClass = 0;
245
246     if (ContiguousRegs && (i < CSI.size()-1)) {
247       const unsigned* SuperRegNext = TRI->getSuperRegisters(CSI[i+1].getReg());
248       assert(SuperRegNext[0] && !SuperRegNext[1] &&
249              "Expected exactly one superreg");
250       SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg[0]);
251       CanUseDblStore = (SuperRegNext[0] == SuperReg[0]);
252     }
253
254
255     if (CanUseDblStore) {
256       TII.storeRegToStackSlot(MBB, MI, SuperReg[0], true,
257                               CSI[i+1].getFrameIdx(), SuperRegClass, TRI);
258       MBB.addLiveIn(SuperReg[0]);
259       ++i;
260     } else {
261       // Cannot use a double-word store.
262       ContiguousRegs = false;
263       const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
264       TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC,
265                               TRI);
266       MBB.addLiveIn(Reg);
267     }
268   }
269   return true;
270 }
271
272
273 bool HexagonFrameLowering::restoreCalleeSavedRegisters(
274                                         MachineBasicBlock &MBB,
275                                         MachineBasicBlock::iterator MI,
276                                         const std::vector<CalleeSavedInfo> &CSI,
277                                         const TargetRegisterInfo *TRI) const {
278
279   MachineFunction *MF = MBB.getParent();
280   const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
281
282   if (CSI.empty()) {
283     return false;
284   }
285
286   // We can only schedule double loads if we spill contiguous callee-saved regs
287   // For instance, we cannot scheduled double-word loads if we spill r24,
288   // r26, and r27.
289   // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
290   // above.
291   bool ContiguousRegs = true;
292
293   for (unsigned i = 0; i < CSI.size(); ++i) {
294     unsigned Reg = CSI[i].getReg();
295
296     //
297     // Check if we can use a double-word load.
298     //
299     const unsigned* SuperReg = TRI->getSuperRegisters(Reg);
300     const TargetRegisterClass* SuperRegClass = 0;
301
302     // Assume that there is exactly one superreg.
303     assert(SuperReg[0] && !SuperReg[1] && "Expected exactly one superreg");
304     bool CanUseDblLoad = false;
305     if (ContiguousRegs && (i < CSI.size()-1)) {
306       const unsigned* SuperRegNext = TRI->getSuperRegisters(CSI[i+1].getReg());
307       assert(SuperRegNext[0] && !SuperRegNext[1] &&
308              "Expected exactly one superreg");
309       SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg[0]);
310       CanUseDblLoad = (SuperRegNext[0] == SuperReg[0]);
311     }
312
313
314     if (CanUseDblLoad) {
315       TII.loadRegFromStackSlot(MBB, MI, SuperReg[0], CSI[i+1].getFrameIdx(),
316                                SuperRegClass, TRI);
317       MBB.addLiveIn(SuperReg[0]);
318       ++i;
319     } else {
320       // Cannot use a double-word load.
321       ContiguousRegs = false;
322       const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
323       TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI);
324       MBB.addLiveIn(Reg);
325     }
326   }
327   return true;
328 }
329
330 int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
331                                               int FI) const {
332   return MF.getFrameInfo()->getObjectOffset(FI);
333 }