xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/Target/PowerPC/PPCFrameLowering.h (revision 82d56013d7b633d116a93943de88e08335357a7c)
17330f729Sjoerg //===-- PPCFrameLowering.h - Define frame lowering for PowerPC --*- C++ -*-===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg //
107330f729Sjoerg //===----------------------------------------------------------------------===//
117330f729Sjoerg 
127330f729Sjoerg #ifndef LLVM_LIB_TARGET_POWERPC_PPCFRAMELOWERING_H
137330f729Sjoerg #define LLVM_LIB_TARGET_POWERPC_PPCFRAMELOWERING_H
147330f729Sjoerg 
157330f729Sjoerg #include "llvm/ADT/STLExtras.h"
167330f729Sjoerg #include "llvm/CodeGen/TargetFrameLowering.h"
177330f729Sjoerg #include "llvm/Target/TargetMachine.h"
187330f729Sjoerg 
197330f729Sjoerg namespace llvm {
207330f729Sjoerg class PPCSubtarget;
217330f729Sjoerg 
227330f729Sjoerg class PPCFrameLowering: public TargetFrameLowering {
237330f729Sjoerg   const PPCSubtarget &Subtarget;
247330f729Sjoerg   const unsigned ReturnSaveOffset;
257330f729Sjoerg   const unsigned TOCSaveOffset;
267330f729Sjoerg   const unsigned FramePointerSaveOffset;
277330f729Sjoerg   const unsigned LinkageSize;
287330f729Sjoerg   const unsigned BasePointerSaveOffset;
297330f729Sjoerg   const unsigned CRSaveOffset;
307330f729Sjoerg 
31*82d56013Sjoerg   // Map each group of one or two GPRs to corresponding VSR for spilling.
32*82d56013Sjoerg   // TODO: Use local table in methods to avoid this mutable member.
33*82d56013Sjoerg   mutable DenseMap<unsigned, std::pair<Register, Register>> VSRContainingGPRs;
34*82d56013Sjoerg 
357330f729Sjoerg   /**
367330f729Sjoerg    * Find register[s] that can be used in function prologue and epilogue
377330f729Sjoerg    *
387330f729Sjoerg    * Find register[s] that can be use as scratch register[s] in function
397330f729Sjoerg    * prologue and epilogue to save various registers (Link Register, Base
407330f729Sjoerg    * Pointer, etc.). Prefer R0/R12, if available. Otherwise choose whatever
417330f729Sjoerg    * register[s] are available.
427330f729Sjoerg    *
437330f729Sjoerg    * This method will return true if it is able to find enough unique scratch
447330f729Sjoerg    * registers (1 or 2 depending on the requirement). If it is unable to find
457330f729Sjoerg    * enough available registers in the block, it will return false and set
467330f729Sjoerg    * any passed output parameter that corresponds to a required unique register
477330f729Sjoerg    * to PPC::NoRegister.
487330f729Sjoerg    *
497330f729Sjoerg    * \param[in] MBB The machine basic block to find an available register for
507330f729Sjoerg    * \param[in] UseAtEnd Specify whether the scratch register will be used at
517330f729Sjoerg    *                     the end of the basic block (i.e., will the scratch
527330f729Sjoerg    *                     register kill a register defined in the basic block)
537330f729Sjoerg    * \param[in] TwoUniqueRegsRequired Specify whether this basic block will
547330f729Sjoerg    *                                  require two unique scratch registers.
557330f729Sjoerg    * \param[out] SR1 The scratch register to use
567330f729Sjoerg    * \param[out] SR2 The second scratch register. If this pointer is not null
577330f729Sjoerg    *                 the function will attempt to set it to an available
587330f729Sjoerg    *                 register regardless of whether there is a hard requirement
597330f729Sjoerg    *                 for two unique scratch registers.
607330f729Sjoerg    * \return true if the required number of registers was found.
617330f729Sjoerg    *         false if the required number of scratch register weren't available.
627330f729Sjoerg    *         If either output parameter refers to a required scratch register
637330f729Sjoerg    *         that isn't available, it will be set to an invalid value.
647330f729Sjoerg    */
657330f729Sjoerg   bool findScratchRegister(MachineBasicBlock *MBB,
667330f729Sjoerg                            bool UseAtEnd,
677330f729Sjoerg                            bool TwoUniqueRegsRequired = false,
68*82d56013Sjoerg                            Register *SR1 = nullptr,
69*82d56013Sjoerg                            Register *SR2 = nullptr) const;
707330f729Sjoerg   bool twoUniqueScratchRegsRequired(MachineBasicBlock *MBB) const;
717330f729Sjoerg 
727330f729Sjoerg   /**
737330f729Sjoerg    * Create branch instruction for PPC::TCRETURN* (tail call return)
747330f729Sjoerg    *
757330f729Sjoerg    * \param[in] MBB that is terminated by PPC::TCRETURN*
767330f729Sjoerg    */
777330f729Sjoerg   void createTailCallBranchInstr(MachineBasicBlock &MBB) const;
787330f729Sjoerg 
797330f729Sjoerg   /**
807330f729Sjoerg     * Check if the conditions are correct to allow for the stack update
817330f729Sjoerg     * to be moved past the CSR save/restore code.
827330f729Sjoerg     */
837330f729Sjoerg   bool stackUpdateCanBeMoved(MachineFunction &MF) const;
847330f729Sjoerg 
857330f729Sjoerg public:
867330f729Sjoerg   PPCFrameLowering(const PPCSubtarget &STI);
877330f729Sjoerg 
887330f729Sjoerg   /**
897330f729Sjoerg    * Determine the frame layout and update the machine function.
907330f729Sjoerg    */
917330f729Sjoerg   unsigned determineFrameLayoutAndUpdate(MachineFunction &MF,
927330f729Sjoerg                                          bool UseEstimate = false) const;
937330f729Sjoerg 
947330f729Sjoerg   /**
957330f729Sjoerg    * Determine the frame layout but do not update the machine function.
967330f729Sjoerg    * The MachineFunction object can be const in this case as it is not
977330f729Sjoerg    * modified.
987330f729Sjoerg    */
997330f729Sjoerg   unsigned determineFrameLayout(const MachineFunction &MF,
1007330f729Sjoerg                                 bool UseEstimate = false,
1017330f729Sjoerg                                 unsigned *NewMaxCallFrameSize = nullptr) const;
1027330f729Sjoerg 
1037330f729Sjoerg   /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
1047330f729Sjoerg   /// the function.
1057330f729Sjoerg   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
1067330f729Sjoerg   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
107*82d56013Sjoerg   void inlineStackProbe(MachineFunction &MF,
108*82d56013Sjoerg                         MachineBasicBlock &PrologMBB) const override;
1097330f729Sjoerg 
1107330f729Sjoerg   bool hasFP(const MachineFunction &MF) const override;
1117330f729Sjoerg   bool needsFP(const MachineFunction &MF) const;
1127330f729Sjoerg   void replaceFPWithRealFP(MachineFunction &MF) const;
1137330f729Sjoerg 
1147330f729Sjoerg   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
1157330f729Sjoerg                             RegScavenger *RS = nullptr) const override;
1167330f729Sjoerg   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
1177330f729Sjoerg                                      RegScavenger *RS = nullptr) const override;
1187330f729Sjoerg   void addScavengingSpillSlot(MachineFunction &MF, RegScavenger *RS) const;
1197330f729Sjoerg 
1207330f729Sjoerg   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
1217330f729Sjoerg                                  MachineBasicBlock::iterator MI,
122*82d56013Sjoerg                                  ArrayRef<CalleeSavedInfo> CSI,
1237330f729Sjoerg                                  const TargetRegisterInfo *TRI) const override;
1247330f729Sjoerg   /// This function will assign callee saved gprs to volatile vector registers
1257330f729Sjoerg   /// for prologue spills when applicable. It returns false if there are any
1267330f729Sjoerg   /// registers which were not spilled to volatile vector registers.
1277330f729Sjoerg   bool
1287330f729Sjoerg   assignCalleeSavedSpillSlots(MachineFunction &MF,
1297330f729Sjoerg                               const TargetRegisterInfo *TRI,
1307330f729Sjoerg                               std::vector<CalleeSavedInfo> &CSI) const override;
1317330f729Sjoerg 
1327330f729Sjoerg   MachineBasicBlock::iterator
1337330f729Sjoerg   eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
1347330f729Sjoerg                                 MachineBasicBlock::iterator I) const override;
1357330f729Sjoerg 
136*82d56013Sjoerg   bool
137*82d56013Sjoerg   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
1387330f729Sjoerg                               MachineBasicBlock::iterator MI,
139*82d56013Sjoerg                               MutableArrayRef<CalleeSavedInfo> CSI,
1407330f729Sjoerg                               const TargetRegisterInfo *TRI) const override;
1417330f729Sjoerg 
1427330f729Sjoerg   /// targetHandlesStackFrameRounding - Returns true if the target is
1437330f729Sjoerg   /// responsible for rounding up the stack frame (probably at emitPrologue
1447330f729Sjoerg   /// time).
targetHandlesStackFrameRounding()1457330f729Sjoerg   bool targetHandlesStackFrameRounding() const override { return true; }
1467330f729Sjoerg 
1477330f729Sjoerg   /// getReturnSaveOffset - Return the previous frame offset to save the
1487330f729Sjoerg   /// return address.
getReturnSaveOffset()1497330f729Sjoerg   unsigned getReturnSaveOffset() const { return ReturnSaveOffset; }
1507330f729Sjoerg 
1517330f729Sjoerg   /// getTOCSaveOffset - Return the previous frame offset to save the
1527330f729Sjoerg   /// TOC register -- 64-bit SVR4 ABI only.
1537330f729Sjoerg   unsigned getTOCSaveOffset() const;
1547330f729Sjoerg 
1557330f729Sjoerg   /// getFramePointerSaveOffset - Return the previous frame offset to save the
1567330f729Sjoerg   /// frame pointer.
1577330f729Sjoerg   unsigned getFramePointerSaveOffset() const;
1587330f729Sjoerg 
1597330f729Sjoerg   /// getBasePointerSaveOffset - Return the previous frame offset to save the
1607330f729Sjoerg   /// base pointer.
1617330f729Sjoerg   unsigned getBasePointerSaveOffset() const;
1627330f729Sjoerg 
1637330f729Sjoerg   /// getLinkageSize - Return the size of the PowerPC ABI linkage area.
1647330f729Sjoerg   ///
getLinkageSize()1657330f729Sjoerg   unsigned getLinkageSize() const { return LinkageSize; }
1667330f729Sjoerg 
1677330f729Sjoerg   const SpillSlot *
1687330f729Sjoerg   getCalleeSavedSpillSlots(unsigned &NumEntries) const override;
1697330f729Sjoerg 
1707330f729Sjoerg   bool enableShrinkWrapping(const MachineFunction &MF) const override;
1717330f729Sjoerg 
1727330f729Sjoerg   /// Methods used by shrink wrapping to determine if MBB can be used for the
1737330f729Sjoerg   /// function prologue/epilogue.
1747330f729Sjoerg   bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
1757330f729Sjoerg   bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override;
1767330f729Sjoerg };
1777330f729Sjoerg } // End llvm namespace
1787330f729Sjoerg 
1797330f729Sjoerg #endif
180