blob: 0fda4edf86304e6377238b5c1dc12aa99e59cf4b [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.
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 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);
85
86 // Check if frame moves are needed for EH.
87 bool needsFrameMoves = MMI.hasDebugInfo() ||
88 !MF.getFunction()->needsUnwindTableEntry();
89
90 // Get the number of bytes to allocate from the FrameInfo.
91 int NumBytes = (int) MFI->getStackSize();
92
93 // LLVM expects allocframe not to be the first instruction in the
94 // basic block.
95 MachineBasicBlock::iterator InsertPt = MBB.begin();
96
97 //
98 // ALLOCA adjust regs. Iterate over ADJDYNALLOC nodes and change the offset.
99 //
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();
106 i != e; ++i) {
107 MachineInstr* MI = *i;
108 assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) &&
109 "Expected adjust alloca node");
110
111 MachineOperand& MO = MI->getOperand(2);
112 assert(MO.isImm() && "Expected immediate");
113 MO.setImm(MFI->getMaxCallFrameSize());
114 }
115
116 std::vector<MachineMove> &Moves = MMI.getFrameMoves();
117
118 if (needsFrameMoves) {
119 // Advance CFA. DW_CFA_def_cfa
120 unsigned FPReg = QRI->getFrameRegister();
121 unsigned RAReg = QRI->getRARegister();
122
123 MachineLocation Dst(MachineLocation::VirtualFP);
124 MachineLocation Src(FPReg, -8);
125 Moves.push_back(MachineMove(0, Dst, Src));
126
127 // R31 = (R31 - #4)
128 MachineLocation LRDst(RAReg, -4);
129 MachineLocation LRSrc(RAReg);
130 Moves.push_back(MachineMove(0, LRDst, LRSrc));
131
132 // R30 = (R30 - #8)
133 MachineLocation SPDst(FPReg, -8);
134 MachineLocation SPSrc(FPReg);
135 Moves.push_back(MachineMove(0, SPDst, SPSrc));
136 }
137
138 //
139 // Only insert ALLOCFRAME if we need to.
140 //
141 if (hasFP(MF)) {
142 // Check for overflow.
143 // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
Tony Linthicum36e05192011-12-12 21:52:59 +0000144 const int ALLOCFRAME_MAX = 16384;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000145 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
146
147 if (NumBytes >= ALLOCFRAME_MAX) {
148 // Emit allocframe(#0).
149 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0);
150
151 // Subtract offset from frame pointer.
152 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
153 HEXAGON_RESERVED_REG_1).addImm(NumBytes);
154 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr),
155 QRI->getStackRegister()).
156 addReg(QRI->getStackRegister()).
157 addReg(HEXAGON_RESERVED_REG_1);
158 } else {
159 BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes);
160 }
161 }
162}
163// Returns true if MBB has a machine instructions that indicates a tail call
164// in the block.
165bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
166 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
167 unsigned RetOpcode = MBBI->getOpcode();
168
Matthew Curtiscd8c8812012-12-05 19:00:34 +0000169 return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;
170}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000171
172void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
173 MachineBasicBlock &MBB) const {
174 MachineBasicBlock::iterator MBBI = prior(MBB.end());
175 DebugLoc dl = MBBI->getDebugLoc();
176 //
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000177 // Only insert deallocframe if we need to. Also at -O0. See comment
178 // in emitPrologue above.
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000179 //
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000180 if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000181 MachineBasicBlock::iterator MBBI = prior(MBB.end());
182 MachineBasicBlock::iterator MBBI_end = MBB.end();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000183
184 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000185 // Handle EH_RETURN.
186 if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
Jyotsna Vermabf0bd1f2013-05-10 21:44:02 +0000187 assert(MBBI->getOperand(0).isReg() && "Offset should be in register!");
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000188 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
189 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr),
190 Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28);
191 return;
192 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000193 // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
194 // versions.
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000195 if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPret
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000196 && !DisableDeallocRet) {
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000197 // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC
198 // instruction if we encounter it.
199 MachineBasicBlock::iterator BeforeJMPR =
200 MBB.begin() == MBBI ? MBBI : prior(MBBI);
201 if (BeforeJMPR != MBBI &&
202 BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) {
203 // Remove the JMPR node.
204 MBB.erase(MBBI);
205 return;
206 }
207
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000208 // Add dealloc_return.
Jyotsna Verma300f0b92013-05-10 20:27:34 +0000209 MachineInstrBuilder MIB =
210 BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4));
211 // Transfer the function live-out registers.
212 MIB->copyImplicitOps(*MBB.getParent(), &*MBBI);
213 // Remove the JUMPR node.
214 MBB.erase(MBBI);
215 } else { // Add deallocframe for V2 and V3, and V4 tail calls.
216 // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra
217 // DEALLOCFRAME instruction after it.
218 MachineBasicBlock::iterator Term = MBB.getFirstTerminator();
219 MachineBasicBlock::iterator I =
220 Term == MBB.begin() ? MBB.end() : prior(Term);
221 if (I != MBB.end() &&
222 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4)
223 return;
224
225 BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000226 }
227 }
228}
229
230bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
231 const MachineFrameInfo *MFI = MF.getFrameInfo();
232 const HexagonMachineFunctionInfo *FuncInfo =
233 MF.getInfo<HexagonMachineFunctionInfo>();
234 return (MFI->hasCalls() || (MFI->getStackSize() > 0) ||
235 FuncInfo->hasClobberLR() );
236}
237
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000238static inline
239unsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI) {
240 MCSuperRegIterator SRI(Reg, TRI);
241 assert(SRI.isValid() && "Expected a superreg");
242 unsigned SuperReg = *SRI;
243 ++SRI;
244 assert(!SRI.isValid() && "Expected exactly one superreg");
245 return SuperReg;
246}
247
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000248bool
249HexagonFrameLowering::spillCalleeSavedRegisters(
250 MachineBasicBlock &MBB,
251 MachineBasicBlock::iterator MI,
252 const std::vector<CalleeSavedInfo> &CSI,
253 const TargetRegisterInfo *TRI) const {
254 MachineFunction *MF = MBB.getParent();
255 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
256
257 if (CSI.empty()) {
258 return false;
259 }
260
261 // We can only schedule double loads if we spill contiguous callee-saved regs
262 // For instance, we cannot scheduled double-word loads if we spill r24,
263 // r26, and r27.
264 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
265 // above.
266 bool ContiguousRegs = true;
267
268 for (unsigned i = 0; i < CSI.size(); ++i) {
269 unsigned Reg = CSI[i].getReg();
270
271 //
272 // Check if we can use a double-word store.
273 //
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000274 unsigned SuperReg = uniqueSuperReg(Reg, TRI);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000275 bool CanUseDblStore = false;
276 const TargetRegisterClass* SuperRegClass = 0;
277
278 if (ContiguousRegs && (i < CSI.size()-1)) {
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000279 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
280 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
281 CanUseDblStore = (SuperRegNext == SuperReg);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000282 }
283
284
285 if (CanUseDblStore) {
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000286 TII.storeRegToStackSlot(MBB, MI, SuperReg, true,
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000287 CSI[i+1].getFrameIdx(), SuperRegClass, TRI);
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000288 MBB.addLiveIn(SuperReg);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000289 ++i;
290 } else {
291 // Cannot use a double-word store.
292 ContiguousRegs = false;
293 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
294 TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC,
295 TRI);
296 MBB.addLiveIn(Reg);
297 }
298 }
299 return true;
300}
301
302
303bool HexagonFrameLowering::restoreCalleeSavedRegisters(
304 MachineBasicBlock &MBB,
305 MachineBasicBlock::iterator MI,
306 const std::vector<CalleeSavedInfo> &CSI,
307 const TargetRegisterInfo *TRI) const {
308
309 MachineFunction *MF = MBB.getParent();
310 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
311
312 if (CSI.empty()) {
313 return false;
314 }
315
316 // We can only schedule double loads if we spill contiguous callee-saved regs
317 // For instance, we cannot scheduled double-word loads if we spill r24,
318 // r26, and r27.
319 // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
320 // above.
321 bool ContiguousRegs = true;
322
323 for (unsigned i = 0; i < CSI.size(); ++i) {
324 unsigned Reg = CSI[i].getReg();
325
326 //
327 // Check if we can use a double-word load.
328 //
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000329 unsigned SuperReg = uniqueSuperReg(Reg, TRI);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000330 const TargetRegisterClass* SuperRegClass = 0;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000331 bool CanUseDblLoad = false;
332 if (ContiguousRegs && (i < CSI.size()-1)) {
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000333 unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
334 SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
335 CanUseDblLoad = (SuperRegNext == SuperReg);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000336 }
337
338
339 if (CanUseDblLoad) {
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000340 TII.loadRegFromStackSlot(MBB, MI, SuperReg, CSI[i+1].getFrameIdx(),
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000341 SuperRegClass, TRI);
Jakob Stoklund Olesen0b97dbc2012-05-30 22:40:03 +0000342 MBB.addLiveIn(SuperReg);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000343 ++i;
344 } else {
345 // Cannot use a double-word load.
346 ContiguousRegs = false;
347 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
348 TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI);
349 MBB.addLiveIn(Reg);
350 }
351 }
352 return true;
353}
354
Eli Bendersky8da87162013-02-21 20:05:00 +0000355void HexagonFrameLowering::
356eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
357 MachineBasicBlock::iterator I) const {
358 MachineInstr &MI = *I;
359
360 if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) {
361 // Hexagon_TODO: add code
362 } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) {
363 // Hexagon_TODO: add code
364 } else {
365 llvm_unreachable("Cannot handle this call frame pseudo instruction");
366 }
367 MBB.erase(I);
368}
369
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000370int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
371 int FI) const {
372 return MF.getFrameInfo()->getObjectOffset(FI);
373}