1 //===-- ARMMachineFunctionInfo.h - ARM machine function info ----*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file declares ARM-specific per-machine-function information.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
14 #define LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/SmallPtrSet.h"
18 #include "llvm/CodeGen/MIRYamlMapping.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/IR/GlobalVariable.h"
21 #include "llvm/Support/ErrorHandling.h"
27 struct ARMFunctionInfo
;
28 } // end namespace yaml
32 /// ARMFunctionInfo - This class is derived from MachineFunctionInfo and
33 /// contains private ARM-specific information for each MachineFunction.
34 class ARMFunctionInfo
: public MachineFunctionInfo
{
35 virtual void anchor();
37 /// isThumb - True if this function is compiled under Thumb mode.
38 /// Used to initialized Align, so must precede it.
41 /// hasThumb2 - True if the target architecture supports Thumb2. Do not use
42 /// to determine if function is compiled under Thumb mode, for that use
44 bool hasThumb2
= false;
46 /// ArgsRegSaveSize - Size of the register save area for vararg functions or
47 /// those making guaranteed tail calls that need more stack argument space
48 /// than is provided by this functions incoming parameters.
50 unsigned ArgRegsSaveSize
= 0;
52 /// ReturnRegsCount - Number of registers used up in the return.
53 unsigned ReturnRegsCount
= 0;
55 /// HasStackFrame - True if this function has a stack frame. Set by
56 /// determineCalleeSaves().
57 bool HasStackFrame
= false;
59 /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by
61 bool RestoreSPFromFP
= false;
63 /// LRSpilled - True if the LR register has been for spilled for
64 /// any reason, so it's legal to emit an ARM::tBfar (i.e. "bl").
65 bool LRSpilled
= false;
67 /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
68 /// spill stack offset.
69 unsigned FramePtrSpillOffset
= 0;
71 /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
72 /// register spills areas. For Mac OS X:
74 /// GPR callee-saved (1) : r4, r5, r6, r7, lr
75 /// --------------------------------------------
76 /// GPR callee-saved (2) : r8, r10, r11
77 /// --------------------------------------------
78 /// DPR callee-saved : d8 - d15
80 /// Also see AlignedDPRCSRegs below. Not all D-regs need to go in area 3.
81 /// Some may be spilled after the stack has been realigned.
82 unsigned GPRCS1Offset
= 0;
83 unsigned GPRCS2Offset
= 0;
84 unsigned DPRCS1Offset
= 0;
86 /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
88 unsigned FPCXTSaveSize
= 0;
89 unsigned FRSaveSize
= 0;
90 unsigned GPRCS1Size
= 0;
91 unsigned GPRCS2Size
= 0;
92 unsigned DPRCSAlignGapSize
= 0;
93 unsigned DPRCS1Size
= 0;
94 unsigned GPRCS3Size
= 0;
96 /// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in
97 /// the aligned portion of the stack frame. This is always a contiguous
98 /// sequence of D-registers starting from d8.
100 /// We do not keep track of the frame indices used for these registers - they
101 /// behave like any other frame index in the aligned stack frame. These
102 /// registers also aren't included in DPRCSSize above.
103 unsigned NumAlignedDPRCS2Regs
= 0;
105 unsigned PICLabelUId
= 0;
107 /// VarArgsFrameIndex - FrameIndex for start of varargs area.
108 int VarArgsFrameIndex
= 0;
110 /// HasITBlocks - True if IT blocks have been inserted.
111 bool HasITBlocks
= false;
113 // Security Extensions
117 /// CPEClones - Track constant pool entries clones created by Constant Island
119 DenseMap
<unsigned, unsigned> CPEClones
;
121 /// ArgumentStackSize - amount of bytes on stack consumed by the arguments
122 /// being passed on the stack
123 unsigned ArgumentStackSize
= 0;
125 /// ArgumentStackToRestore - amount of bytes on stack consumed that we must
126 /// restore on return.
127 unsigned ArgumentStackToRestore
= 0;
129 /// CoalescedWeights - mapping of basic blocks to the rolling counter of
130 /// coalesced weights.
131 DenseMap
<const MachineBasicBlock
*, unsigned> CoalescedWeights
;
133 /// True if this function has a subset of CSRs that is handled explicitly via
135 bool IsSplitCSR
= false;
137 /// Globals that have had their storage promoted into the constant pool.
138 SmallPtrSet
<const GlobalVariable
*,2> PromotedGlobals
;
140 /// The amount the literal pool has been increasedby due to promoted globals.
141 int PromotedGlobalsIncrease
= 0;
143 /// True if r0 will be preserved by a call to this function (e.g. C++
144 /// con/destructors).
145 bool PreservesR0
= false;
147 /// True if the function should sign its return address.
148 bool SignReturnAddress
= false;
150 /// True if the fucntion should sign its return address, even if LR is not
152 bool SignReturnAddressAll
= false;
154 /// True if BTI instructions should be placed at potential indirect jump
156 bool BranchTargetEnforcement
= false;
159 ARMFunctionInfo() = default;
161 explicit ARMFunctionInfo(const Function
&F
, const ARMSubtarget
*STI
);
163 MachineFunctionInfo
*
164 clone(BumpPtrAllocator
&Allocator
, MachineFunction
&DestMF
,
165 const DenseMap
<MachineBasicBlock
*, MachineBasicBlock
*> &Src2DstMBB
)
168 bool isThumbFunction() const { return isThumb
; }
169 bool isThumb1OnlyFunction() const { return isThumb
&& !hasThumb2
; }
170 bool isThumb2Function() const { return isThumb
&& hasThumb2
; }
172 bool isCmseNSEntryFunction() const { return IsCmseNSEntry
; }
173 bool isCmseNSCallFunction() const { return IsCmseNSCall
; }
175 unsigned getArgRegsSaveSize() const { return ArgRegsSaveSize
; }
176 void setArgRegsSaveSize(unsigned s
) { ArgRegsSaveSize
= s
; }
178 unsigned getReturnRegsCount() const { return ReturnRegsCount
; }
179 void setReturnRegsCount(unsigned s
) { ReturnRegsCount
= s
; }
181 bool hasStackFrame() const { return HasStackFrame
; }
182 void setHasStackFrame(bool s
) { HasStackFrame
= s
; }
184 bool shouldRestoreSPFromFP() const { return RestoreSPFromFP
; }
185 void setShouldRestoreSPFromFP(bool s
) { RestoreSPFromFP
= s
; }
187 bool isLRSpilled() const { return LRSpilled
; }
188 void setLRIsSpilled(bool s
) { LRSpilled
= s
; }
190 unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset
; }
191 void setFramePtrSpillOffset(unsigned o
) { FramePtrSpillOffset
= o
; }
193 unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs
; }
194 void setNumAlignedDPRCS2Regs(unsigned n
) { NumAlignedDPRCS2Regs
= n
; }
196 unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset
; }
197 unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset
; }
198 unsigned getDPRCalleeSavedArea1Offset() const { return DPRCS1Offset
; }
200 void setGPRCalleeSavedArea1Offset(unsigned o
) { GPRCS1Offset
= o
; }
201 void setGPRCalleeSavedArea2Offset(unsigned o
) { GPRCS2Offset
= o
; }
202 void setDPRCalleeSavedArea1Offset(unsigned o
) { DPRCS1Offset
= o
; }
204 unsigned getFPCXTSaveAreaSize() const { return FPCXTSaveSize
; }
205 unsigned getFrameRecordSavedAreaSize() const { return FRSaveSize
; }
206 unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size
; }
207 unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size
; }
208 unsigned getDPRCalleeSavedGapSize() const { return DPRCSAlignGapSize
; }
209 unsigned getDPRCalleeSavedArea1Size() const { return DPRCS1Size
; }
210 unsigned getGPRCalleeSavedArea3Size() const { return GPRCS3Size
; }
212 void setFPCXTSaveAreaSize(unsigned s
) { FPCXTSaveSize
= s
; }
213 void setFrameRecordSavedAreaSize(unsigned s
) { FRSaveSize
= s
; }
214 void setGPRCalleeSavedArea1Size(unsigned s
) { GPRCS1Size
= s
; }
215 void setGPRCalleeSavedArea2Size(unsigned s
) { GPRCS2Size
= s
; }
216 void setDPRCalleeSavedGapSize(unsigned s
) { DPRCSAlignGapSize
= s
; }
217 void setDPRCalleeSavedArea1Size(unsigned s
) { DPRCS1Size
= s
; }
218 void setGPRCalleeSavedArea3Size(unsigned s
) { GPRCS3Size
= s
; }
220 unsigned getArgumentStackSize() const { return ArgumentStackSize
; }
221 void setArgumentStackSize(unsigned size
) { ArgumentStackSize
= size
; }
223 unsigned getArgumentStackToRestore() const { return ArgumentStackToRestore
; }
224 void setArgumentStackToRestore(unsigned v
) { ArgumentStackToRestore
= v
; }
226 void initPICLabelUId(unsigned UId
) {
230 unsigned getNumPICLabels() const {
234 unsigned createPICLabelUId() {
235 return PICLabelUId
++;
238 int getVarArgsFrameIndex() const { return VarArgsFrameIndex
; }
239 void setVarArgsFrameIndex(int Index
) { VarArgsFrameIndex
= Index
; }
241 bool hasITBlocks() const { return HasITBlocks
; }
242 void setHasITBlocks(bool h
) { HasITBlocks
= h
; }
244 bool isSplitCSR() const { return IsSplitCSR
; }
245 void setIsSplitCSR(bool s
) { IsSplitCSR
= s
; }
247 void recordCPEClone(unsigned CPIdx
, unsigned CPCloneIdx
) {
248 if (!CPEClones
.insert(std::make_pair(CPCloneIdx
, CPIdx
)).second
)
249 llvm_unreachable("Duplicate entries!");
252 unsigned getOriginalCPIdx(unsigned CloneIdx
) const {
253 DenseMap
<unsigned, unsigned>::const_iterator I
= CPEClones
.find(CloneIdx
);
254 if (I
!= CPEClones
.end())
260 DenseMap
<const MachineBasicBlock
*, unsigned>::iterator
261 getCoalescedWeight(MachineBasicBlock
*MBB
) {
262 return CoalescedWeights
.try_emplace(MBB
, 0).first
;
265 /// Indicate to the backend that \c GV has had its storage changed to inside
266 /// a constant pool. This means it no longer needs to be emitted as a
268 void markGlobalAsPromotedToConstantPool(const GlobalVariable
*GV
) {
269 PromotedGlobals
.insert(GV
);
271 SmallPtrSet
<const GlobalVariable
*, 2>& getGlobalsPromotedToConstantPool() {
272 return PromotedGlobals
;
274 int getPromotedConstpoolIncrease() const {
275 return PromotedGlobalsIncrease
;
277 void setPromotedConstpoolIncrease(int Sz
) {
278 PromotedGlobalsIncrease
= Sz
;
281 DenseMap
<unsigned, unsigned> EHPrologueRemappedRegs
;
282 DenseMap
<unsigned, unsigned> EHPrologueOffsetInRegs
;
284 void setPreservesR0() { PreservesR0
= true; }
285 bool getPreservesR0() const { return PreservesR0
; }
287 bool shouldSignReturnAddress() const {
288 return shouldSignReturnAddress(LRSpilled
);
291 bool shouldSignReturnAddress(bool SpillsLR
) const {
292 if (!SignReturnAddress
)
294 if (SignReturnAddressAll
)
299 bool branchTargetEnforcement() const { return BranchTargetEnforcement
; }
301 void initializeBaseYamlFields(const yaml::ARMFunctionInfo
&YamlMFI
);
305 struct ARMFunctionInfo final
: public yaml::MachineFunctionInfo
{
308 ARMFunctionInfo() = default;
309 ARMFunctionInfo(const llvm::ARMFunctionInfo
&MFI
);
311 void mappingImpl(yaml::IO
&YamlIO
) override
;
312 ~ARMFunctionInfo() = default;
315 template <> struct MappingTraits
<ARMFunctionInfo
> {
316 static void mapping(IO
&YamlIO
, ARMFunctionInfo
&MFI
) {
317 YamlIO
.mapOptional("isLRSpilled", MFI
.LRSpilled
);
321 } // end namespace yaml
323 } // end namespace llvm
325 #endif // LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H