1 //==- HexagonFrameLowering.h - Define frame lowering for Hexagon -*- C++ -*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H 10 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H 11 12 #include "Hexagon.h" 13 #include "HexagonBlockRanges.h" 14 #include "llvm/ADT/STLExtras.h" 15 #include "llvm/CodeGen/MachineBasicBlock.h" 16 #include "llvm/CodeGen/MachineFrameInfo.h" 17 #include "llvm/CodeGen/TargetFrameLowering.h" 18 #include <vector> 19 20 namespace llvm { 21 22 class BitVector; 23 class HexagonInstrInfo; 24 class HexagonRegisterInfo; 25 class MachineFunction; 26 class MachineInstr; 27 class MachineRegisterInfo; 28 class TargetRegisterClass; 29 30 class HexagonFrameLowering : public TargetFrameLowering { 31 public: 32 // First register which could possibly hold a variable argument. 33 int FirstVarArgSavedReg; 34 explicit HexagonFrameLowering() 35 : TargetFrameLowering(StackGrowsDown, Align(8), 0, Align(1), true) {} 36 37 // All of the prolog/epilog functionality, including saving and restoring 38 // callee-saved registers is handled in emitPrologue. This is to have the 39 // logic for shrink-wrapping in one place. 40 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const 41 override; 42 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const 43 override {} 44 45 bool enableCalleeSaveSkip(const MachineFunction &MF) const override; 46 47 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 48 MachineBasicBlock::iterator MI, 49 ArrayRef<CalleeSavedInfo> CSI, 50 const TargetRegisterInfo *TRI) const override { 51 return true; 52 } 53 54 bool 55 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 56 MachineBasicBlock::iterator MI, 57 MutableArrayRef<CalleeSavedInfo> CSI, 58 const TargetRegisterInfo *TRI) const override { 59 return true; 60 } 61 62 bool hasReservedCallFrame(const MachineFunction &MF) const override { 63 // We always reserve call frame as a part of the initial stack allocation. 64 return true; 65 } 66 67 bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override { 68 // Override this function to avoid calling hasFP before CSI is set 69 // (the default implementation calls hasFP). 70 return true; 71 } 72 73 MachineBasicBlock::iterator 74 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 75 MachineBasicBlock::iterator I) const override; 76 void processFunctionBeforeFrameFinalized(MachineFunction &MF, 77 RegScavenger *RS = nullptr) const override; 78 void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, 79 RegScavenger *RS) const override; 80 81 bool targetHandlesStackFrameRounding() const override { 82 return true; 83 } 84 85 int getFrameIndexReference(const MachineFunction &MF, int FI, 86 Register &FrameReg) const override; 87 bool hasFP(const MachineFunction &MF) const override; 88 89 const SpillSlot *getCalleeSavedSpillSlots(unsigned &NumEntries) 90 const override { 91 static const SpillSlot Offsets[] = { 92 { Hexagon::R17, -4 }, { Hexagon::R16, -8 }, { Hexagon::D8, -8 }, 93 { Hexagon::R19, -12 }, { Hexagon::R18, -16 }, { Hexagon::D9, -16 }, 94 { Hexagon::R21, -20 }, { Hexagon::R20, -24 }, { Hexagon::D10, -24 }, 95 { Hexagon::R23, -28 }, { Hexagon::R22, -32 }, { Hexagon::D11, -32 }, 96 { Hexagon::R25, -36 }, { Hexagon::R24, -40 }, { Hexagon::D12, -40 }, 97 { Hexagon::R27, -44 }, { Hexagon::R26, -48 }, { Hexagon::D13, -48 } 98 }; 99 NumEntries = array_lengthof(Offsets); 100 return Offsets; 101 } 102 103 bool assignCalleeSavedSpillSlots(MachineFunction &MF, 104 const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI) 105 const override; 106 107 bool needsAligna(const MachineFunction &MF) const; 108 const MachineInstr *getAlignaInstr(const MachineFunction &MF) const; 109 110 void insertCFIInstructions(MachineFunction &MF) const; 111 112 private: 113 using CSIVect = std::vector<CalleeSavedInfo>; 114 115 void expandAlloca(MachineInstr *AI, const HexagonInstrInfo &TII, 116 unsigned SP, unsigned CF) const; 117 void insertPrologueInBlock(MachineBasicBlock &MBB, bool PrologueStubs) const; 118 void insertEpilogueInBlock(MachineBasicBlock &MBB) const; 119 void insertAllocframe(MachineBasicBlock &MBB, 120 MachineBasicBlock::iterator InsertPt, unsigned NumBytes) const; 121 bool insertCSRSpillsInBlock(MachineBasicBlock &MBB, const CSIVect &CSI, 122 const HexagonRegisterInfo &HRI, bool &PrologueStubs) const; 123 bool insertCSRRestoresInBlock(MachineBasicBlock &MBB, const CSIVect &CSI, 124 const HexagonRegisterInfo &HRI) const; 125 void updateEntryPaths(MachineFunction &MF, MachineBasicBlock &SaveB) const; 126 bool updateExitPaths(MachineBasicBlock &MBB, MachineBasicBlock &RestoreB, 127 BitVector &DoneT, BitVector &DoneF, BitVector &Path) const; 128 void insertCFIInstructionsAt(MachineBasicBlock &MBB, 129 MachineBasicBlock::iterator At) const; 130 131 void adjustForCalleeSavedRegsSpillCall(MachineFunction &MF) const; 132 133 bool expandCopy(MachineBasicBlock &B, MachineBasicBlock::iterator It, 134 MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 135 SmallVectorImpl<unsigned> &NewRegs) const; 136 bool expandStoreInt(MachineBasicBlock &B, MachineBasicBlock::iterator It, 137 MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 138 SmallVectorImpl<unsigned> &NewRegs) const; 139 bool expandLoadInt(MachineBasicBlock &B, MachineBasicBlock::iterator It, 140 MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 141 SmallVectorImpl<unsigned> &NewRegs) const; 142 bool expandStoreVecPred(MachineBasicBlock &B, MachineBasicBlock::iterator It, 143 MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 144 SmallVectorImpl<unsigned> &NewRegs) const; 145 bool expandLoadVecPred(MachineBasicBlock &B, MachineBasicBlock::iterator It, 146 MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 147 SmallVectorImpl<unsigned> &NewRegs) const; 148 bool expandStoreVec2(MachineBasicBlock &B, MachineBasicBlock::iterator It, 149 MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 150 SmallVectorImpl<unsigned> &NewRegs) const; 151 bool expandLoadVec2(MachineBasicBlock &B, MachineBasicBlock::iterator It, 152 MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 153 SmallVectorImpl<unsigned> &NewRegs) const; 154 bool expandStoreVec(MachineBasicBlock &B, MachineBasicBlock::iterator It, 155 MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 156 SmallVectorImpl<unsigned> &NewRegs) const; 157 bool expandLoadVec(MachineBasicBlock &B, MachineBasicBlock::iterator It, 158 MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 159 SmallVectorImpl<unsigned> &NewRegs) const; 160 bool expandSpillMacros(MachineFunction &MF, 161 SmallVectorImpl<unsigned> &NewRegs) const; 162 163 unsigned findPhysReg(MachineFunction &MF, HexagonBlockRanges::IndexRange &FIR, 164 HexagonBlockRanges::InstrIndexMap &IndexMap, 165 HexagonBlockRanges::RegToRangeMap &DeadMap, 166 const TargetRegisterClass *RC) const; 167 void optimizeSpillSlots(MachineFunction &MF, 168 SmallVectorImpl<unsigned> &VRegs) const; 169 170 void findShrunkPrologEpilog(MachineFunction &MF, MachineBasicBlock *&PrologB, 171 MachineBasicBlock *&EpilogB) const; 172 173 void addCalleeSaveRegistersAsImpOperand(MachineInstr *MI, const CSIVect &CSI, 174 bool IsDef, bool IsKill) const; 175 bool shouldInlineCSR(const MachineFunction &MF, const CSIVect &CSI) const; 176 bool useSpillFunction(const MachineFunction &MF, const CSIVect &CSI) const; 177 bool useRestoreFunction(const MachineFunction &MF, const CSIVect &CSI) const; 178 bool mayOverflowFrameOffset(MachineFunction &MF) const; 179 }; 180 181 } // end namespace llvm 182 183 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H 184