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