199193Sjmallett//==- HexagonFrameLowering.h - Define frame lowering for Hexagon -*- C++ -*-==// 299193Sjmallett// 399193Sjmallett// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 499193Sjmallett// See https://llvm.org/LICENSE.txt for license information. 599193Sjmallett// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 699193Sjmallett// 799193Sjmallett//===----------------------------------------------------------------------===// 899193Sjmallett 999193Sjmallett#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H 1099193Sjmallett#define LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H 1199193Sjmallett 1299193Sjmallett#include "Hexagon.h" 1399193Sjmallett#include "HexagonBlockRanges.h" 1499193Sjmallett#include "MCTargetDesc/HexagonMCTargetDesc.h" 1599193Sjmallett#include "llvm/ADT/STLExtras.h" 1699193Sjmallett#include "llvm/CodeGen/MachineBasicBlock.h" 1799193Sjmallett#include "llvm/CodeGen/MachineFrameInfo.h" 1899193Sjmallett#include "llvm/CodeGen/TargetFrameLowering.h" 1999193Sjmallett#include <vector> 2099193Sjmallett 2199193Sjmallettnamespace llvm { 2299193Sjmallett 2399193Sjmallettclass BitVector; 2499193Sjmallettclass HexagonInstrInfo; 2599193Sjmallettclass HexagonRegisterInfo; 2699193Sjmallettclass MachineFunction; 2799193Sjmallettclass MachineInstr; 2899193Sjmallettclass MachineRegisterInfo; 2999193Sjmallettclass TargetRegisterClass; 3099193Sjmallett 3199193Sjmallettclass HexagonFrameLowering : public TargetFrameLowering { 3299193Sjmallettpublic: 3399193Sjmallett // First register which could possibly hold a variable argument. 3499193Sjmallett int FirstVarArgSavedReg; 3599193Sjmallett explicit HexagonFrameLowering() 3699193Sjmallett : TargetFrameLowering(StackGrowsDown, Align(8), 0, Align(1), true) {} 3799193Sjmallett 3899193Sjmallett // All of the prolog/epilog functionality, including saving and restoring 3999193Sjmallett // callee-saved registers is handled in emitPrologue. This is to have the 4099193Sjmallett // logic for shrink-wrapping in one place. 4199193Sjmallett void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const 42109506Sjmallett override; 43109506Sjmallett void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const 4499193Sjmallett override {} 4599193Sjmallett 4699193Sjmallett bool enableCalleeSaveSkip(const MachineFunction &MF) const override; 4799193Sjmallett 4899193Sjmallett bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 4999193Sjmallett MachineBasicBlock::iterator MI, 5099193Sjmallett ArrayRef<CalleeSavedInfo> CSI, 51109506Sjmallett const TargetRegisterInfo *TRI) const override { 52109506Sjmallett return true; 53110066Sjmallett } 54110066Sjmallett 55109506Sjmallett bool 5699193Sjmallett restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 5799193Sjmallett MachineBasicBlock::iterator MI, 5899193Sjmallett MutableArrayRef<CalleeSavedInfo> CSI, 59109462Sjmallett const TargetRegisterInfo *TRI) const override { 6099193Sjmallett return true; 6199193Sjmallett } 6299193Sjmallett 6399193Sjmallett bool hasReservedCallFrame(const MachineFunction &MF) const override { 6499193Sjmallett // We always reserve call frame as a part of the initial stack allocation. 65109506Sjmallett return true; 66109506Sjmallett } 67109506Sjmallett 68109506Sjmallett bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override { 69207141Sjeff // Override this function to avoid calling hasFP before CSI is set 70207141Sjeff // (the default implementation calls hasFP). 71207141Sjeff return true; 72207141Sjeff } 73116084Sjmallett 7499193Sjmallett MachineBasicBlock::iterator 7599193Sjmallett eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 7699193Sjmallett MachineBasicBlock::iterator I) const override; 7799193Sjmallett void processFunctionBeforeFrameFinalized(MachineFunction &MF, 7899193Sjmallett RegScavenger *RS = nullptr) const override; 79109755Sjmallett void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, 80116084Sjmallett RegScavenger *RS) const override; 81109755Sjmallett 82109755Sjmallett bool targetHandlesStackFrameRounding() const override { 83109755Sjmallett return true; 84116084Sjmallett } 85109755Sjmallett 86116084Sjmallett StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, 87109755Sjmallett Register &FrameReg) const override; 88109755Sjmallett bool hasFP(const MachineFunction &MF) const override; 89109755Sjmallett 90109755Sjmallett const SpillSlot *getCalleeSavedSpillSlots(unsigned &NumEntries) 91109755Sjmallett const override { 92109506Sjmallett static const SpillSlot Offsets[] = { 93109506Sjmallett { Hexagon::R17, -4 }, { Hexagon::R16, -8 }, { Hexagon::D8, -8 }, 94167625Spjd { Hexagon::R19, -12 }, { Hexagon::R18, -16 }, { Hexagon::D9, -16 }, 95109506Sjmallett { Hexagon::R21, -20 }, { Hexagon::R20, -24 }, { Hexagon::D10, -24 }, 96109506Sjmallett { Hexagon::R23, -28 }, { Hexagon::R22, -32 }, { Hexagon::D11, -32 }, 97167625Spjd { Hexagon::R25, -36 }, { Hexagon::R24, -40 }, { Hexagon::D12, -40 }, 9899193Sjmallett { Hexagon::R27, -44 }, { Hexagon::R26, -48 }, { Hexagon::D13, -48 } 99109462Sjmallett }; 10099222Sjmallett NumEntries = array_lengthof(Offsets); 101109506Sjmallett return Offsets; 102167625Spjd } 103109506Sjmallett 104109506Sjmallett bool assignCalleeSavedSpillSlots(MachineFunction &MF, 105109506Sjmallett const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI) 106109506Sjmallett const override; 107109506Sjmallett 108167625Spjd bool needsAligna(const MachineFunction &MF) const; 109167625Spjd const MachineInstr *getAlignaInstr(const MachineFunction &MF) const; 110167625Spjd 111167625Spjd void insertCFIInstructions(MachineFunction &MF) const; 112167625Spjd 113167625Spjdprivate: 114167625Spjd using CSIVect = std::vector<CalleeSavedInfo>; 115194030Sjmallett 116194030Sjmallett void expandAlloca(MachineInstr *AI, const HexagonInstrInfo &TII, 117194030Sjmallett unsigned SP, unsigned CF) const; 118194030Sjmallett void insertPrologueInBlock(MachineBasicBlock &MBB, bool PrologueStubs) const; 119167625Spjd void insertEpilogueInBlock(MachineBasicBlock &MBB) const; 120167625Spjd void insertAllocframe(MachineBasicBlock &MBB, 121167625Spjd MachineBasicBlock::iterator InsertPt, unsigned NumBytes) const; 122167625Spjd bool insertCSRSpillsInBlock(MachineBasicBlock &MBB, const CSIVect &CSI, 123167625Spjd const HexagonRegisterInfo &HRI, bool &PrologueStubs) const; 124167625Spjd bool insertCSRRestoresInBlock(MachineBasicBlock &MBB, const CSIVect &CSI, 125167625Spjd const HexagonRegisterInfo &HRI) const; 126167625Spjd void updateEntryPaths(MachineFunction &MF, MachineBasicBlock &SaveB) const; 127167625Spjd bool updateExitPaths(MachineBasicBlock &MBB, MachineBasicBlock &RestoreB, 128167625Spjd BitVector &DoneT, BitVector &DoneF, BitVector &Path) const; 129167625Spjd void insertCFIInstructionsAt(MachineBasicBlock &MBB, 130167625Spjd MachineBasicBlock::iterator At) const; 131167625Spjd 132167625Spjd void adjustForCalleeSavedRegsSpillCall(MachineFunction &MF) const; 133167625Spjd 134167625Spjd bool expandCopy(MachineBasicBlock &B, MachineBasicBlock::iterator It, 135167625Spjd MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 136167625Spjd SmallVectorImpl<unsigned> &NewRegs) const; 137167625Spjd bool expandStoreInt(MachineBasicBlock &B, MachineBasicBlock::iterator It, 138167625Spjd MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 139167625Spjd SmallVectorImpl<unsigned> &NewRegs) const; 140167625Spjd bool expandLoadInt(MachineBasicBlock &B, MachineBasicBlock::iterator It, 141167625Spjd MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 142167625Spjd SmallVectorImpl<unsigned> &NewRegs) const; 143167625Spjd bool expandStoreVecPred(MachineBasicBlock &B, MachineBasicBlock::iterator It, 144109506Sjmallett MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 145116084Sjmallett SmallVectorImpl<unsigned> &NewRegs) const; 146109506Sjmallett bool expandLoadVecPred(MachineBasicBlock &B, MachineBasicBlock::iterator It, 14799193Sjmallett MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 14899193Sjmallett SmallVectorImpl<unsigned> &NewRegs) const; 149109506Sjmallett bool expandStoreVec2(MachineBasicBlock &B, MachineBasicBlock::iterator It, 150116084Sjmallett MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 15199193Sjmallett SmallVectorImpl<unsigned> &NewRegs) const; 15299193Sjmallett bool expandLoadVec2(MachineBasicBlock &B, MachineBasicBlock::iterator It, 15399193Sjmallett MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 154109509Sjmallett SmallVectorImpl<unsigned> &NewRegs) const; 15599193Sjmallett bool expandStoreVec(MachineBasicBlock &B, MachineBasicBlock::iterator It, 15699193Sjmallett MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 15799823Sjmallett SmallVectorImpl<unsigned> &NewRegs) const; 15899823Sjmallett bool expandLoadVec(MachineBasicBlock &B, MachineBasicBlock::iterator It, 159109518Sjmallett MachineRegisterInfo &MRI, const HexagonInstrInfo &HII, 160109506Sjmallett SmallVectorImpl<unsigned> &NewRegs) const; 161101687Sjmallett bool expandSpillMacros(MachineFunction &MF, 162105737Sjmallett SmallVectorImpl<unsigned> &NewRegs) const; 163207141Sjeff 16499193Sjmallett unsigned findPhysReg(MachineFunction &MF, HexagonBlockRanges::IndexRange &FIR, 165109506Sjmallett HexagonBlockRanges::InstrIndexMap &IndexMap, 166109506Sjmallett HexagonBlockRanges::RegToRangeMap &DeadMap, 167109506Sjmallett const TargetRegisterClass *RC) const; 168109506Sjmallett void optimizeSpillSlots(MachineFunction &MF, 169116084Sjmallett SmallVectorImpl<unsigned> &VRegs) const; 170109506Sjmallett 171109506Sjmallett void findShrunkPrologEpilog(MachineFunction &MF, MachineBasicBlock *&PrologB, 172109506Sjmallett MachineBasicBlock *&EpilogB) const; 173109506Sjmallett 174109506Sjmallett void addCalleeSaveRegistersAsImpOperand(MachineInstr *MI, const CSIVect &CSI, 175116084Sjmallett bool IsDef, bool IsKill) const; 17699193Sjmallett bool shouldInlineCSR(const MachineFunction &MF, const CSIVect &CSI) const; 177110066Sjmallett bool useSpillFunction(const MachineFunction &MF, const CSIVect &CSI) const; 178110066Sjmallett bool useRestoreFunction(const MachineFunction &MF, const CSIVect &CSI) const; 179110066Sjmallett bool mayOverflowFrameOffset(MachineFunction &MF) const; 180110066Sjmallett}; 181110066Sjmallett 182110066Sjmallett} // end namespace llvm 183110066Sjmallett 184116084Sjmallett#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H 185110066Sjmallett