TargetFrameLowering.h revision 16c29b5f285f375be53dabaa73e3e91107485fe4
116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov//===-- llvm/Target/TargetFrameLowering.h ---------------------------*- C++ -*-===//
234695381d626485a560594f162701088079589dfMisha Brukman//
36fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//                     The LLVM Compiler Infrastructure
46fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
734695381d626485a560594f162701088079589dfMisha Brukman//
86fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//===----------------------------------------------------------------------===//
9035dfbe7f2d109008d2d62d9f2a67efb477a7ab6Chris Lattner//
10fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner// Interface to describe the layout of a stack frame on the target machine.
11035dfbe7f2d109008d2d62d9f2a67efb477a7ab6Chris Lattner//
12035dfbe7f2d109008d2d62d9f2a67efb477a7ab6Chris Lattner//===----------------------------------------------------------------------===//
137cffcaaa48656fa6f90b041cc5f056304addef32Vikram S. Adve
1416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#ifndef LLVM_TARGET_TARGETFRAMELOWERING_H
1516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#define LLVM_TARGET_TARGETFRAMELOWERING_H
167cffcaaa48656fa6f90b041cc5f056304addef32Vikram S. Adve
17cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov#include "llvm/CodeGen/MachineBasicBlock.h"
18cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
1909431e187f9abd45af08461df728204ee9731fd7Chris Lattner#include <utility>
20d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov#include <vector>
2109431e187f9abd45af08461df728204ee9731fd7Chris Lattner
22d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
23cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  class CalleeSavedInfo;
2433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  class MachineFunction;
2533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  class MachineBasicBlock;
26d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov  class MachineMove;
2794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  class RegScavenger;
28d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
29c07c0df634d31849ac659234e4718b57ddacb882Chris Lattner/// Information about stack frame layout on the target.  It holds the direction
30c07c0df634d31849ac659234e4718b57ddacb882Chris Lattner/// of stack growth, the known stack alignment on entry to each function, and
31c07c0df634d31849ac659234e4718b57ddacb882Chris Lattner/// the offset to the locals area.
32c07c0df634d31849ac659234e4718b57ddacb882Chris Lattner///
33c07c0df634d31849ac659234e4718b57ddacb882Chris Lattner/// The offset to the local area is the offset from the stack pointer on
34c07c0df634d31849ac659234e4718b57ddacb882Chris Lattner/// function entry to the first location where function data (local variables,
35c07c0df634d31849ac659234e4718b57ddacb882Chris Lattner/// spill locations) can be stored.
3616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovclass TargetFrameLowering {
371fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerpublic:
38fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  enum StackDirection {
39fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner    StackGrowsUp,        // Adding to the stack increases the stack address
40fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner    StackGrowsDown       // Adding to the stack decreases the stack address
41fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  };
428ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller
438ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller  // Maps a callee saved register to a stack slot with a fixed offset.
448ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller  struct SpillSlot {
458ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller    unsigned Reg;
468ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller    int Offset; // Offset relative to stack pointer on function entry.
478ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller  };
48fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattnerprivate:
49fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  StackDirection StackDir;
50fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  unsigned StackAlignment;
510035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson  unsigned TransientStackAlignment;
52fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  int LocalAreaOffset;
537cffcaaa48656fa6f90b041cc5f056304addef32Vikram S. Advepublic:
5416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO,
5516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov                      unsigned TransAl = 1)
560035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
570035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson      LocalAreaOffset(LAO) {}
58fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner
5916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  virtual ~TargetFrameLowering();
60a1aad3b0eda2a516f663cb5f9f8c4c9bbb6ef224Reid Spencer
61fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  // These methods return information that describes the abstract stack layout
62fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  // of the target machine.
63fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner
64fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  /// getStackGrowthDirection - Return the direction the stack grows
65fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  ///
66fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  StackDirection getStackGrowthDirection() const { return StackDir; }
67fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner
680035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson  /// getStackAlignment - This method returns the number of bytes to which the
690035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson  /// stack pointer must be aligned on entry to a function.  Typically, this
700035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson  /// is the largest alignment for any data object in the target.
71fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  ///
72fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  unsigned getStackAlignment() const { return StackAlignment; }
73fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner
740035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson  /// getTransientStackAlignment - This method returns the number of bytes to
750035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson  /// which the stack pointer must be aligned at all times, even between
760035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson  /// calls.
770035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson  ///
780035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson  unsigned getTransientStackAlignment() const {
790035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    return TransientStackAlignment;
800035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson  }
810035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson
82fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  /// getOffsetOfLocalArea - This method returns the offset of the local area
83fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  /// from the stack pointer on entrance to a function.
84fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  ///
85fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner  int getOffsetOfLocalArea() const { return LocalAreaOffset; }
86fd529d2e4aed9a455d539962248fda8583d6ba8eChris Lattner
870098b3e2b69e527ddcf2ebad7a3081898fa3b4f0Evan Cheng  /// getCalleeSavedSpillSlots - This method returns a pointer to an array of
880098b3e2b69e527ddcf2ebad7a3081898fa3b4f0Evan Cheng  /// pairs, that contains an entry for each callee saved register that must be
8909431e187f9abd45af08461df728204ee9731fd7Chris Lattner  /// spilled to a particular stack location if it is spilled.
9009431e187f9abd45af08461df728204ee9731fd7Chris Lattner  ///
9109431e187f9abd45af08461df728204ee9731fd7Chris Lattner  /// Each entry in this array contains a <register,offset> pair, indicating the
9209431e187f9abd45af08461df728204ee9731fd7Chris Lattner  /// fixed offset from the incoming stack pointer that each register should be
938ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller  /// spilled at. If a register is not listed here, the code generator is
9409431e187f9abd45af08461df728204ee9731fd7Chris Lattner  /// allowed to spill it anywhere it chooses.
9534695381d626485a560594f162701088079589dfMisha Brukman  ///
968ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller  virtual const SpillSlot *
970098b3e2b69e527ddcf2ebad7a3081898fa3b4f0Evan Cheng  getCalleeSavedSpillSlots(unsigned &NumEntries) const {
9809431e187f9abd45af08461df728204ee9731fd7Chris Lattner    NumEntries = 0;
9909431e187f9abd45af08461df728204ee9731fd7Chris Lattner    return 0;
10009431e187f9abd45af08461df728204ee9731fd7Chris Lattner  }
10133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
10233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  /// targetHandlesStackFrameRounding - Returns true if the target is
10333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  /// responsible for rounding up the stack frame (probably at emitPrologue
10433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  /// time).
10533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  virtual bool targetHandlesStackFrameRounding() const {
10633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    return false;
10733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  }
10833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
10933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
11033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  /// the function.
11133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  virtual void emitPrologue(MachineFunction &MF) const = 0;
11233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  virtual void emitEpilogue(MachineFunction &MF,
11333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov                            MachineBasicBlock &MBB) const = 0;
114d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
115cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
116cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  /// saved registers and returns true if it isn't possible / profitable to do
117cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  /// so by issuing a series of store instructions via
118cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  /// storeRegToStackSlot(). Returns false otherwise.
119cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
120cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov                                         MachineBasicBlock::iterator MI,
121cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov                                        const std::vector<CalleeSavedInfo> &CSI,
122cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov                                         const TargetRegisterInfo *TRI) const {
123cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov    return false;
124cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  }
125cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
126cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  /// restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee
127cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  /// saved registers and returns true if it isn't possible / profitable to do
128cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  /// so by issuing a series of load instructions via loadRegToStackSlot().
129cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  /// Returns false otherwise.
130cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
131cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov                                           MachineBasicBlock::iterator MI,
132cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov                                        const std::vector<CalleeSavedInfo> &CSI,
133cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov                                        const TargetRegisterInfo *TRI) const {
134cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov    return false;
135cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  }
136cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
137d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// hasFP - Return true if the specified function should have a dedicated
138d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// frame pointer register. For most targets this is true only if the function
139d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// has variable sized allocas or if frame pointer elimination is disabled.
140d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  virtual bool hasFP(const MachineFunction &MF) const = 0;
141d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
142d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
143d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// not required, we reserve argument space for call sites in the function
144d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// immediately on entry to the current function. This eliminates the need for
145d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// add/sub sp brackets around call sites. Returns true if the call frame is
146d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// included as part of the stack frame.
147d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  virtual bool hasReservedCallFrame(const MachineFunction &MF) const {
148d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    return !hasFP(MF);
149d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  }
150d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
151d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// canSimplifyCallFramePseudos - When possible, it's best to simplify the
152d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// call frame pseudo ops before doing frame index elimination. This is
153d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// possible only when frame index references between the pseudos won't
154d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// need adjusting for the call frame adjustments. Normally, that's true
155d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// if the function has a reserved call frame or a frame pointer. Some
156d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// targets (Thumb2, for example) may have more complicated criteria,
157d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  /// however, and can override this behavior.
158d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const {
159d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    return hasReservedCallFrame(MF) || hasFP(MF);
160d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  }
161d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
162d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov  /// getInitialFrameState - Returns a list of machine moves that are assumed
163d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov  /// on entry to all functions.  Note that LabelID is ignored (assumed to be
164d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov  /// the beginning of the function.)
165d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov  virtual void getInitialFrameState(std::vector<MachineMove> &Moves) const;
16682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov
16782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov  /// getFrameIndexOffset - Returns the displacement from the frame register to
16882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov  /// the stack frame of the specified index.
16982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov  virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
17082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov
17182f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov  /// getFrameIndexReference - This method should return the base register
17282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov  /// and offset used to reference a frame index location. The offset is
17382f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov  /// returned directly, and the base register is returned via FrameReg.
17482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov  virtual int getFrameIndexReference(const MachineFunction &MF, int FI,
17582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov                                     unsigned &FrameReg) const;
17694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov
17794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  /// processFunctionBeforeCalleeSavedScan - This method is called immediately
17894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  /// before PrologEpilogInserter scans the physical registers used to determine
17994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  /// what callee saved registers should be spilled. This method is optional.
18094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
18194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov                                                RegScavenger *RS = NULL) const {
18294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov
18394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  }
18494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov
18594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  /// processFunctionBeforeFrameFinalized - This method is called immediately
18694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  /// before the specified function's frame layout (MF.getFrameInfo()) is
18794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  /// finalized.  Once the frame is finalized, MO_FrameIndex operands are
18894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  /// replaced with direct constants.  This method is optional.
18994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  ///
19094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
19194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  }
1927cffcaaa48656fa6f90b041cc5f056304addef32Vikram S. Adve};
1937cffcaaa48656fa6f90b041cc5f056304addef32Vikram S. Adve
194d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
195d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
1967cffcaaa48656fa6f90b041cc5f056304addef32Vikram S. Adve#endif
197