• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- LanaiFrameLowering.cpp - Lanai Frame Information ------------------===//
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 // This file contains the Lanai implementation of TargetFrameLowering class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "LanaiFrameLowering.h"
15 
16 #include "LanaiInstrInfo.h"
17 #include "LanaiMachineFunctionInfo.h"
18 #include "LanaiSubtarget.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/IR/Function.h"
24 
25 using namespace llvm;
26 
27 // Determines the size of the frame and maximum call frame size.
determineFrameLayout(MachineFunction & MF) const28 void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const {
29   MachineFrameInfo &MFI = MF.getFrameInfo();
30   const LanaiRegisterInfo *LRI = STI.getRegisterInfo();
31 
32   // Get the number of bytes to allocate from the FrameInfo.
33   unsigned FrameSize = MFI.getStackSize();
34 
35   // Get the alignment.
36   unsigned StackAlign = LRI->needsStackRealignment(MF) ? MFI.getMaxAlignment()
37                                                        : getStackAlignment();
38 
39   // Get the maximum call frame size of all the calls.
40   unsigned MaxCallFrameSize = MFI.getMaxCallFrameSize();
41 
42   // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so
43   // that allocations will be aligned.
44   if (MFI.hasVarSizedObjects())
45     MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign);
46 
47   // Update maximum call frame size.
48   MFI.setMaxCallFrameSize(MaxCallFrameSize);
49 
50   // Include call frame size in total.
51   if (!(hasReservedCallFrame(MF) && MFI.adjustsStack()))
52     FrameSize += MaxCallFrameSize;
53 
54   // Make sure the frame is aligned.
55   FrameSize = alignTo(FrameSize, StackAlign);
56 
57   // Update frame info.
58   MFI.setStackSize(FrameSize);
59 }
60 
61 // Iterates through each basic block in a machine function and replaces
62 // ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the
63 // maximum call frame size as the immediate.
replaceAdjDynAllocPseudo(MachineFunction & MF) const64 void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const {
65   const LanaiInstrInfo &LII =
66       *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
67   unsigned MaxCallFrameSize = MF.getFrameInfo().getMaxCallFrameSize();
68 
69   for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); MBB != E;
70        ++MBB) {
71     MachineBasicBlock::iterator MBBI = MBB->begin();
72     while (MBBI != MBB->end()) {
73       MachineInstr &MI = *MBBI++;
74       if (MI.getOpcode() == Lanai::ADJDYNALLOC) {
75         DebugLoc DL = MI.getDebugLoc();
76         unsigned Dst = MI.getOperand(0).getReg();
77         unsigned Src = MI.getOperand(1).getReg();
78 
79         BuildMI(*MBB, MI, DL, LII.get(Lanai::ADD_I_LO), Dst)
80             .addReg(Src)
81             .addImm(MaxCallFrameSize);
82         MI.eraseFromParent();
83       }
84     }
85   }
86 }
87 
88 // Generates the following sequence for function entry:
89 //   st %fp,-4[*%sp]        !push old FP
90 //   add %sp,8,%fp          !generate new FP
91 //   sub %sp,0x4,%sp        !allocate stack space (as needed)
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const92 void LanaiFrameLowering::emitPrologue(MachineFunction &MF,
93                                       MachineBasicBlock &MBB) const {
94   assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
95 
96   MachineFrameInfo &MFI = MF.getFrameInfo();
97   const LanaiInstrInfo &LII =
98       *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
99   MachineBasicBlock::iterator MBBI = MBB.begin();
100 
101   // Debug location must be unknown since the first debug location is used
102   // to determine the end of the prologue.
103   DebugLoc DL;
104 
105   // Determine the correct frame layout
106   determineFrameLayout(MF);
107 
108   // FIXME: This appears to be overallocating.  Needs investigation.
109   // Get the number of bytes to allocate from the FrameInfo.
110   unsigned StackSize = MFI.getStackSize();
111 
112   // Push old FP
113   // st %fp,-4[*%sp]
114   BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI))
115       .addReg(Lanai::FP)
116       .addReg(Lanai::SP)
117       .addImm(-4)
118       .addImm(LPAC::makePreOp(LPAC::ADD))
119       .setMIFlag(MachineInstr::FrameSetup);
120 
121   // Generate new FP
122   // add %sp,8,%fp
123   BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP)
124       .addReg(Lanai::SP)
125       .addImm(8)
126       .setMIFlag(MachineInstr::FrameSetup);
127 
128   // Allocate space on the stack if needed
129   // sub %sp,StackSize,%sp
130   if (StackSize != 0) {
131     BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP)
132         .addReg(Lanai::SP)
133         .addImm(StackSize)
134         .setMIFlag(MachineInstr::FrameSetup);
135   }
136 
137   // Replace ADJDYNANALLOC
138   if (MFI.hasVarSizedObjects())
139     replaceAdjDynAllocPseudo(MF);
140 }
141 
eliminateCallFramePseudoInstr(MachineFunction &,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const142 MachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr(
143     MachineFunction & /*MF*/, MachineBasicBlock &MBB,
144     MachineBasicBlock::iterator I) const {
145   // Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
146   return MBB.erase(I);
147 }
148 
149 // The function epilogue should not depend on the current stack pointer!
150 // It should use the frame pointer only.  This is mandatory because
151 // of alloca; we also take advantage of it to omit stack adjustments
152 // before returning.
153 //
154 // Note that when we go to restore the preserved register values we must
155 // not try to address their slots by using offsets from the stack pointer.
156 // That's because the stack pointer may have been moved during the function
157 // execution due to a call to alloca().  Rather, we must restore all
158 // preserved registers via offsets from the frame pointer value.
159 //
160 // Note also that when the current frame is being "popped" (by adjusting
161 // the value of the stack pointer) on function exit, we must (for the
162 // sake of alloca) set the new value of the stack pointer based upon
163 // the current value of the frame pointer.  We can't just add what we
164 // believe to be the (static) frame size to the stack pointer because
165 // if we did that, and alloca() had been called during this function,
166 // we would end up returning *without* having fully deallocated all of
167 // the space grabbed by alloca.  If that happened, and a function
168 // containing one or more alloca() calls was called over and over again,
169 // then the stack would grow without limit!
170 //
171 // RET is lowered to
172 //      ld -4[%fp],%pc  # modify %pc (two delay slots)
173 // as the return address is in the stack frame and mov to pc is allowed.
174 // emitEpilogue emits
175 //      mov %fp,%sp     # restore the stack pointer
176 //      ld -8[%fp],%fp  # restore the caller's frame pointer
177 // before RET and the delay slot filler will move RET such that these
178 // instructions execute in the delay slots of the load to PC.
emitEpilogue(MachineFunction &,MachineBasicBlock & MBB) const179 void LanaiFrameLowering::emitEpilogue(MachineFunction & /*MF*/,
180                                       MachineBasicBlock &MBB) const {
181   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
182   const LanaiInstrInfo &LII =
183       *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
184   DebugLoc DL = MBBI->getDebugLoc();
185 
186   // Restore the stack pointer using the callee's frame pointer value.
187   BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::SP)
188       .addReg(Lanai::FP)
189       .addImm(0);
190 
191   // Restore the frame pointer from the stack.
192   BuildMI(MBB, MBBI, DL, LII.get(Lanai::LDW_RI), Lanai::FP)
193       .addReg(Lanai::FP)
194       .addImm(-8)
195       .addImm(LPAC::ADD);
196 }
197 
determineCalleeSaves(MachineFunction & MF,BitVector & SavedRegs,RegScavenger * RS) const198 void LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF,
199                                               BitVector &SavedRegs,
200                                               RegScavenger *RS) const {
201   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
202 
203   MachineFrameInfo &MFI = MF.getFrameInfo();
204   const LanaiRegisterInfo *LRI =
205       static_cast<const LanaiRegisterInfo *>(STI.getRegisterInfo());
206   int Offset = -4;
207 
208   // Reserve 4 bytes for the saved RCA
209   MFI.CreateFixedObject(4, Offset, true);
210   Offset -= 4;
211 
212   // Reserve 4 bytes for the saved FP
213   MFI.CreateFixedObject(4, Offset, true);
214   Offset -= 4;
215 
216   if (LRI->hasBasePointer(MF)) {
217     MFI.CreateFixedObject(4, Offset, true);
218     SavedRegs.reset(LRI->getBaseRegister());
219   }
220 }
221