LLVM  10.0.0svn
MSP430FrameLowering.cpp
Go to the documentation of this file.
1 //===-- MSP430FrameLowering.cpp - MSP430 Frame Information ----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the MSP430 implementation of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MSP430FrameLowering.h"
14 #include "MSP430InstrInfo.h"
16 #include "MSP430Subtarget.h"
22 #include "llvm/IR/DataLayout.h"
23 #include "llvm/IR/Function.h"
25 
26 using namespace llvm;
27 
29  const MachineFrameInfo &MFI = MF.getFrameInfo();
30 
31  return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
33  MFI.isFrameAddressTaken());
34 }
35 
37  return !MF.getFrameInfo().hasVarSizedObjects();
38 }
39 
41  MachineBasicBlock &MBB) const {
42  assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
43  MachineFrameInfo &MFI = MF.getFrameInfo();
45  const MSP430InstrInfo &TII =
46  *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().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 FP into the appropriate stack slot...
66  BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
67  .addReg(MSP430::FP, RegState::Kill);
68 
69  // Update FP with the new base value...
70  BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FP)
71  .addReg(MSP430::SP);
72 
73  // Mark the FramePtr as live-in in every block except the entry.
74  for (MachineFunction::iterator I = std::next(MF.begin()), E = MF.end();
75  I != E; ++I)
76  I->addLiveIn(MSP430::FP);
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: SP -= numbytes
89  // If there is an SUB16ri of SP immediately before this instruction, merge
90  // the two.
91  //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
92  // If there is an ADD16ri or SUB16ri of SP 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::SP)
99  .addReg(MSP430::SP).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.getSubtarget().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 FP.
135  BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FP);
136  } else
137  NumBytes = StackSize - CSSize;
138 
139  // Skip the callee-saved pop instructions.
140  while (MBBI != MBB.begin()) {
141  MachineBasicBlock::iterator PI = std::prev(MBBI);
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 SP 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::SP).addReg(MSP430::FP);
158  if (CSSize) {
159  MachineInstr *MI =
160  BuildMI(MBB, MBBI, DL,
161  TII.get(MSP430::SUB16ri), MSP430::SP)
162  .addReg(MSP430::SP).addImm(CSSize);
163  // The SRW implicit def is dead.
164  MI->getOperand(3).setIsDead();
165  }
166  } else {
167  // adjust stack pointer back: SP += numbytes
168  if (NumBytes) {
169  MachineInstr *MI =
170  BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP)
171  .addReg(MSP430::SP).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.getSubtarget().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  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.getSubtarget().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.getSubtarget().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 SP, <amt>' and the
235  // adjcallstackdown instruction into 'add SP, <amt>'
236  // TODO: consider using push / pop instead of sub + store / add
237  MachineInstr &Old = *I;
238  uint64_t Amount = TII.getFrameSize(Old);
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 = nullptr;
246  if (Old.getOpcode() == TII.getCallFrameSetupOpcode()) {
247  New =
248  BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP)
249  .addReg(MSP430::SP)
250  .addImm(Amount);
251  } else {
252  assert(Old.getOpcode() == TII.getCallFrameDestroyOpcode());
253  // factor out the amount the callee already popped.
254  Amount -= TII.getFramePoppedByCallee(Old);
255  if (Amount)
256  New = BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::ADD16ri),
257  MSP430::SP)
258  .addReg(MSP430::SP)
259  .addImm(Amount);
260  }
261 
262  if (New) {
263  // The SRW implicit def is dead.
264  New->getOperand(3).setIsDead();
265 
266  // Replace the pseudo instruction with a new instruction...
267  MBB.insert(I, New);
268  }
269  }
270  } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
271  // If we are performing frame pointer elimination and if the callee pops
272  // something off the stack pointer, add it back.
273  if (uint64_t CalleeAmt = TII.getFramePoppedByCallee(*I)) {
274  MachineInstr &Old = *I;
275  MachineInstr *New =
276  BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP)
277  .addReg(MSP430::SP)
278  .addImm(CalleeAmt);
279  // The SRW implicit def is dead.
280  New->getOperand(3).setIsDead();
281 
282  MBB.insert(I, New);
283  }
284  }
285 
286  return MBB.erase(I);
287 }
288 
289 void
291  RegScavenger *) const {
292  // Create a frame entry for the FP register that must be saved.
293  if (hasFP(MF)) {
294  int FrameIdx = MF.getFrameInfo().CreateFixedObject(2, -4, true);
295  (void)FrameIdx;
296  assert(FrameIdx == MF.getFrameInfo().getObjectIndexBegin() &&
297  "Slot for FP register must be last in order to be found!");
298  }
299 }
DILocation * get() const
Get the underlying DILocation.
Definition: DebugLoc.cpp:21
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:23
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:384
unsigned Reg
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
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:410
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.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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...
constexpr double e
Definition: MathExtras.h:57
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:63
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:44
TargetOptions Options
#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:415
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...