xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- ARMTargetFrameLowering.h - Define frame lowering for ARM -*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_ARM_ARMFRAMELOWERING_H
100b57cec5SDimitry Andric #define LLVM_LIB_TARGET_ARM_ARMFRAMELOWERING_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
13e8d8bef9SDimitry Andric #include "llvm/Support/TypeSize.h"
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric namespace llvm {
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric class ARMSubtarget;
180b57cec5SDimitry Andric class CalleeSavedInfo;
190b57cec5SDimitry Andric class MachineFunction;
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric class ARMFrameLowering : public TargetFrameLowering {
220b57cec5SDimitry Andric protected:
230b57cec5SDimitry Andric   const ARMSubtarget &STI;
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric public:
260b57cec5SDimitry Andric   explicit ARMFrameLowering(const ARMSubtarget &sti);
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric   /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
290b57cec5SDimitry Andric   /// the function.
300b57cec5SDimitry Andric   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
310b57cec5SDimitry Andric   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
340b57cec5SDimitry Andric                                  MachineBasicBlock::iterator MI,
355ffd83dbSDimitry Andric                                  ArrayRef<CalleeSavedInfo> CSI,
360b57cec5SDimitry Andric                                  const TargetRegisterInfo *TRI) const override;
370b57cec5SDimitry Andric 
385ffd83dbSDimitry Andric   bool
395ffd83dbSDimitry Andric   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
400b57cec5SDimitry Andric                               MachineBasicBlock::iterator MI,
415ffd83dbSDimitry Andric                               MutableArrayRef<CalleeSavedInfo> CSI,
420b57cec5SDimitry Andric                               const TargetRegisterInfo *TRI) const override;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   bool keepFramePointer(const MachineFunction &MF) const override;
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric   bool enableCalleeSaveSkip(const MachineFunction &MF) const override;
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   bool hasFP(const MachineFunction &MF) const override;
4981ad6265SDimitry Andric   bool isFPReserved(const MachineFunction &MF) const;
50*0fca6ea1SDimitry Andric   bool requiresAAPCSFrameRecord(const MachineFunction &MF) const;
510b57cec5SDimitry Andric   bool hasReservedCallFrame(const MachineFunction &MF) const override;
520b57cec5SDimitry Andric   bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;
53e8d8bef9SDimitry Andric   StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
545ffd83dbSDimitry Andric                                      Register &FrameReg) const override;
550b57cec5SDimitry Andric   int ResolveFrameIndexReference(const MachineFunction &MF, int FI,
565ffd83dbSDimitry Andric                                  Register &FrameReg, int SPAdj) const;
570b57cec5SDimitry Andric 
58480093f4SDimitry Andric   void getCalleeSaves(const MachineFunction &MF,
59480093f4SDimitry Andric                       BitVector &SavedRegs) const override;
600b57cec5SDimitry Andric   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
610b57cec5SDimitry Andric                             RegScavenger *RS) const override;
620b57cec5SDimitry Andric 
63439352acSDimitry Andric   /// Update the IsRestored flag on LR if it is spilled, based on the return
64439352acSDimitry Andric   /// instructions.
65439352acSDimitry Andric   static void updateLRRestored(MachineFunction &MF);
66439352acSDimitry Andric 
67cb14a3feSDimitry Andric   void processFunctionBeforeFrameFinalized(
68cb14a3feSDimitry Andric       MachineFunction &MF, RegScavenger *RS = nullptr) const override;
69cb14a3feSDimitry Andric 
700b57cec5SDimitry Andric   void adjustForSegmentedStacks(MachineFunction &MF,
710b57cec5SDimitry Andric                                 MachineBasicBlock &MBB) const override;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   /// Returns true if the target will correctly handle shrink wrapping.
745ffd83dbSDimitry Andric   bool enableShrinkWrapping(const MachineFunction &MF) const override;
755ffd83dbSDimitry Andric 
768bcb0991SDimitry Andric   bool isProfitableForNoCSROpt(const Function &F) const override {
778bcb0991SDimitry Andric     // The no-CSR optimisation is bad for code size on ARM, because we can save
788bcb0991SDimitry Andric     // many registers with a single PUSH/POP pair.
798bcb0991SDimitry Andric     return false;
808bcb0991SDimitry Andric   }
810b57cec5SDimitry Andric 
825ffd83dbSDimitry Andric   bool
835ffd83dbSDimitry Andric   assignCalleeSavedSpillSlots(MachineFunction &MF,
845ffd83dbSDimitry Andric                               const TargetRegisterInfo *TRI,
855ffd83dbSDimitry Andric                               std::vector<CalleeSavedInfo> &CSI) const override;
865ffd83dbSDimitry Andric 
875ffd83dbSDimitry Andric   const SpillSlot *
885ffd83dbSDimitry Andric   getCalleeSavedSpillSlots(unsigned &NumEntries) const override;
895ffd83dbSDimitry Andric 
900b57cec5SDimitry Andric private:
910b57cec5SDimitry Andric   void emitPushInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
925ffd83dbSDimitry Andric                     ArrayRef<CalleeSavedInfo> CSI, unsigned StmOpc,
935ffd83dbSDimitry Andric                     unsigned StrOpc, bool NoGap, bool (*Func)(unsigned, bool),
945ffd83dbSDimitry Andric                     unsigned NumAlignedDPRCS2Regs, unsigned MIFlags = 0) const;
950b57cec5SDimitry Andric   void emitPopInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
965ffd83dbSDimitry Andric                    MutableArrayRef<CalleeSavedInfo> CSI, unsigned LdmOpc,
970b57cec5SDimitry Andric                    unsigned LdrOpc, bool isVarArg, bool NoGap,
980b57cec5SDimitry Andric                    bool (*Func)(unsigned, bool),
990b57cec5SDimitry Andric                    unsigned NumAlignedDPRCS2Regs) const;
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   MachineBasicBlock::iterator
1020b57cec5SDimitry Andric   eliminateCallFramePseudoInstr(MachineFunction &MF,
1030b57cec5SDimitry Andric                                 MachineBasicBlock &MBB,
1040b57cec5SDimitry Andric                                 MachineBasicBlock::iterator MI) const override;
1050b57cec5SDimitry Andric };
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric } // end namespace llvm
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_ARM_ARMFRAMELOWERING_H
110