Home | History | Annotate | Line # | Download | only in ARM
      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 
     13 #ifndef LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
     14 #define LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
     15 
     16 #include "llvm/ADT/DenseMap.h"
     17 #include "llvm/ADT/SmallPtrSet.h"
     18 #include "llvm/CodeGen/MachineFunction.h"
     19 #include "llvm/IR/GlobalVariable.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   /// LRSpilled - True if the LR register has been for spilled for
     62   /// any reason, so it's legal to emit an ARM::tBfar (i.e. "bl").
     63   bool LRSpilled = 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 FPCXTSaveSize = 0;
     87   unsigned GPRCS1Size = 0;
     88   unsigned GPRCS2Size = 0;
     89   unsigned DPRCSAlignGapSize = 0;
     90   unsigned DPRCSSize = 0;
     91 
     92   /// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in
     93   /// the aligned portion of the stack frame.  This is always a contiguous
     94   /// sequence of D-registers starting from d8.
     95   ///
     96   /// We do not keep track of the frame indices used for these registers - they
     97   /// behave like any other frame index in the aligned stack frame.  These
     98   /// registers also aren't included in DPRCSSize above.
     99   unsigned NumAlignedDPRCS2Regs = 0;
    100 
    101   unsigned PICLabelUId = 0;
    102 
    103   /// VarArgsFrameIndex - FrameIndex for start of varargs area.
    104   int VarArgsFrameIndex = 0;
    105 
    106   /// HasITBlocks - True if IT blocks have been inserted.
    107   bool HasITBlocks = false;
    108 
    109   // Security Extensions
    110   bool IsCmseNSEntry;
    111   bool IsCmseNSCall;
    112 
    113   /// CPEClones - Track constant pool entries clones created by Constant Island
    114   /// pass.
    115   DenseMap<unsigned, unsigned> CPEClones;
    116 
    117   /// ArgumentStackSize - amount of bytes on stack consumed by the arguments
    118   /// being passed on the stack
    119   unsigned ArgumentStackSize = 0;
    120 
    121   /// CoalescedWeights - mapping of basic blocks to the rolling counter of
    122   /// coalesced weights.
    123   DenseMap<const MachineBasicBlock*, unsigned> CoalescedWeights;
    124 
    125   /// True if this function has a subset of CSRs that is handled explicitly via
    126   /// copies.
    127   bool IsSplitCSR = false;
    128 
    129   /// Globals that have had their storage promoted into the constant pool.
    130   SmallPtrSet<const GlobalVariable*,2> PromotedGlobals;
    131 
    132   /// The amount the literal pool has been increasedby due to promoted globals.
    133   int PromotedGlobalsIncrease = 0;
    134 
    135   /// True if r0 will be preserved by a call to this function (e.g. C++
    136   /// con/destructors).
    137   bool PreservesR0 = false;
    138 
    139 public:
    140   ARMFunctionInfo() = default;
    141 
    142   explicit ARMFunctionInfo(MachineFunction &MF);
    143 
    144   bool isThumbFunction() const { return isThumb; }
    145   bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
    146   bool isThumb2Function() const { return isThumb && hasThumb2; }
    147 
    148   bool isCmseNSEntryFunction() const { return IsCmseNSEntry; }
    149   bool isCmseNSCallFunction() const { return IsCmseNSCall; }
    150 
    151   unsigned getStoredByValParamsPadding() const { return StByValParamsPadding; }
    152   void setStoredByValParamsPadding(unsigned p) { StByValParamsPadding = p; }
    153 
    154   unsigned getArgRegsSaveSize() const { return ArgRegsSaveSize; }
    155   void setArgRegsSaveSize(unsigned s) { ArgRegsSaveSize = s; }
    156 
    157   unsigned getReturnRegsCount() const { return ReturnRegsCount; }
    158   void setReturnRegsCount(unsigned s) { ReturnRegsCount = s; }
    159 
    160   bool hasStackFrame() const { return HasStackFrame; }
    161   void setHasStackFrame(bool s) { HasStackFrame = s; }
    162 
    163   bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
    164   void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }
    165 
    166   bool isLRSpilled() const { return LRSpilled; }
    167   void setLRIsSpilled(bool s) { LRSpilled = s; }
    168 
    169   unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
    170   void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
    171 
    172   unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; }
    173   void setNumAlignedDPRCS2Regs(unsigned n) { NumAlignedDPRCS2Regs = n; }
    174 
    175   unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
    176   unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
    177   unsigned getDPRCalleeSavedAreaOffset()  const { return DPRCSOffset; }
    178 
    179   void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
    180   void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
    181   void setDPRCalleeSavedAreaOffset(unsigned o)  { DPRCSOffset = o; }
    182 
    183   unsigned getFPCXTSaveAreaSize() const       { return FPCXTSaveSize; }
    184   unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
    185   unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
    186   unsigned getDPRCalleeSavedGapSize() const   { return DPRCSAlignGapSize; }
    187   unsigned getDPRCalleeSavedAreaSize()  const { return DPRCSSize; }
    188 
    189   void setFPCXTSaveAreaSize(unsigned s)       { FPCXTSaveSize = s; }
    190   void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
    191   void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
    192   void setDPRCalleeSavedGapSize(unsigned s)   { DPRCSAlignGapSize = s; }
    193   void setDPRCalleeSavedAreaSize(unsigned s)  { DPRCSSize = s; }
    194 
    195   unsigned getArgumentStackSize() const { return ArgumentStackSize; }
    196   void setArgumentStackSize(unsigned size) { ArgumentStackSize = size; }
    197 
    198   void initPICLabelUId(unsigned UId) {
    199     PICLabelUId = UId;
    200   }
    201 
    202   unsigned getNumPICLabels() const {
    203     return PICLabelUId;
    204   }
    205 
    206   unsigned createPICLabelUId() {
    207     return PICLabelUId++;
    208   }
    209 
    210   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
    211   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
    212 
    213   bool hasITBlocks() const { return HasITBlocks; }
    214   void setHasITBlocks(bool h) { HasITBlocks = h; }
    215 
    216   bool isSplitCSR() const { return IsSplitCSR; }
    217   void setIsSplitCSR(bool s) { IsSplitCSR = s; }
    218 
    219   void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {
    220     if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)
    221       llvm_unreachable("Duplicate entries!");
    222   }
    223 
    224   unsigned getOriginalCPIdx(unsigned CloneIdx) const {
    225     DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);
    226     if (I != CPEClones.end())
    227       return I->second;
    228     else
    229       return -1U;
    230   }
    231 
    232   DenseMap<const MachineBasicBlock*, unsigned>::iterator getCoalescedWeight(
    233                                                   MachineBasicBlock* MBB) {
    234     auto It = CoalescedWeights.find(MBB);
    235     if (It == CoalescedWeights.end()) {
    236       It = CoalescedWeights.insert(std::make_pair(MBB, 0)).first;
    237     }
    238     return It;
    239   }
    240 
    241   /// Indicate to the backend that \c GV has had its storage changed to inside
    242   /// a constant pool. This means it no longer needs to be emitted as a
    243   /// global variable.
    244   void markGlobalAsPromotedToConstantPool(const GlobalVariable *GV) {
    245     PromotedGlobals.insert(GV);
    246   }
    247   SmallPtrSet<const GlobalVariable*, 2>& getGlobalsPromotedToConstantPool() {
    248     return PromotedGlobals;
    249   }
    250   int getPromotedConstpoolIncrease() const {
    251     return PromotedGlobalsIncrease;
    252   }
    253   void setPromotedConstpoolIncrease(int Sz) {
    254     PromotedGlobalsIncrease = Sz;
    255   }
    256 
    257   DenseMap<unsigned, unsigned> EHPrologueRemappedRegs;
    258   DenseMap<unsigned, unsigned> EHPrologueOffsetInRegs;
    259 
    260   void setPreservesR0() { PreservesR0 = true; }
    261   bool getPreservesR0() const { return PreservesR0; }
    262 };
    263 
    264 } // end namespace llvm
    265 
    266 #endif // LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
    267