summaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCFrameLowering.h
blob: 01c155594c442f9a953915d9a91a0b9352fa9a2b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//===-- PPCFrameLowering.h - Define frame lowering for PowerPC --*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_POWERPC_PPCFRAMELOWERING_H
#define LLVM_LIB_TARGET_POWERPC_PPCFRAMELOWERING_H

#include "PPC.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/Target/TargetMachine.h"

namespace llvm {
class PPCSubtarget;

class PPCFrameLowering: public TargetFrameLowering {
  const PPCSubtarget &Subtarget;
  const unsigned ReturnSaveOffset;
  const unsigned TOCSaveOffset;
  const unsigned FramePointerSaveOffset;
  const unsigned LinkageSize;
  const unsigned BasePointerSaveOffset;

  /**
   * Find register[s] that can be used in function prologue and epilogue
   *
   * Find register[s] that can be use as scratch register[s] in function
   * prologue and epilogue to save various registers (Link Register, Base
   * Pointer, etc.). Prefer R0/R12, if available. Otherwise choose whatever
   * register[s] are available.
   *
   * This method will return true if it is able to find enough unique scratch
   * registers (1 or 2 depending on the requirement). If it is unable to find
   * enough available registers in the block, it will return false and set
   * any passed output parameter that corresponds to a required unique register
   * to PPC::NoRegister.
   *
   * \param[in] MBB The machine basic block to find an available register for
   * \param[in] UseAtEnd Specify whether the scratch register will be used at
   *                     the end of the basic block (i.e., will the scratch
   *                     register kill a register defined in the basic block)
   * \param[in] TwoUniqueRegsRequired Specify whether this basic block will
   *                                  require two unique scratch registers.
   * \param[out] SR1 The scratch register to use
   * \param[out] SR2 The second scratch register. If this pointer is not null
   *                 the function will attempt to set it to an available
   *                 register regardless of whether there is a hard requirement
   *                 for two unique scratch registers.
   * \return true if the required number of registers was found.
   *         false if the required number of scratch register weren't available.
   *         If either output parameter refers to a required scratch register
   *         that isn't available, it will be set to an invalid value.
   */
  bool findScratchRegister(MachineBasicBlock *MBB,
                           bool UseAtEnd,
                           bool TwoUniqueRegsRequired = false,
                           unsigned *SR1 = nullptr,
                           unsigned *SR2 = nullptr) const;
  bool twoUniqueScratchRegsRequired(MachineBasicBlock *MBB) const;

  /**
   * Create branch instruction for PPC::TCRETURN* (tail call return)
   *
   * \param[in] MBB that is terminated by PPC::TCRETURN*
   */
  void createTailCallBranchInstr(MachineBasicBlock &MBB) const;

public:
  PPCFrameLowering(const PPCSubtarget &STI);

  unsigned determineFrameLayout(MachineFunction &MF,
                                bool UpdateMF = true,
                                bool UseEstimate = false) const;

  /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
  /// the function.
  void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
  void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;

  bool hasFP(const MachineFunction &MF) const override;
  bool needsFP(const MachineFunction &MF) const;
  void replaceFPWithRealFP(MachineFunction &MF) const;

  void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
                            RegScavenger *RS = nullptr) const override;
  void processFunctionBeforeFrameFinalized(MachineFunction &MF,
                                     RegScavenger *RS = nullptr) const override;
  void addScavengingSpillSlot(MachineFunction &MF, RegScavenger *RS) const;

  bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
                                 MachineBasicBlock::iterator MI,
                                 const std::vector<CalleeSavedInfo> &CSI,
                                 const TargetRegisterInfo *TRI) const override;

  MachineBasicBlock::iterator
  eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
                                MachineBasicBlock::iterator I) const override;

  bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                  MachineBasicBlock::iterator MI,
                                  std::vector<CalleeSavedInfo> &CSI,
                                  const TargetRegisterInfo *TRI) const override;

  /// targetHandlesStackFrameRounding - Returns true if the target is
  /// responsible for rounding up the stack frame (probably at emitPrologue
  /// time).
  bool targetHandlesStackFrameRounding() const override { return true; }

  /// getReturnSaveOffset - Return the previous frame offset to save the
  /// return address.
  unsigned getReturnSaveOffset() const { return ReturnSaveOffset; }

  /// getTOCSaveOffset - Return the previous frame offset to save the
  /// TOC register -- 64-bit SVR4 ABI only.
  unsigned getTOCSaveOffset() const { return TOCSaveOffset; }

  /// getFramePointerSaveOffset - Return the previous frame offset to save the
  /// frame pointer.
  unsigned getFramePointerSaveOffset() const { return FramePointerSaveOffset; }

  /// getBasePointerSaveOffset - Return the previous frame offset to save the
  /// base pointer.
  unsigned getBasePointerSaveOffset() const { return BasePointerSaveOffset; }

  /// getLinkageSize - Return the size of the PowerPC ABI linkage area.
  ///
  unsigned getLinkageSize() const { return LinkageSize; }

  const SpillSlot *
  getCalleeSavedSpillSlots(unsigned &NumEntries) const override;

  bool enableShrinkWrapping(const MachineFunction &MF) const override;

  /// Methods used by shrink wrapping to determine if MBB can be used for the
  /// function prologue/epilogue.
  bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
  bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override;
};
} // End llvm namespace

#endif