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
37using namespace llvm;
38
39static 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.
46void 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 = MF.getTarget().getFrameLowering()->getStackAlignment();
54  // Get the maximum call frame size of all the calls.
55  unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
56
57  // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
58  // that allocations will be aligned.
59  if (MFI->hasVarSizedObjects())
60    maxCallFrameSize = RoundUpToAlignment(maxCallFrameSize, TargetAlign);
61
62  // Update maximum call frame size.
63  MFI->setMaxCallFrameSize(maxCallFrameSize);
64
65  // Include call frame size in total.
66  FrameSize += maxCallFrameSize;
67
68  // Make sure the frame is aligned.
69  FrameSize = RoundUpToAlignment(FrameSize, TargetAlign);
70
71  // Update frame info.
72  MFI->setStackSize(FrameSize);
73}
74
75
76void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
77  MachineBasicBlock &MBB = MF.front();
78  MachineFrameInfo *MFI = MF.getFrameInfo();
79  MachineBasicBlock::iterator MBBI = MBB.begin();
80  const HexagonRegisterInfo *QRI =
81    static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
82  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
83  determineFrameLayout(MF);
84
85  // Get the number of bytes to allocate from the FrameInfo.
86  int NumBytes = (int) MFI->getStackSize();
87
88  // LLVM expects allocframe not to be the first instruction in the
89  // basic block.
90  MachineBasicBlock::iterator InsertPt = MBB.begin();
91
92  //
93  // ALLOCA adjust regs.  Iterate over ADJDYNALLOC nodes and change the offset.
94  //
95  HexagonMachineFunctionInfo *FuncInfo =
96    MF.getInfo<HexagonMachineFunctionInfo>();
97  const std::vector<MachineInstr*>& AdjustRegs =
98    FuncInfo->getAllocaAdjustInsts();
99  for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(),
100         e = AdjustRegs.end();
101       i != e; ++i) {
102    MachineInstr* MI = *i;
103    assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) &&
104           "Expected adjust alloca node");
105
106    MachineOperand& MO = MI->getOperand(2);
107    assert(MO.isImm() && "Expected immediate");
108    MO.setImm(MFI->getMaxCallFrameSize());
109  }
110
111  //
112  // Only insert ALLOCFRAME if we need to.
113  //
114  if (hasFP(MF)) {
115    // Check for overflow.
116    // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
117    const int ALLOCFRAME_MAX = 16384;
118    const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
119
120    if (NumBytes >= ALLOCFRAME_MAX) {
121      // Emit allocframe(#0).
122      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0);
123
124      // Subtract offset from frame pointer.
125      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
126                                      HEXAGON_RESERVED_REG_1).addImm(NumBytes);
127      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr),
128                                      QRI->getStackRegister()).
129                                      addReg(QRI->getStackRegister()).
130                                      addReg(HEXAGON_RESERVED_REG_1);
131    } else {
132      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes);
133    }
134  }
135}
136// Returns true if MBB has a machine instructions that indicates a tail call
137// in the block.
138bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
139  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
140  unsigned RetOpcode = MBBI->getOpcode();
141
142  return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;
143}
144
145void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
146                                     MachineBasicBlock &MBB) const {
147  MachineBasicBlock::iterator MBBI = std::prev(MBB.end());
148  DebugLoc dl = MBBI->getDebugLoc();
149  //
150  // Only insert deallocframe if we need to.  Also at -O0.  See comment
151  // in emitPrologue above.
152  //
153  if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) {
154    MachineBasicBlock::iterator MBBI = std::prev(MBB.end());
155    MachineBasicBlock::iterator MBBI_end = MBB.end();
156
157    const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
158    // Handle EH_RETURN.
159    if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
160      assert(MBBI->getOperand(0).isReg() && "Offset should be in register!");
161      BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
162      BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr),
163              Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28);
164      return;
165    }
166    // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
167    // versions.
168    if (MF.getTarget().getSubtarget<HexagonSubtarget>().hasV4TOps() &&
169        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::DEALLOC_RET_V4));
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::DEALLOCFRAME));
199    }
200  }
201}
202
203bool 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
211static inline
212unsigned 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
221bool
222HexagonFrameLowering::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->getTarget().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
276bool 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->getTarget().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
328void HexagonFrameLowering::
329eliminateCallFramePseudoInstr(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
343int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
344                                              int FI) const {
345  return MF.getFrameInfo()->getObjectOffset(FI);
346}
347