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