LLVM  8.0.1
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"
17 #include "MSP430Subtarget.h"
23 #include "llvm/IR/DataLayout.h"
24 #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) const {
43  assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
44  MachineFrameInfo &MFI = MF.getFrameInfo();
46  const MSP430InstrInfo &TII =
47  *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
48 
50  DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
51 
52  // Get the number of bytes to allocate from the FrameInfo.
53  uint64_t StackSize = MFI.getStackSize();
54 
55  uint64_t NumBytes = 0;
56  if (hasFP(MF)) {
57  // Calculate required stack adjustment
58  uint64_t FrameSize = StackSize - 2;
59  NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize();
60 
61  // Get the offset of the stack slot for the EBP register... which is
62  // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
63  // Update the frame offset adjustment.
64  MFI.setOffsetAdjustment(-NumBytes);
65 
66  // Save FP into the appropriate stack slot...
67  BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
68  .addReg(MSP430::FP, RegState::Kill);
69 
70  // Update FP with the new base value...
71  BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FP)
72  .addReg(MSP430::SP);
73 
74  // Mark the FramePtr as live-in in every block except the entry.
75  for (MachineFunction::iterator I = std::next(MF.begin()), E = MF.end();
76  I != E; ++I)
77  I->addLiveIn(MSP430::FP);
78 
79  } else
80  NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize();
81 
82  // Skip the callee-saved push instructions.
83  while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r))
84  ++MBBI;
85 
86  if (MBBI != MBB.end())
87  DL = MBBI->getDebugLoc();
88 
89  if (NumBytes) { // adjust stack pointer: SP -= numbytes
90  // If there is an SUB16ri of SP immediately before this instruction, merge
91  // the two.
92  //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
93  // If there is an ADD16ri or SUB16ri of SP immediately after this
94  // instruction, merge the two instructions.
95  // mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
96 
97  if (NumBytes) {
98  MachineInstr *MI =
99  BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP)
100  .addReg(MSP430::SP).addImm(NumBytes);
101  // The SRW implicit def is dead.
102  MI->getOperand(3).setIsDead();
103  }
104  }
105 }
106 
108  MachineBasicBlock &MBB) const {
109  const MachineFrameInfo &MFI = MF.getFrameInfo();
111  const MSP430InstrInfo &TII =
112  *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
113 
115  unsigned RetOpcode = MBBI->getOpcode();
116  DebugLoc DL = MBBI->getDebugLoc();
117 
118  switch (RetOpcode) {
119  case MSP430::RET:
120  case MSP430::RETI: break; // These are ok
121  default:
122  llvm_unreachable("Can only insert epilog into returning blocks");
123  }
124 
125  // Get the number of bytes to allocate from the FrameInfo
126  uint64_t StackSize = MFI.getStackSize();
127  unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
128  uint64_t NumBytes = 0;
129 
130  if (hasFP(MF)) {
131  // Calculate required stack adjustment
132  uint64_t FrameSize = StackSize - 2;
133  NumBytes = FrameSize - CSSize;
134 
135  // pop FP.
136  BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FP);
137  } else
138  NumBytes = StackSize - CSSize;
139 
140  // Skip the callee-saved pop instructions.
141  while (MBBI != MBB.begin()) {
142  MachineBasicBlock::iterator PI = std::prev(MBBI);
143  unsigned Opc = PI->getOpcode();
144  if (Opc != MSP430::POP16r && !PI->isTerminator())
145  break;
146  --MBBI;
147  }
148 
149  DL = MBBI->getDebugLoc();
150 
151  // If there is an ADD16ri or SUB16ri of SP immediately before this
152  // instruction, merge the two instructions.
153  //if (NumBytes || MFI.hasVarSizedObjects())
154  // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
155 
156  if (MFI.hasVarSizedObjects()) {
157  BuildMI(MBB, MBBI, DL,
158  TII.get(MSP430::MOV16rr), MSP430::SP).addReg(MSP430::FP);
159  if (CSSize) {
160  MachineInstr *MI =
161  BuildMI(MBB, MBBI, DL,
162  TII.get(MSP430::SUB16ri), MSP430::SP)
163  .addReg(MSP430::SP).addImm(CSSize);
164  // The SRW implicit def is dead.
165  MI->getOperand(3).setIsDead();
166  }
167  } else {
168  // adjust stack pointer back: SP += numbytes
169  if (NumBytes) {
170  MachineInstr *MI =
171  BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP)
172  .addReg(MSP430::SP).addImm(NumBytes);
173  // The SRW implicit def is dead.
174  MI->getOperand(3).setIsDead();
175  }
176  }
177 }
178 
179 // FIXME: Can we eleminate these in favour of generic code?
180 bool
183  const std::vector<CalleeSavedInfo> &CSI,
184  const TargetRegisterInfo *TRI) const {
185  if (CSI.empty())
186  return false;
187 
188  DebugLoc DL;
189  if (MI != MBB.end()) DL = MI->getDebugLoc();
190 
191  MachineFunction &MF = *MBB.getParent();
192  const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
194  MFI->setCalleeSavedFrameSize(CSI.size() * 2);
195 
196  for (unsigned i = CSI.size(); i != 0; --i) {
197  unsigned Reg = CSI[i-1].getReg();
198  // Add the callee-saved register as live-in. It's killed at the spill.
199  MBB.addLiveIn(Reg);
200  BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r))
201  .addReg(Reg, RegState::Kill);
202  }
203  return true;
204 }
205 
206 bool
209  std::vector<CalleeSavedInfo> &CSI,
210  const TargetRegisterInfo *TRI) const {
211  if (CSI.empty())
212  return false;
213 
214  DebugLoc DL;
215  if (MI != MBB.end()) DL = MI->getDebugLoc();
216 
217  MachineFunction &MF = *MBB.getParent();
218  const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
219 
220  for (unsigned i = 0, e = CSI.size(); i != e; ++i)
221  BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), CSI[i].getReg());
222 
223  return true;
224 }
225 
229  const MSP430InstrInfo &TII =
230  *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
231  unsigned StackAlign = getStackAlignment();
232 
233  if (!hasReservedCallFrame(MF)) {
234  // If the stack pointer can be changed after prologue, turn the
235  // adjcallstackup instruction into a 'sub SP, <amt>' and the
236  // adjcallstackdown instruction into 'add SP, <amt>'
237  // TODO: consider using push / pop instead of sub + store / add
238  MachineInstr &Old = *I;
239  uint64_t Amount = TII.getFrameSize(Old);
240  if (Amount != 0) {
241  // We need to keep the stack aligned properly. To do this, we round the
242  // amount of space needed for the outgoing arguments up to the next
243  // alignment boundary.
244  Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
245 
246  MachineInstr *New = nullptr;
247  if (Old.getOpcode() == TII.getCallFrameSetupOpcode()) {
248  New =
249  BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP)
250  .addReg(MSP430::SP)
251  .addImm(Amount);
252  } else {
253  assert(Old.getOpcode() == TII.getCallFrameDestroyOpcode());
254  // factor out the amount the callee already popped.
255  Amount -= TII.getFramePoppedByCallee(Old);
256  if (Amount)
257  New = BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::ADD16ri),
258  MSP430::SP)
259  .addReg(MSP430::SP)
260  .addImm(Amount);
261  }
262 
263  if (New) {
264  // The SRW implicit def is dead.
265  New->getOperand(3).setIsDead();
266 
267  // Replace the pseudo instruction with a new instruction...
268  MBB.insert(I, New);
269  }
270  }
271  } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
272  // If we are performing frame pointer elimination and if the callee pops
273  // something off the stack pointer, add it back.
274  if (uint64_t CalleeAmt = TII.getFramePoppedByCallee(*I)) {
275  MachineInstr &Old = *I;
276  MachineInstr *New =
277  BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP)
278  .addReg(MSP430::SP)
279  .addImm(CalleeAmt);
280  // The SRW implicit def is dead.
281  New->getOperand(3).setIsDead();
282 
283  MBB.insert(I, New);
284  }
285  }
286 
287  return MBB.erase(I);
288 }
289 
290 void
292  RegScavenger *) const {
293  // Create a frame entry for the FP register that must be saved.
294  if (hasFP(MF)) {
295  int FrameIdx = MF.getFrameInfo().CreateFixedObject(2, -4, true);
296  (void)FrameIdx;
297  assert(FrameIdx == MF.getFrameInfo().getObjectIndexBegin() &&
298  "Slot for FP register must be last in order to be found!");
299  }
300 }
DILocation * get() const
Get the underlying DILocation.
Definition: DebugLoc.cpp:22
MSP430MachineFunctionInfo - This class is derived from MachineFunction and contains private MSP430 ta...
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
This class represents lattice values for constants.
Definition: AllocatorList.h:24
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:383
unsigned Reg
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:34
void setIsDead(bool Val=true)
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
const HexagonInstrInfo * TII
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
int getObjectIndexBegin() const
Return the minimum frame object index.
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
virtual const TargetInstrInfo * getInstrInfo() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required, we reserve argument space for call sites in the function immediately on entry to the current function.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
Iterator for intrusive lists based on ilist_node.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int64_t getFramePoppedByCallee(const MachineInstr &I) const
Representation of each machine instruction.
Definition: MachineInstr.h:64
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
TargetOptions Options
Definition: TargetMachine.h:97
#define I(x, y, z)
Definition: MD5.cpp:58
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...