LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSP430FrameLowering.cpp
Go to the documentation of this file.
1 //===-- MSP430FrameLowering.cpp - MSP430 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 MSP430 implementation of TargetFrameLowering class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "MSP430FrameLowering.h"
15 #include "MSP430InstrInfo.h"
22 #include "llvm/IR/DataLayout.h"
23 #include "llvm/IR/Function.h"
26 
27 using namespace llvm;
28 
30  const MachineFrameInfo *MFI = MF.getFrameInfo();
31 
32  return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
34  MFI->isFrameAddressTaken());
35 }
36 
38  return !MF.getFrameInfo()->hasVarSizedObjects();
39 }
40 
42  MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
43  MachineFrameInfo *MFI = MF.getFrameInfo();
45  const MSP430InstrInfo &TII =
46  *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
47 
49  DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
50 
51  // Get the number of bytes to allocate from the FrameInfo.
52  uint64_t StackSize = MFI->getStackSize();
53 
54  uint64_t NumBytes = 0;
55  if (hasFP(MF)) {
56  // Calculate required stack adjustment
57  uint64_t FrameSize = StackSize - 2;
58  NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize();
59 
60  // Get the offset of the stack slot for the EBP register... which is
61  // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
62  // Update the frame offset adjustment.
63  MFI->setOffsetAdjustment(-NumBytes);
64 
65  // Save FPW into the appropriate stack slot...
66  BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
67  .addReg(MSP430::FPW, RegState::Kill);
68 
69  // Update FPW with the new base value...
70  BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FPW)
71  .addReg(MSP430::SPW);
72 
73  // Mark the FramePtr as live-in in every block except the entry.
74  for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();
75  I != E; ++I)
76  I->addLiveIn(MSP430::FPW);
77 
78  } else
79  NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize();
80 
81  // Skip the callee-saved push instructions.
82  while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r))
83  ++MBBI;
84 
85  if (MBBI != MBB.end())
86  DL = MBBI->getDebugLoc();
87 
88  if (NumBytes) { // adjust stack pointer: SPW -= numbytes
89  // If there is an SUB16ri of SPW immediately before this instruction, merge
90  // the two.
91  //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
92  // If there is an ADD16ri or SUB16ri of SPW immediately after this
93  // instruction, merge the two instructions.
94  // mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
95 
96  if (NumBytes) {
97  MachineInstr *MI =
98  BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SPW)
99  .addReg(MSP430::SPW).addImm(NumBytes);
100  // The SRW implicit def is dead.
101  MI->getOperand(3).setIsDead();
102  }
103  }
104 }
105 
107  MachineBasicBlock &MBB) const {
108  const MachineFrameInfo *MFI = MF.getFrameInfo();
110  const MSP430InstrInfo &TII =
111  *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
112 
114  unsigned RetOpcode = MBBI->getOpcode();
115  DebugLoc DL = MBBI->getDebugLoc();
116 
117  switch (RetOpcode) {
118  case MSP430::RET:
119  case MSP430::RETI: break; // These are ok
120  default:
121  llvm_unreachable("Can only insert epilog into returning blocks");
122  }
123 
124  // Get the number of bytes to allocate from the FrameInfo
125  uint64_t StackSize = MFI->getStackSize();
126  unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
127  uint64_t NumBytes = 0;
128 
129  if (hasFP(MF)) {
130  // Calculate required stack adjustment
131  uint64_t FrameSize = StackSize - 2;
132  NumBytes = FrameSize - CSSize;
133 
134  // pop FPW.
135  BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW);
136  } else
137  NumBytes = StackSize - CSSize;
138 
139  // Skip the callee-saved pop instructions.
140  while (MBBI != MBB.begin()) {
142  unsigned Opc = PI->getOpcode();
143  if (Opc != MSP430::POP16r && !PI->isTerminator())
144  break;
145  --MBBI;
146  }
147 
148  DL = MBBI->getDebugLoc();
149 
150  // If there is an ADD16ri or SUB16ri of SPW immediately before this
151  // instruction, merge the two instructions.
152  //if (NumBytes || MFI->hasVarSizedObjects())
153  // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
154 
155  if (MFI->hasVarSizedObjects()) {
156  BuildMI(MBB, MBBI, DL,
157  TII.get(MSP430::MOV16rr), MSP430::SPW).addReg(MSP430::FPW);
158  if (CSSize) {
159  MachineInstr *MI =
160  BuildMI(MBB, MBBI, DL,
161  TII.get(MSP430::SUB16ri), MSP430::SPW)
162  .addReg(MSP430::SPW).addImm(CSSize);
163  // The SRW implicit def is dead.
164  MI->getOperand(3).setIsDead();
165  }
166  } else {
167  // adjust stack pointer back: SPW += numbytes
168  if (NumBytes) {
169  MachineInstr *MI =
170  BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW)
171  .addReg(MSP430::SPW).addImm(NumBytes);
172  // The SRW implicit def is dead.
173  MI->getOperand(3).setIsDead();
174  }
175  }
176 }
177 
178 // FIXME: Can we eleminate these in favour of generic code?
179 bool
182  const std::vector<CalleeSavedInfo> &CSI,
183  const TargetRegisterInfo *TRI) const {
184  if (CSI.empty())
185  return false;
186 
187  DebugLoc DL;
188  if (MI != MBB.end()) DL = MI->getDebugLoc();
189 
190  MachineFunction &MF = *MBB.getParent();
191  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
193  MFI->setCalleeSavedFrameSize(CSI.size() * 2);
194 
195  for (unsigned i = CSI.size(); i != 0; --i) {
196  unsigned Reg = CSI[i-1].getReg();
197  // Add the callee-saved register as live-in. It's killed at the spill.
198  MBB.addLiveIn(Reg);
199  BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r))
200  .addReg(Reg, RegState::Kill);
201  }
202  return true;
203 }
204 
205 bool
208  const std::vector<CalleeSavedInfo> &CSI,
209  const TargetRegisterInfo *TRI) const {
210  if (CSI.empty())
211  return false;
212 
213  DebugLoc DL;
214  if (MI != MBB.end()) DL = MI->getDebugLoc();
215 
216  MachineFunction &MF = *MBB.getParent();
217  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
218 
219  for (unsigned i = 0, e = CSI.size(); i != e; ++i)
220  BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), CSI[i].getReg());
221 
222  return true;
223 }
224 
228  const MSP430InstrInfo &TII =
229  *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
230  unsigned StackAlign = getStackAlignment();
231 
232  if (!hasReservedCallFrame(MF)) {
233  // If the stack pointer can be changed after prologue, turn the
234  // adjcallstackup instruction into a 'sub SPW, <amt>' and the
235  // adjcallstackdown instruction into 'add SPW, <amt>'
236  // TODO: consider using push / pop instead of sub + store / add
237  MachineInstr *Old = I;
238  uint64_t Amount = Old->getOperand(0).getImm();
239  if (Amount != 0) {
240  // We need to keep the stack aligned properly. To do this, we round the
241  // amount of space needed for the outgoing arguments up to the next
242  // alignment boundary.
243  Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
244 
245  MachineInstr *New = 0;
246  if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) {
247  New = BuildMI(MF, Old->getDebugLoc(),
248  TII.get(MSP430::SUB16ri), MSP430::SPW)
249  .addReg(MSP430::SPW).addImm(Amount);
250  } else {
251  assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode());
252  // factor out the amount the callee already popped.
253  uint64_t CalleeAmt = Old->getOperand(1).getImm();
254  Amount -= CalleeAmt;
255  if (Amount)
256  New = BuildMI(MF, Old->getDebugLoc(),
257  TII.get(MSP430::ADD16ri), MSP430::SPW)
258  .addReg(MSP430::SPW).addImm(Amount);
259  }
260 
261  if (New) {
262  // The SRW implicit def is dead.
263  New->getOperand(3).setIsDead();
264 
265  // Replace the pseudo instruction with a new instruction...
266  MBB.insert(I, New);
267  }
268  }
269  } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
270  // If we are performing frame pointer elimination and if the callee pops
271  // something off the stack pointer, add it back.
272  if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
273  MachineInstr *Old = I;
274  MachineInstr *New =
275  BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
276  MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt);
277  // The SRW implicit def is dead.
278  New->getOperand(3).setIsDead();
279 
280  MBB.insert(I, New);
281  }
282  }
283 
284  MBB.erase(I);
285 }
286 
287 void
289  RegScavenger *) const {
290  // Create a frame entry for the FPW register that must be saved.
291  if (hasFP(MF)) {
292  int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true);
293  (void)FrameIdx;
294  assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() &&
295  "Slot for FPW register must be last in order to be found!");
296  }
297 }
unsigned getStackAlignment() const
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
const MachineFunction * getParent() const
instr_iterator erase(instr_iterator I)
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=NULL) const
void emitPrologue(MachineFunction &MF) const
void addLiveIn(unsigned Reg)
void setIsDead(bool Val=true)
uint64_t getStackSize() const
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
bool DisableFramePointerElim(const MachineFunction &MF) const
Abstract Stack Frame Information.
bool isFrameAddressTaken() const
const MachineInstrBuilder & addImm(int64_t Val) const
bool hasFP(const MachineFunction &MF) const
const MachineBasicBlock & front() const
int getObjectIndexBegin() const
int getOpcode() const
Definition: MachineInstr.h:261
int64_t getImm() const
bundle_iterator< MachineInstr, instr_iterator > iterator
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
ItTy next(ItTy it, Dist n)
Definition: STLExtras.h:154
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
const MCInstrDesc & get(unsigned Opcode) const
Definition: MCInstrInfo.h:48
virtual const TargetInstrInfo * getInstrInfo() const
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
void setOffsetAdjustment(int Adj)
MachineFrameInfo * getFrameInfo()
bool hasReservedCallFrame(const MachineFunction &MF) const
static DebugLoc get(unsigned Line, unsigned Col, MDNode *Scope, MDNode *InlinedAt=0)
Definition: DebugLoc.cpp:74
#define I(x, y, z)
Definition: MD5.cpp:54
const TargetMachine & getTarget() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
bool hasVarSizedObjects() const
BasicBlockListType::iterator iterator
ItTy prior(ItTy it, Dist n)
Definition: STLExtras.h:167
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable)
DebugLoc getDebugLoc() const
Definition: MachineInstr.h:244