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