1 //===-- HexagonFrameLowering.cpp - Define frame lowering ------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #include "HexagonFrameLowering.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"
39 static cl::opt<bool> DisableDeallocRet(
40 "disable-hexagon-dealloc-ret",
42 cl::desc("Disable Dealloc Return for Hexagon target"));
44 /// determineFrameLayout - Determine the size of the frame and maximum call
46 void HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const {
47 MachineFrameInfo *MFI = MF.getFrameInfo();
49 // Get the number of bytes to allocate from the FrameInfo.
50 unsigned FrameSize = MFI->getStackSize();
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();
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);
62 // Update maximum call frame size.
63 MFI->setMaxCallFrameSize(maxCallFrameSize);
65 // Include call frame size in total.
66 FrameSize += maxCallFrameSize;
68 // Make sure the frame is aligned.
69 FrameSize = RoundUpToAlignment(FrameSize, TargetAlign);
72 MFI->setStackSize(FrameSize);
76 void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
77 MachineBasicBlock &MBB = MF.front();
78 MachineFrameInfo *MFI = MF.getFrameInfo();
79 MachineModuleInfo &MMI = MF.getMMI();
80 MachineBasicBlock::iterator MBBI = MBB.begin();
81 const HexagonRegisterInfo *QRI =
82 static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
83 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
84 determineFrameLayout(MF);
86 // Check if frame moves are needed for EH.
87 bool needsFrameMoves = MMI.hasDebugInfo() ||
88 !MF.getFunction()->needsUnwindTableEntry();
90 // Get the number of bytes to allocate from the FrameInfo.
91 int NumBytes = (int) MFI->getStackSize();
93 // LLVM expects allocframe not to be the first instruction in the
95 MachineBasicBlock::iterator InsertPt = MBB.begin();
98 // ALLOCA adjust regs. Iterate over ADJDYNALLOC nodes and change the offset.
100 HexagonMachineFunctionInfo *FuncInfo =
101 MF.getInfo<HexagonMachineFunctionInfo>();
102 const std::vector<MachineInstr*>& AdjustRegs =
103 FuncInfo->getAllocaAdjustInsts();
104 for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(),
105 e = AdjustRegs.end();
107 MachineInstr* MI = *i;
108 assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) &&
109 "Expected adjust alloca node");
111 MachineOperand& MO = MI->getOperand(2);
112 assert(MO.isImm() && "Expected immediate");
113 MO.setImm(MFI->getMaxCallFrameSize());
116 if (needsFrameMoves) {
117 // Advance CFA. DW_CFA_def_cfa
118 unsigned FPReg = QRI->getFrameRegister();
119 unsigned RAReg = QRI->getRARegister();
121 MachineLocation Dst(MachineLocation::VirtualFP);
122 MachineLocation Src(FPReg, -8);
123 MMI.addFrameMove(0, Dst, Src);
126 MachineLocation LRDst(RAReg, -4);
127 MachineLocation LRSrc(RAReg);
128 MMI.addFrameMove(0, LRDst, LRSrc);
131 MachineLocation SPDst(FPReg, -8);
132 MachineLocation SPSrc(FPReg);
133 MMI.addFrameMove(0, SPDst, SPSrc);
137 // Only insert ALLOCFRAME if we need to.
140 // Check for overflow.
141 // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
142 const int ALLOCFRAME_MAX = 16384;
143 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
145 if (NumBytes >= ALLOCFRAME_MAX) {
146 // Emit allocframe(#0).
147 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0);
149 // Subtract offset from frame pointer.
150 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
151 HEXAGON_RESERVED_REG_1).addImm(NumBytes);
152 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr),
153 QRI->getStackRegister()).
154 addReg(QRI->getStackRegister()).
155 addReg(HEXAGON_RESERVED_REG_1);
157 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes);
161 // Returns true if MBB has a machine instructions that indicates a tail call
163 bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
164 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
165 unsigned RetOpcode = MBBI->getOpcode();
167 return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;
170 void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
171 MachineBasicBlock &MBB) const {
172 MachineBasicBlock::iterator MBBI = prior(MBB.end());
173 DebugLoc dl = MBBI->getDebugLoc();
175 // Only insert deallocframe if we need to. Also at -O0. See comment
176 // in emitPrologue above.
178 if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) {
179 MachineBasicBlock::iterator MBBI = prior(MBB.end());
180 MachineBasicBlock::iterator MBBI_end = MBB.end();
182 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
184 if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
185 assert(MBBI->getOperand(0).isReg() && "Offset should be in register!");
186 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
187 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr),
188 Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28);
191 // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
193 if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPret
194 && !DisableDeallocRet) {
195 // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC
196 // instruction if we encounter it.
197 MachineBasicBlock::iterator BeforeJMPR =
198 MBB.begin() == MBBI ? MBBI : prior(MBBI);
199 if (BeforeJMPR != MBBI &&
200 BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) {
201 // Remove the JMPR node.
206 // Add dealloc_return.
207 MachineInstrBuilder MIB =
208 BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4));
209 // Transfer the function live-out registers.
210 MIB->copyImplicitOps(*MBB.getParent(), &*MBBI);
211 // Remove the JUMPR node.
213 } else { // Add deallocframe for V2 and V3, and V4 tail calls.
214 // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra
215 // DEALLOCFRAME instruction after it.
216 MachineBasicBlock::iterator Term = MBB.getFirstTerminator();
217 MachineBasicBlock::iterator I =
218 Term == MBB.begin() ? MBB.end() : prior(Term);
219 if (I != MBB.end() &&
220 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4)
223 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
228 bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
229 const MachineFrameInfo *MFI = MF.getFrameInfo();
230 const HexagonMachineFunctionInfo *FuncInfo =
231 MF.getInfo<HexagonMachineFunctionInfo>();
232 return (MFI->hasCalls() || (MFI->getStackSize() > 0) ||
233 FuncInfo->hasClobberLR() );
237 unsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI) {
238 MCSuperRegIterator SRI(Reg, TRI);
239 assert(SRI.isValid() && "Expected a superreg");
240 unsigned SuperReg = *SRI;
242 assert(!SRI.isValid() && "Expected exactly one superreg");
247 HexagonFrameLowering::spillCalleeSavedRegisters(
248 MachineBasicBlock &MBB,
249 MachineBasicBlock::iterator MI,
250 const std::vector<CalleeSavedInfo> &CSI,
251 const TargetRegisterInfo *TRI) const {
252 MachineFunction *MF = MBB.getParent();
253 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
259 // We can only schedule double loads if we spill contiguous callee-saved regs
260 // For instance, we cannot scheduled double-word loads if we spill r24,
262 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
264 bool ContiguousRegs = true;
266 for (unsigned i = 0; i < CSI.size(); ++i) {
267 unsigned Reg = CSI[i].getReg();
270 // Check if we can use a double-word store.
272 unsigned SuperReg = uniqueSuperReg(Reg, TRI);
273 bool CanUseDblStore = false;
274 const TargetRegisterClass* SuperRegClass = 0;
276 if (ContiguousRegs && (i < CSI.size()-1)) {
277 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
278 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
279 CanUseDblStore = (SuperRegNext == SuperReg);
283 if (CanUseDblStore) {
284 TII.storeRegToStackSlot(MBB, MI, SuperReg, true,
285 CSI[i+1].getFrameIdx(), SuperRegClass, TRI);
286 MBB.addLiveIn(SuperReg);
289 // Cannot use a double-word store.
290 ContiguousRegs = false;
291 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
292 TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC,
301 bool HexagonFrameLowering::restoreCalleeSavedRegisters(
302 MachineBasicBlock &MBB,
303 MachineBasicBlock::iterator MI,
304 const std::vector<CalleeSavedInfo> &CSI,
305 const TargetRegisterInfo *TRI) const {
307 MachineFunction *MF = MBB.getParent();
308 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
314 // We can only schedule double loads if we spill contiguous callee-saved regs
315 // For instance, we cannot scheduled double-word loads if we spill r24,
317 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
319 bool ContiguousRegs = true;
321 for (unsigned i = 0; i < CSI.size(); ++i) {
322 unsigned Reg = CSI[i].getReg();
325 // Check if we can use a double-word load.
327 unsigned SuperReg = uniqueSuperReg(Reg, TRI);
328 const TargetRegisterClass* SuperRegClass = 0;
329 bool CanUseDblLoad = false;
330 if (ContiguousRegs && (i < CSI.size()-1)) {
331 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
332 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
333 CanUseDblLoad = (SuperRegNext == SuperReg);
338 TII.loadRegFromStackSlot(MBB, MI, SuperReg, CSI[i+1].getFrameIdx(),
340 MBB.addLiveIn(SuperReg);
343 // Cannot use a double-word load.
344 ContiguousRegs = false;
345 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
346 TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI);
353 void HexagonFrameLowering::
354 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
355 MachineBasicBlock::iterator I) const {
356 MachineInstr &MI = *I;
358 if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) {
359 // Hexagon_TODO: add code
360 } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) {
361 // Hexagon_TODO: add code
363 llvm_unreachable("Cannot handle this call frame pseudo instruction");
368 int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
370 return MF.getFrameInfo()->getObjectOffset(FI);