ARMMachineFunctionInfo.h 11 KB

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