Line data Source code
1 : //===-- ARMMachineFunctionInfo.h - ARM machine function info ----*- 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 : // This file declares ARM-specific per-machine-function information.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
15 : #define LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
16 :
17 : #include "llvm/ADT/DenseMap.h"
18 : #include "llvm/ADT/SmallPtrSet.h"
19 : #include "llvm/CodeGen/MachineFunction.h"
20 : #include "llvm/Support/ErrorHandling.h"
21 : #include <utility>
22 :
23 : namespace llvm {
24 :
25 : /// ARMFunctionInfo - This class is derived from MachineFunctionInfo and
26 : /// contains private ARM-specific information for each MachineFunction.
27 : class ARMFunctionInfo : public MachineFunctionInfo {
28 : virtual void anchor();
29 :
30 : /// isThumb - True if this function is compiled under Thumb mode.
31 : /// Used to initialized Align, so must precede it.
32 : bool isThumb = false;
33 :
34 : /// hasThumb2 - True if the target architecture supports Thumb2. Do not use
35 : /// to determine if function is compiled under Thumb mode, for that use
36 : /// 'isThumb'.
37 : bool hasThumb2 = false;
38 :
39 : /// StByValParamsPadding - For parameter that is split between
40 : /// GPRs and memory; while recovering GPRs part, when
41 : /// StackAlignment > 4, and GPRs-part-size mod StackAlignment != 0,
42 : /// we need to insert gap before parameter start address. It allows to
43 : /// "attach" GPR-part to the part that was passed via stack.
44 : unsigned StByValParamsPadding = 0;
45 :
46 : /// VarArgsRegSaveSize - Size of the register save area for vararg functions.
47 : ///
48 : unsigned ArgRegsSaveSize = 0;
49 :
50 : /// ReturnRegsCount - Number of registers used up in the return.
51 : unsigned ReturnRegsCount = 0;
52 :
53 : /// HasStackFrame - True if this function has a stack frame. Set by
54 : /// determineCalleeSaves().
55 : bool HasStackFrame = false;
56 :
57 : /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by
58 : /// emitPrologue.
59 : bool RestoreSPFromFP = false;
60 :
61 : /// LRSpilledForFarJump - True if the LR register has been for spilled to
62 : /// enable far jump.
63 : bool LRSpilledForFarJump = false;
64 :
65 : /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
66 : /// spill stack offset.
67 : unsigned FramePtrSpillOffset = 0;
68 :
69 : /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
70 : /// register spills areas. For Mac OS X:
71 : ///
72 : /// GPR callee-saved (1) : r4, r5, r6, r7, lr
73 : /// --------------------------------------------
74 : /// GPR callee-saved (2) : r8, r10, r11
75 : /// --------------------------------------------
76 : /// DPR callee-saved : d8 - d15
77 : ///
78 : /// Also see AlignedDPRCSRegs below. Not all D-regs need to go in area 3.
79 : /// Some may be spilled after the stack has been realigned.
80 : unsigned GPRCS1Offset = 0;
81 : unsigned GPRCS2Offset = 0;
82 : unsigned DPRCSOffset = 0;
83 :
84 : /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
85 : /// areas.
86 : unsigned GPRCS1Size = 0;
87 : unsigned GPRCS2Size = 0;
88 : unsigned DPRCSAlignGapSize = 0;
89 : unsigned DPRCSSize = 0;
90 :
91 : /// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in
92 : /// the aligned portion of the stack frame. This is always a contiguous
93 : /// sequence of D-registers starting from d8.
94 : ///
95 : /// We do not keep track of the frame indices used for these registers - they
96 : /// behave like any other frame index in the aligned stack frame. These
97 : /// registers also aren't included in DPRCSSize above.
98 : unsigned NumAlignedDPRCS2Regs = 0;
99 :
100 : unsigned PICLabelUId = 0;
101 :
102 : /// VarArgsFrameIndex - FrameIndex for start of varargs area.
103 : int VarArgsFrameIndex = 0;
104 :
105 : /// HasITBlocks - True if IT blocks have been inserted.
106 : bool HasITBlocks = false;
107 :
108 : /// CPEClones - Track constant pool entries clones created by Constant Island
109 : /// pass.
110 : DenseMap<unsigned, unsigned> CPEClones;
111 :
112 : /// ArgumentStackSize - amount of bytes on stack consumed by the arguments
113 : /// being passed on the stack
114 : unsigned ArgumentStackSize = 0;
115 :
116 : /// CoalescedWeights - mapping of basic blocks to the rolling counter of
117 : /// coalesced weights.
118 : DenseMap<const MachineBasicBlock*, unsigned> CoalescedWeights;
119 :
120 : /// True if this function has a subset of CSRs that is handled explicitly via
121 : /// copies.
122 : bool IsSplitCSR = false;
123 :
124 : /// Globals that have had their storage promoted into the constant pool.
125 : SmallPtrSet<const GlobalVariable*,2> PromotedGlobals;
126 :
127 : /// The amount the literal pool has been increasedby due to promoted globals.
128 : int PromotedGlobalsIncrease = 0;
129 :
130 : public:
131 : ARMFunctionInfo() = default;
132 :
133 : explicit ARMFunctionInfo(MachineFunction &MF);
134 :
135 0 : bool isThumbFunction() const { return isThumb; }
136 66990 : bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
137 88768 : bool isThumb2Function() const { return isThumb && hasThumb2; }
138 :
139 : unsigned getStoredByValParamsPadding() const { return StByValParamsPadding; }
140 : void setStoredByValParamsPadding(unsigned p) { StByValParamsPadding = p; }
141 :
142 0 : unsigned getArgRegsSaveSize() const { return ArgRegsSaveSize; }
143 27538 : void setArgRegsSaveSize(unsigned s) { ArgRegsSaveSize = s; }
144 :
145 0 : unsigned getReturnRegsCount() const { return ReturnRegsCount; }
146 13429 : void setReturnRegsCount(unsigned s) { ReturnRegsCount = s; }
147 :
148 0 : bool hasStackFrame() const { return HasStackFrame; }
149 4355 : void setHasStackFrame(bool s) { HasStackFrame = s; }
150 :
151 0 : bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
152 635 : void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }
153 :
154 0 : bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
155 1 : void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
156 :
157 0 : unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
158 1139 : void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
159 :
160 0 : unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; }
161 14734 : void setNumAlignedDPRCS2Regs(unsigned n) { NumAlignedDPRCS2Regs = n; }
162 :
163 : unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
164 : unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
165 : unsigned getDPRCalleeSavedAreaOffset() const { return DPRCSOffset; }
166 :
167 4290 : void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
168 4290 : void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
169 4290 : void setDPRCalleeSavedAreaOffset(unsigned o) { DPRCSOffset = o; }
170 :
171 0 : unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
172 0 : unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
173 0 : unsigned getDPRCalleeSavedGapSize() const { return DPRCSAlignGapSize; }
174 0 : unsigned getDPRCalleeSavedAreaSize() const { return DPRCSSize; }
175 :
176 4290 : void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
177 4290 : void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
178 3651 : void setDPRCalleeSavedGapSize(unsigned s) { DPRCSAlignGapSize = s; }
179 4290 : void setDPRCalleeSavedAreaSize(unsigned s) { DPRCSSize = s; }
180 :
181 0 : unsigned getArgumentStackSize() const { return ArgumentStackSize; }
182 13769 : void setArgumentStackSize(unsigned size) { ArgumentStackSize = size; }
183 :
184 0 : void initPICLabelUId(unsigned UId) {
185 14600 : PICLabelUId = UId;
186 0 : }
187 :
188 : unsigned getNumPICLabels() const {
189 : return PICLabelUId;
190 : }
191 :
192 0 : unsigned createPICLabelUId() {
193 1764 : return PICLabelUId++;
194 : }
195 :
196 0 : int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
197 34 : void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
198 :
199 0 : bool hasITBlocks() const { return HasITBlocks; }
200 810 : void setHasITBlocks(bool h) { HasITBlocks = h; }
201 :
202 0 : bool isSplitCSR() const { return IsSplitCSR; }
203 15 : void setIsSplitCSR(bool s) { IsSplitCSR = s; }
204 :
205 : void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {
206 2845 : if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)
207 0 : llvm_unreachable("Duplicate entries!");
208 : }
209 :
210 : unsigned getOriginalCPIdx(unsigned CloneIdx) const {
211 0 : DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);
212 0 : if (I != CPEClones.end())
213 0 : return I->second;
214 : else
215 : return -1U;
216 : }
217 :
218 442 : DenseMap<const MachineBasicBlock*, unsigned>::iterator getCoalescedWeight(
219 : MachineBasicBlock* MBB) {
220 442 : auto It = CoalescedWeights.find(MBB);
221 442 : if (It == CoalescedWeights.end()) {
222 152 : It = CoalescedWeights.insert(std::make_pair(MBB, 0)).first;
223 : }
224 442 : return It;
225 : }
226 :
227 : /// Indicate to the backend that \c GV has had its storage changed to inside
228 : /// a constant pool. This means it no longer needs to be emitted as a
229 : /// global variable.
230 : void markGlobalAsPromotedToConstantPool(const GlobalVariable *GV) {
231 86 : PromotedGlobals.insert(GV);
232 : }
233 : SmallPtrSet<const GlobalVariable*, 2>& getGlobalsPromotedToConstantPool() {
234 : return PromotedGlobals;
235 : }
236 0 : int getPromotedConstpoolIncrease() const {
237 0 : return PromotedGlobalsIncrease;
238 : }
239 0 : void setPromotedConstpoolIncrease(int Sz) {
240 86 : PromotedGlobalsIncrease = Sz;
241 0 : }
242 : };
243 :
244 : } // end namespace llvm
245 :
246 : #endif // LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
|