17330f729Sjoerg //==- HexagonFrameLowering.h - Define frame lowering for Hexagon -*- 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 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H 107330f729Sjoerg #define LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H 117330f729Sjoerg 127330f729Sjoerg #include "Hexagon.h" 137330f729Sjoerg #include "HexagonBlockRanges.h" 14*82d56013Sjoerg #include "MCTargetDesc/HexagonMCTargetDesc.h" 157330f729Sjoerg #include "llvm/ADT/STLExtras.h" 167330f729Sjoerg #include "llvm/CodeGen/MachineBasicBlock.h" 177330f729Sjoerg #include "llvm/CodeGen/MachineFrameInfo.h" 187330f729Sjoerg #include "llvm/CodeGen/TargetFrameLowering.h" 197330f729Sjoerg #include <vector> 207330f729Sjoerg 217330f729Sjoerg namespace llvm { 227330f729Sjoerg 237330f729Sjoerg class BitVector; 247330f729Sjoerg class HexagonInstrInfo; 257330f729Sjoerg class HexagonRegisterInfo; 267330f729Sjoerg class MachineFunction; 277330f729Sjoerg class MachineInstr; 287330f729Sjoerg class MachineRegisterInfo; 297330f729Sjoerg class TargetRegisterClass; 307330f729Sjoerg 317330f729Sjoerg class HexagonFrameLowering : public TargetFrameLowering { 327330f729Sjoerg public: 33*82d56013Sjoerg // First register which could possibly hold a variable argument. 34*82d56013Sjoerg int FirstVarArgSavedReg; HexagonFrameLowering()357330f729Sjoerg explicit HexagonFrameLowering() 36*82d56013Sjoerg : TargetFrameLowering(StackGrowsDown, Align(8), 0, Align(1), true) {} 377330f729Sjoerg 387330f729Sjoerg // All of the prolog/epilog functionality, including saving and restoring 397330f729Sjoerg // callee-saved registers is handled in emitPrologue. This is to have the 407330f729Sjoerg // logic for shrink-wrapping in one place. 417330f729Sjoerg void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const 427330f729Sjoerg override; emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB)437330f729Sjoerg void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const 447330f729Sjoerg override {} 457330f729Sjoerg 467330f729Sjoerg bool enableCalleeSaveSkip(const MachineFunction &MF) const override; 477330f729Sjoerg spillCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,ArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI)487330f729Sjoerg bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 49*82d56013Sjoerg MachineBasicBlock::iterator MI, 50*82d56013Sjoerg ArrayRef<CalleeSavedInfo> CSI, 517330f729Sjoerg const TargetRegisterInfo *TRI) const override { 527330f729Sjoerg return true; 537330f729Sjoerg } 547330f729Sjoerg 55*82d56013Sjoerg bool restoreCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,MutableArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI)56*82d56013Sjoerg restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 57*82d56013Sjoerg MachineBasicBlock::iterator MI, 58*82d56013Sjoerg MutableArrayRef<CalleeSavedInfo> CSI, 597330f729Sjoerg const TargetRegisterInfo *TRI) const override { 607330f729Sjoerg return true; 617330f729Sjoerg } 627330f729Sjoerg hasReservedCallFrame(const MachineFunction & MF)637330f729Sjoerg bool hasReservedCallFrame(const MachineFunction &MF) const override { 647330f729Sjoerg // We always reserve call frame as a part of the initial stack allocation. 657330f729Sjoerg return true; 667330f729Sjoerg } 677330f729Sjoerg canSimplifyCallFramePseudos(const MachineFunction & MF)687330f729Sjoerg bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override { 697330f729Sjoerg // Override this function to avoid calling hasFP before CSI is set 707330f729Sjoerg // (the default implementation calls hasFP). 717330f729Sjoerg return true; 727330f729Sjoerg } 737330f729Sjoerg 747330f729Sjoerg MachineBasicBlock::iterator 757330f729Sjoerg eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 767330f729Sjoerg MachineBasicBlock::iterator I) const override; 777330f729Sjoerg void processFunctionBeforeFrameFinalized(MachineFunction &MF, 787330f729Sjoerg RegScavenger *RS = nullptr) const override; 797330f729Sjoerg void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, 807330f729Sjoerg RegScavenger *RS) const override; 817330f729Sjoerg targetHandlesStackFrameRounding()827330f729Sjoerg bool targetHandlesStackFrameRounding() const override { 837330f729Sjoerg return true; 847330f729Sjoerg } 857330f729Sjoerg 86*82d56013Sjoerg StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, 87*82d56013Sjoerg Register &FrameReg) const override; 887330f729Sjoerg bool hasFP(const MachineFunction &MF) const override; 897330f729Sjoerg getCalleeSavedSpillSlots(unsigned & NumEntries)907330f729Sjoerg const SpillSlot *getCalleeSavedSpillSlots(unsigned &NumEntries) 917330f729Sjoerg const override { 927330f729Sjoerg static const SpillSlot Offsets[] = { 937330f729Sjoerg { Hexagon::R17, -4 }, { Hexagon::R16, -8 }, { Hexagon::D8, -8 }, 947330f729Sjoerg { Hexagon::R19, -12 }, { Hexagon::R18, -16 }, { Hexagon::D9, -16 }, 957330f729Sjoerg { Hexagon::R21, -20 }, { Hexagon::R20, -24 }, { Hexagon::D10, -24 }, 967330f729Sjoerg { Hexagon::R23, -28 }, { Hexagon::R22, -32 }, { Hexagon::D11, -32 }, 977330f729Sjoerg { Hexagon::R25, -36 }, { Hexagon::R24, -40 }, { Hexagon::D12, -40 }, 987330f729Sjoerg { Hexagon::R27, -44 }, { Hexagon::R26, -48 }, { Hexagon::D13, -48 } 997330f729Sjoerg }; 1007330f729Sjoerg NumEntries = array_lengthof(Offsets); 1017330f729Sjoerg return Offsets; 1027330f729Sjoerg } 1037330f729Sjoerg 1047330f729Sjoerg bool assignCalleeSavedSpillSlots(MachineFunction &MF, 1057330f729Sjoerg const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI) 1067330f729Sjoerg const override; 1077330f729Sjoerg 1087330f729Sjoerg bool needsAligna(const MachineFunction &MF) const; 1097330f729Sjoerg const MachineInstr *getAlignaInstr(const MachineFunction &MF) const; 1107330f729Sjoerg 1117330f729Sjoerg void insertCFIInstructions(MachineFunction &MF) const; 1127330f729Sjoerg 1137330f729Sjoerg private: 1147330f729Sjoerg using CSIVect = std::vector<CalleeSavedInfo>; 1157330f729Sjoerg 1167330f729Sjoerg void expandAlloca(MachineInstr *AI, const HexagonInstrInfo &TII, 1177330f729Sjoerg unsigned SP, unsigned CF) const; 1187330f729Sjoerg void insertPrologueInBlock(MachineBasicBlock &MBB, bool PrologueStubs) const; 1197330f729Sjoerg void insertEpilogueInBlock(MachineBasicBlock &MBB) const; 1207330f729Sjoerg void insertAllocframe(MachineBasicBlock &MBB, 1217330f729Sjoerg MachineBasicBlock::iterator InsertPt, unsigned NumBytes) const; 1227330f729Sjoerg bool insertCSRSpillsInBlock(MachineBasicBlock &MBB, const CSIVect &CSI, 1237330f729Sjoerg const HexagonRegisterInfo &HRI, bool &PrologueStubs) const; 1247330f729Sjoerg bool insertCSRRestoresInBlock(MachineBasicBlock &MBB, const CSIVect &CSI, 1257330f729Sjoerg const HexagonRegisterInfo &HRI) const; 1267330f729Sjoerg void updateEntryPaths(MachineFunction &MF, MachineBasicBlock &SaveB) const; 1277330f729Sjoerg bool updateExitPaths(MachineBasicBlock &MBB, MachineBasicBlock &RestoreB, 1287330f729Sjoerg BitVector &DoneT, BitVector &DoneF, BitVector &Path) const; 1297330f729Sjoerg void insertCFIInstructionsAt(MachineBasicBlock &MBB, 1307330f729Sjoerg MachineBasicBlock::iterator At) const; 1317330f729Sjoerg 1327330f729Sjoerg void adjustForCalleeSavedRegsSpillCall(MachineFunction &MF) const; 1337330f729Sjoerg 1347330f729Sjoerg bool expandCopy(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1357330f729Sjoerg MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 1367330f729Sjoerg SmallVectorImpl<unsigned> &NewRegs) const; 1377330f729Sjoerg bool expandStoreInt(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1387330f729Sjoerg MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 1397330f729Sjoerg SmallVectorImpl<unsigned> &NewRegs) const; 1407330f729Sjoerg bool expandLoadInt(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1417330f729Sjoerg MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 1427330f729Sjoerg SmallVectorImpl<unsigned> &NewRegs) const; 1437330f729Sjoerg bool expandStoreVecPred(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1447330f729Sjoerg MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 1457330f729Sjoerg SmallVectorImpl<unsigned> &NewRegs) const; 1467330f729Sjoerg bool expandLoadVecPred(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1477330f729Sjoerg MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 1487330f729Sjoerg SmallVectorImpl<unsigned> &NewRegs) const; 1497330f729Sjoerg bool expandStoreVec2(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1507330f729Sjoerg MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 1517330f729Sjoerg SmallVectorImpl<unsigned> &NewRegs) const; 1527330f729Sjoerg bool expandLoadVec2(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1537330f729Sjoerg MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 1547330f729Sjoerg SmallVectorImpl<unsigned> &NewRegs) const; 1557330f729Sjoerg bool expandStoreVec(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1567330f729Sjoerg MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 1577330f729Sjoerg SmallVectorImpl<unsigned> &NewRegs) const; 1587330f729Sjoerg bool expandLoadVec(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1597330f729Sjoerg MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 1607330f729Sjoerg SmallVectorImpl<unsigned> &NewRegs) const; 1617330f729Sjoerg bool expandSpillMacros(MachineFunction &MF, 1627330f729Sjoerg SmallVectorImpl<unsigned> &NewRegs) const; 1637330f729Sjoerg 1647330f729Sjoerg unsigned findPhysReg(MachineFunction &MF, HexagonBlockRanges::IndexRange &FIR, 1657330f729Sjoerg HexagonBlockRanges::InstrIndexMap &IndexMap, 1667330f729Sjoerg HexagonBlockRanges::RegToRangeMap &DeadMap, 1677330f729Sjoerg const TargetRegisterClass *RC) const; 1687330f729Sjoerg void optimizeSpillSlots(MachineFunction &MF, 1697330f729Sjoerg SmallVectorImpl<unsigned> &VRegs) const; 1707330f729Sjoerg 1717330f729Sjoerg void findShrunkPrologEpilog(MachineFunction &MF, MachineBasicBlock *&PrologB, 1727330f729Sjoerg MachineBasicBlock *&EpilogB) const; 1737330f729Sjoerg 1747330f729Sjoerg void addCalleeSaveRegistersAsImpOperand(MachineInstr *MI, const CSIVect &CSI, 1757330f729Sjoerg bool IsDef, bool IsKill) const; 1767330f729Sjoerg bool shouldInlineCSR(const MachineFunction &MF, const CSIVect &CSI) const; 1777330f729Sjoerg bool useSpillFunction(const MachineFunction &MF, const CSIVect &CSI) const; 1787330f729Sjoerg bool useRestoreFunction(const MachineFunction &MF, const CSIVect &CSI) const; 1797330f729Sjoerg bool mayOverflowFrameOffset(MachineFunction &MF) const; 1807330f729Sjoerg }; 1817330f729Sjoerg 1827330f729Sjoerg } // end namespace llvm 1837330f729Sjoerg 1847330f729Sjoerg #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H 185