10b57cec5SDimitry Andric //==- HexagonFrameLowering.h - Define frame lowering for Hexagon -*- 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_HEXAGON_HEXAGONFRAMELOWERING_H 100b57cec5SDimitry Andric #define LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "Hexagon.h" 130b57cec5SDimitry Andric #include "HexagonBlockRanges.h" 14e8d8bef9SDimitry Andric #include "MCTargetDesc/HexagonMCTargetDesc.h" 150b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h" 190b57cec5SDimitry Andric #include <vector> 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace llvm { 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric class BitVector; 240b57cec5SDimitry Andric class HexagonInstrInfo; 250b57cec5SDimitry Andric class HexagonRegisterInfo; 260b57cec5SDimitry Andric class MachineFunction; 270b57cec5SDimitry Andric class MachineInstr; 280b57cec5SDimitry Andric class MachineRegisterInfo; 290b57cec5SDimitry Andric class TargetRegisterClass; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric class HexagonFrameLowering : public TargetFrameLowering { 320b57cec5SDimitry Andric public: 335ffd83dbSDimitry Andric // First register which could possibly hold a variable argument. 345ffd83dbSDimitry Andric int FirstVarArgSavedReg; 350b57cec5SDimitry Andric explicit HexagonFrameLowering() 365ffd83dbSDimitry Andric : TargetFrameLowering(StackGrowsDown, Align(8), 0, Align(1), true) {} 370b57cec5SDimitry Andric 38*0fca6ea1SDimitry Andric void 39*0fca6ea1SDimitry Andric orderFrameObjects(const MachineFunction &MF, 40*0fca6ea1SDimitry Andric SmallVectorImpl<int> &ObjectsToAllocate) const override; 41*0fca6ea1SDimitry Andric 420b57cec5SDimitry Andric // All of the prolog/epilog functionality, including saving and restoring 430b57cec5SDimitry Andric // callee-saved registers is handled in emitPrologue. This is to have the 440b57cec5SDimitry Andric // logic for shrink-wrapping in one place. 450b57cec5SDimitry Andric void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const 460b57cec5SDimitry Andric override; 470b57cec5SDimitry Andric void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const 480b57cec5SDimitry Andric override {} 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric bool enableCalleeSaveSkip(const MachineFunction &MF) const override; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 535ffd83dbSDimitry Andric MachineBasicBlock::iterator MI, 545ffd83dbSDimitry Andric ArrayRef<CalleeSavedInfo> CSI, 550b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override { 560b57cec5SDimitry Andric return true; 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric 595ffd83dbSDimitry Andric bool 605ffd83dbSDimitry Andric restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 615ffd83dbSDimitry Andric MachineBasicBlock::iterator MI, 625ffd83dbSDimitry Andric MutableArrayRef<CalleeSavedInfo> CSI, 630b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override { 640b57cec5SDimitry Andric return true; 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric bool hasReservedCallFrame(const MachineFunction &MF) const override { 680b57cec5SDimitry Andric // We always reserve call frame as a part of the initial stack allocation. 690b57cec5SDimitry Andric return true; 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override { 730b57cec5SDimitry Andric // Override this function to avoid calling hasFP before CSI is set 740b57cec5SDimitry Andric // (the default implementation calls hasFP). 750b57cec5SDimitry Andric return true; 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric MachineBasicBlock::iterator 790b57cec5SDimitry Andric eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 800b57cec5SDimitry Andric MachineBasicBlock::iterator I) const override; 810b57cec5SDimitry Andric void processFunctionBeforeFrameFinalized(MachineFunction &MF, 820b57cec5SDimitry Andric RegScavenger *RS = nullptr) const override; 830b57cec5SDimitry Andric void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, 840b57cec5SDimitry Andric RegScavenger *RS) const override; 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric bool targetHandlesStackFrameRounding() const override { 870b57cec5SDimitry Andric return true; 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 90e8d8bef9SDimitry Andric StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, 915ffd83dbSDimitry Andric Register &FrameReg) const override; 920b57cec5SDimitry Andric bool hasFP(const MachineFunction &MF) const override; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric const SpillSlot *getCalleeSavedSpillSlots(unsigned &NumEntries) 950b57cec5SDimitry Andric const override { 960b57cec5SDimitry Andric static const SpillSlot Offsets[] = { 970b57cec5SDimitry Andric { Hexagon::R17, -4 }, { Hexagon::R16, -8 }, { Hexagon::D8, -8 }, 980b57cec5SDimitry Andric { Hexagon::R19, -12 }, { Hexagon::R18, -16 }, { Hexagon::D9, -16 }, 990b57cec5SDimitry Andric { Hexagon::R21, -20 }, { Hexagon::R20, -24 }, { Hexagon::D10, -24 }, 1000b57cec5SDimitry Andric { Hexagon::R23, -28 }, { Hexagon::R22, -32 }, { Hexagon::D11, -32 }, 1010b57cec5SDimitry Andric { Hexagon::R25, -36 }, { Hexagon::R24, -40 }, { Hexagon::D12, -40 }, 1020b57cec5SDimitry Andric { Hexagon::R27, -44 }, { Hexagon::R26, -48 }, { Hexagon::D13, -48 } 1030b57cec5SDimitry Andric }; 104bdd1243dSDimitry Andric NumEntries = std::size(Offsets); 1050b57cec5SDimitry Andric return Offsets; 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric bool assignCalleeSavedSpillSlots(MachineFunction &MF, 1090b57cec5SDimitry Andric const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI) 1100b57cec5SDimitry Andric const override; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric bool needsAligna(const MachineFunction &MF) const; 1130b57cec5SDimitry Andric const MachineInstr *getAlignaInstr(const MachineFunction &MF) const; 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric void insertCFIInstructions(MachineFunction &MF) const; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric private: 1180b57cec5SDimitry Andric using CSIVect = std::vector<CalleeSavedInfo>; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric void expandAlloca(MachineInstr *AI, const HexagonInstrInfo &TII, 121bdd1243dSDimitry Andric Register SP, unsigned CF) const; 1220b57cec5SDimitry Andric void insertPrologueInBlock(MachineBasicBlock &MBB, bool PrologueStubs) const; 1230b57cec5SDimitry Andric void insertEpilogueInBlock(MachineBasicBlock &MBB) const; 1240b57cec5SDimitry Andric void insertAllocframe(MachineBasicBlock &MBB, 1250b57cec5SDimitry Andric MachineBasicBlock::iterator InsertPt, unsigned NumBytes) const; 1260b57cec5SDimitry Andric bool insertCSRSpillsInBlock(MachineBasicBlock &MBB, const CSIVect &CSI, 1270b57cec5SDimitry Andric const HexagonRegisterInfo &HRI, bool &PrologueStubs) const; 1280b57cec5SDimitry Andric bool insertCSRRestoresInBlock(MachineBasicBlock &MBB, const CSIVect &CSI, 1290b57cec5SDimitry Andric const HexagonRegisterInfo &HRI) const; 1300b57cec5SDimitry Andric void updateEntryPaths(MachineFunction &MF, MachineBasicBlock &SaveB) const; 1310b57cec5SDimitry Andric bool updateExitPaths(MachineBasicBlock &MBB, MachineBasicBlock &RestoreB, 1320b57cec5SDimitry Andric BitVector &DoneT, BitVector &DoneF, BitVector &Path) const; 1330b57cec5SDimitry Andric void insertCFIInstructionsAt(MachineBasicBlock &MBB, 1340b57cec5SDimitry Andric MachineBasicBlock::iterator At) const; 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric bool expandCopy(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1370b57cec5SDimitry Andric MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 138bdd1243dSDimitry Andric SmallVectorImpl<Register> &NewRegs) const; 1390b57cec5SDimitry Andric bool expandStoreInt(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1400b57cec5SDimitry Andric MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 141bdd1243dSDimitry Andric SmallVectorImpl<Register> &NewRegs) const; 1420b57cec5SDimitry Andric bool expandLoadInt(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1430b57cec5SDimitry Andric MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 144bdd1243dSDimitry Andric SmallVectorImpl<Register> &NewRegs) const; 1450b57cec5SDimitry Andric bool expandStoreVecPred(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1460b57cec5SDimitry Andric MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 147bdd1243dSDimitry Andric SmallVectorImpl<Register> &NewRegs) const; 1480b57cec5SDimitry Andric bool expandLoadVecPred(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1490b57cec5SDimitry Andric MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 150bdd1243dSDimitry Andric SmallVectorImpl<Register> &NewRegs) const; 1510b57cec5SDimitry Andric bool expandStoreVec2(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1520b57cec5SDimitry Andric MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 153bdd1243dSDimitry Andric SmallVectorImpl<Register> &NewRegs) const; 1540b57cec5SDimitry Andric bool expandLoadVec2(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1550b57cec5SDimitry Andric MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 156bdd1243dSDimitry Andric SmallVectorImpl<Register> &NewRegs) const; 1570b57cec5SDimitry Andric bool expandStoreVec(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1580b57cec5SDimitry Andric MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 159bdd1243dSDimitry Andric SmallVectorImpl<Register> &NewRegs) const; 1600b57cec5SDimitry Andric bool expandLoadVec(MachineBasicBlock &B, MachineBasicBlock::iterator It, 1610b57cec5SDimitry Andric MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 162bdd1243dSDimitry Andric SmallVectorImpl<Register> &NewRegs) const; 1630b57cec5SDimitry Andric bool expandSpillMacros(MachineFunction &MF, 164bdd1243dSDimitry Andric SmallVectorImpl<Register> &NewRegs) const; 1650b57cec5SDimitry Andric 166bdd1243dSDimitry Andric Register findPhysReg(MachineFunction &MF, HexagonBlockRanges::IndexRange &FIR, 1670b57cec5SDimitry Andric HexagonBlockRanges::InstrIndexMap &IndexMap, 1680b57cec5SDimitry Andric HexagonBlockRanges::RegToRangeMap &DeadMap, 1690b57cec5SDimitry Andric const TargetRegisterClass *RC) const; 1700b57cec5SDimitry Andric void optimizeSpillSlots(MachineFunction &MF, 171bdd1243dSDimitry Andric SmallVectorImpl<Register> &VRegs) const; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric void findShrunkPrologEpilog(MachineFunction &MF, MachineBasicBlock *&PrologB, 1740b57cec5SDimitry Andric MachineBasicBlock *&EpilogB) const; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric void addCalleeSaveRegistersAsImpOperand(MachineInstr *MI, const CSIVect &CSI, 1770b57cec5SDimitry Andric bool IsDef, bool IsKill) const; 1780b57cec5SDimitry Andric bool shouldInlineCSR(const MachineFunction &MF, const CSIVect &CSI) const; 1790b57cec5SDimitry Andric bool useSpillFunction(const MachineFunction &MF, const CSIVect &CSI) const; 1800b57cec5SDimitry Andric bool useRestoreFunction(const MachineFunction &MF, const CSIVect &CSI) const; 1810b57cec5SDimitry Andric bool mayOverflowFrameOffset(MachineFunction &MF) const; 1820b57cec5SDimitry Andric }; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric } // end namespace llvm 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H 187