ARMMachineFunctionInfo.h 9.7 KB

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