blob: 2999c2d5f30de5d715a251873c0d374ee696c44f [file] [log] [blame]
Jia Liub22310f2012-02-18 12:03:15 +00001//===-- HexagonFrameLowering.cpp - Define frame lowering ------------------===//
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002//
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//===----------------------------------------------------------------------===//
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000010
Craig Topperb25fda92012-03-17 18:46:09 +000011#include "HexagonFrameLowering.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000012#include "Hexagon.h"
13#include "HexagonInstrInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000014#include "HexagonMachineFunctionInfo.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000015#include "HexagonRegisterInfo.h"
16#include "HexagonSubtarget.h"
17#include "HexagonTargetMachine.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000018#include "llvm/ADT/BitVector.h"
19#include "llvm/ADT/STLExtras.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000020#include "llvm/CodeGen/AsmPrinter.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000021#include "llvm/CodeGen/MachineFrameInfo.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000022#include "llvm/CodeGen/MachineFunction.h"
23#include "llvm/CodeGen/MachineFunctionPass.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000024#include "llvm/CodeGen/MachineInstrBuilder.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000025#include "llvm/CodeGen/MachineModuleInfo.h"
26#include "llvm/CodeGen/MachineRegisterInfo.h"
27#include "llvm/CodeGen/RegisterScavenging.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000028#include "llvm/IR/Function.h"
29#include "llvm/IR/Type.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000030#include "llvm/MC/MCAsmInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000031#include "llvm/MC/MachineLocation.h"
32#include "llvm/Support/CommandLine.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000033#include "llvm/Target/TargetInstrInfo.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000034#include "llvm/Target/TargetMachine.h"
35#include "llvm/Target/TargetOptions.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000036
Tony Linthicum1213a7a2011-12-12 21:14:40 +000037using 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.
Eric Christopherd9134482014-08-04 21:25:23 +000053 unsigned TargetAlign = MF.getTarget()
54 .getSubtargetImpl()
55 ->getFrameLowering()
56 ->getStackAlignment();
Tony Linthicum1213a7a2011-12-12 21:14:40 +000057 // Get the maximum call frame size of all the calls.
58 unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
59
60 // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
61 // that allocations will be aligned.
62 if (MFI->hasVarSizedObjects())
63 maxCallFrameSize = RoundUpToAlignment(maxCallFrameSize, TargetAlign);
64
65 // Update maximum call frame size.
66 MFI->setMaxCallFrameSize(maxCallFrameSize);
67
68 // Include call frame size in total.
69 FrameSize += maxCallFrameSize;
70
71 // Make sure the frame is aligned.
72 FrameSize = RoundUpToAlignment(FrameSize, TargetAlign);
73
74 // Update frame info.
75 MFI->setStackSize(FrameSize);
76}
77
78
79void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
80 MachineBasicBlock &MBB = MF.front();
81 MachineFrameInfo *MFI = MF.getFrameInfo();
Tony Linthicum1213a7a2011-12-12 21:14:40 +000082 MachineBasicBlock::iterator MBBI = MBB.begin();
Eric Christopherd9134482014-08-04 21:25:23 +000083 const HexagonRegisterInfo *QRI = static_cast<const HexagonRegisterInfo *>(
84 MF.getTarget().getSubtargetImpl()->getRegisterInfo());
Tony Linthicum1213a7a2011-12-12 21:14:40 +000085 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
86 determineFrameLayout(MF);
87
Tony Linthicum1213a7a2011-12-12 21:14:40 +000088 // Get the number of bytes to allocate from the FrameInfo.
89 int NumBytes = (int) MFI->getStackSize();
90
91 // LLVM expects allocframe not to be the first instruction in the
92 // basic block.
93 MachineBasicBlock::iterator InsertPt = MBB.begin();
94
95 //
96 // ALLOCA adjust regs. Iterate over ADJDYNALLOC nodes and change the offset.
97 //
98 HexagonMachineFunctionInfo *FuncInfo =
99 MF.getInfo<HexagonMachineFunctionInfo>();
100 const std::vector<MachineInstr*>& AdjustRegs =
101 FuncInfo->getAllocaAdjustInsts();
102 for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(),
103 e = AdjustRegs.end();
104 i != e; ++i) {
105 MachineInstr* MI = *i;
106 assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) &&
107 "Expected adjust alloca node");
108
109 MachineOperand& MO = MI->getOperand(2);
110 assert(MO.isImm() && "Expected immediate");
111 MO.setImm(MFI->getMaxCallFrameSize());
112 }
113
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000114 //
115 // Only insert ALLOCFRAME if we need to.
116 //
117 if (hasFP(MF)) {
118 // Check for overflow.
119 // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
Tony Linthicum36e05192011-12-12 21:52:59 +0000120 const int ALLOCFRAME_MAX = 16384;
Eric Christopherd9134482014-08-04 21:25:23 +0000121 const TargetInstrInfo &TII =
122 *MF.getTarget().getSubtargetImpl()->getInstrInfo();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000123
124 if (NumBytes >= ALLOCFRAME_MAX) {
125 // Emit allocframe(#0).
126 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0);
127
128 // Subtract offset from frame pointer.
129 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
130 HEXAGON_RESERVED_REG_1).addImm(NumBytes);
131 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr),
132 QRI->getStackRegister()).
133 addReg(QRI->getStackRegister()).
134 addReg(HEXAGON_RESERVED_REG_1);
135 } else {
136 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes);
137 }
138 }
139}
140// Returns true if MBB has a machine instructions that indicates a tail call
141// in the block.
142bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
143 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
144 unsigned RetOpcode = MBBI->getOpcode();
145
Matthew Curtiscd8c8812012-12-05 19:00:34 +0000146 return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;
147}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000148
149void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
150 MachineBasicBlock &MBB) const {
Benjamin Kramerb6d0bd42014-03-02 12:27:27 +0000151 MachineBasicBlock::iterator MBBI = std::prev(MBB.end());
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000152 DebugLoc dl = MBBI->getDebugLoc();
153 //
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000154 // Only insert deallocframe if we need to. Also at -O0. See comment
155 // in emitPrologue above.
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000156 //
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000157 if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) {
Benjamin Kramerb6d0bd42014-03-02 12:27:27 +0000158 MachineBasicBlock::iterator MBBI = std::prev(MBB.end());
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000159 MachineBasicBlock::iterator MBBI_end = MBB.end();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000160
Eric Christopherd9134482014-08-04 21:25:23 +0000161 const TargetInstrInfo &TII =
162 *MF.getTarget().getSubtargetImpl()->getInstrInfo();
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000163 // Handle EH_RETURN.
164 if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
Jyotsna Vermabf0bd1f2013-05-10 21:44:02 +0000165 assert(MBBI->getOperand(0).isReg() && "Offset should be in register!");
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000166 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
167 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr),
168 Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28);
169 return;
170 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000171 // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
172 // versions.
Eric Christophera68f3762014-06-27 00:13:47 +0000173 if (MF.getTarget().getSubtarget<HexagonSubtarget>().hasV4TOps() &&
174 MBBI->getOpcode() == Hexagon::JMPret && !DisableDeallocRet) {
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000175 // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC
176 // instruction if we encounter it.
177 MachineBasicBlock::iterator BeforeJMPR =
Benjamin Kramerb6d0bd42014-03-02 12:27:27 +0000178 MBB.begin() == MBBI ? MBBI : std::prev(MBBI);
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000179 if (BeforeJMPR != MBBI &&
180 BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) {
181 // Remove the JMPR node.
182 MBB.erase(MBBI);
183 return;
184 }
185
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000186 // Add dealloc_return.
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000187 MachineInstrBuilder MIB =
188 BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4));
189 // Transfer the function live-out registers.
190 MIB->copyImplicitOps(*MBB.getParent(), &*MBBI);
191 // Remove the JUMPR node.
192 MBB.erase(MBBI);
193 } else { // Add deallocframe for V2 and V3, and V4 tail calls.
194 // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra
195 // DEALLOCFRAME instruction after it.
196 MachineBasicBlock::iterator Term = MBB.getFirstTerminator();
197 MachineBasicBlock::iterator I =
Benjamin Kramerb6d0bd42014-03-02 12:27:27 +0000198 Term == MBB.begin() ? MBB.end() : std::prev(Term);
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000199 if (I != MBB.end() &&
200 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4)
201 return;
202
203 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000204 }
205 }
206}
207
208bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
209 const MachineFrameInfo *MFI = MF.getFrameInfo();
210 const HexagonMachineFunctionInfo *FuncInfo =
211 MF.getInfo<HexagonMachineFunctionInfo>();
212 return (MFI->hasCalls() || (MFI->getStackSize() > 0) ||
213 FuncInfo->hasClobberLR() );
214}
215
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000216static inline
217unsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI) {
218 MCSuperRegIterator SRI(Reg, TRI);
219 assert(SRI.isValid() && "Expected a superreg");
220 unsigned SuperReg = *SRI;
221 ++SRI;
222 assert(!SRI.isValid() && "Expected exactly one superreg");
223 return SuperReg;
224}
225
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000226bool
227HexagonFrameLowering::spillCalleeSavedRegisters(
228 MachineBasicBlock &MBB,
229 MachineBasicBlock::iterator MI,
230 const std::vector<CalleeSavedInfo> &CSI,
231 const TargetRegisterInfo *TRI) const {
232 MachineFunction *MF = MBB.getParent();
Eric Christopherd9134482014-08-04 21:25:23 +0000233 const TargetInstrInfo &TII =
234 *MF->getTarget().getSubtargetImpl()->getInstrInfo();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000235
236 if (CSI.empty()) {
237 return false;
238 }
239
240 // We can only schedule double loads if we spill contiguous callee-saved regs
241 // For instance, we cannot scheduled double-word loads if we spill r24,
242 // r26, and r27.
243 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
244 // above.
245 bool ContiguousRegs = true;
246
247 for (unsigned i = 0; i < CSI.size(); ++i) {
248 unsigned Reg = CSI[i].getReg();
249
250 //
251 // Check if we can use a double-word store.
252 //
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000253 unsigned SuperReg = uniqueSuperReg(Reg, TRI);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000254 bool CanUseDblStore = false;
Craig Topper062a2ba2014-04-25 05:30:21 +0000255 const TargetRegisterClass* SuperRegClass = nullptr;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000256
257 if (ContiguousRegs && (i < CSI.size()-1)) {
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000258 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
259 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
260 CanUseDblStore = (SuperRegNext == SuperReg);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000261 }
262
263
264 if (CanUseDblStore) {
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000265 TII.storeRegToStackSlot(MBB, MI, SuperReg, true,
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000266 CSI[i+1].getFrameIdx(), SuperRegClass, TRI);
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000267 MBB.addLiveIn(SuperReg);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000268 ++i;
269 } else {
270 // Cannot use a double-word store.
271 ContiguousRegs = false;
272 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
273 TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC,
274 TRI);
275 MBB.addLiveIn(Reg);
276 }
277 }
278 return true;
279}
280
281
282bool HexagonFrameLowering::restoreCalleeSavedRegisters(
283 MachineBasicBlock &MBB,
284 MachineBasicBlock::iterator MI,
285 const std::vector<CalleeSavedInfo> &CSI,
286 const TargetRegisterInfo *TRI) const {
287
288 MachineFunction *MF = MBB.getParent();
Eric Christopherd9134482014-08-04 21:25:23 +0000289 const TargetInstrInfo &TII =
290 *MF->getTarget().getSubtargetImpl()->getInstrInfo();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000291
292 if (CSI.empty()) {
293 return false;
294 }
295
296 // We can only schedule double loads if we spill contiguous callee-saved regs
297 // For instance, we cannot scheduled double-word loads if we spill r24,
298 // r26, and r27.
299 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
300 // above.
301 bool ContiguousRegs = true;
302
303 for (unsigned i = 0; i < CSI.size(); ++i) {
304 unsigned Reg = CSI[i].getReg();
305
306 //
307 // Check if we can use a double-word load.
308 //
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000309 unsigned SuperReg = uniqueSuperReg(Reg, TRI);
Craig Topper062a2ba2014-04-25 05:30:21 +0000310 const TargetRegisterClass* SuperRegClass = nullptr;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000311 bool CanUseDblLoad = false;
312 if (ContiguousRegs && (i < CSI.size()-1)) {
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000313 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
314 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
315 CanUseDblLoad = (SuperRegNext == SuperReg);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000316 }
317
318
319 if (CanUseDblLoad) {
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000320 TII.loadRegFromStackSlot(MBB, MI, SuperReg, CSI[i+1].getFrameIdx(),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000321 SuperRegClass, TRI);
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000322 MBB.addLiveIn(SuperReg);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000323 ++i;
324 } else {
325 // Cannot use a double-word load.
326 ContiguousRegs = false;
327 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
328 TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI);
329 MBB.addLiveIn(Reg);
330 }
331 }
332 return true;
333}
334
Eli Bendersky8da87162013-02-21 20:05:00 +0000335void HexagonFrameLowering::
336eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
337 MachineBasicBlock::iterator I) const {
338 MachineInstr &MI = *I;
339
340 if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) {
341 // Hexagon_TODO: add code
342 } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) {
343 // Hexagon_TODO: add code
344 } else {
345 llvm_unreachable("Cannot handle this call frame pseudo instruction");
346 }
347 MBB.erase(I);
348}
349
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000350int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
351 int FI) const {
352 return MF.getFrameInfo()->getObjectOffset(FI);
353}