Home | History | Annotate | Download | only in ARM
      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   bool isThumbFunction() const { return isThumb; }
    136   bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
    137   bool isThumb2Function() const { return isThumb && hasThumb2; }
    138 
    139   unsigned getStoredByValParamsPadding() const { return StByValParamsPadding; }
    140   void setStoredByValParamsPadding(unsigned p) { StByValParamsPadding = p; }
    141 
    142   unsigned getArgRegsSaveSize() const { return ArgRegsSaveSize; }
    143   void setArgRegsSaveSize(unsigned s) { ArgRegsSaveSize = s; }
    144 
    145   unsigned getReturnRegsCount() const { return ReturnRegsCount; }
    146   void setReturnRegsCount(unsigned s) { ReturnRegsCount = s; }
    147 
    148   bool hasStackFrame() const { return HasStackFrame; }
    149   void setHasStackFrame(bool s) { HasStackFrame = s; }
    150 
    151   bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
    152   void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }
    153 
    154   bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
    155   void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
    156 
    157   unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
    158   void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
    159 
    160   unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; }
    161   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   void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
    168   void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
    169   void setDPRCalleeSavedAreaOffset(unsigned o)  { DPRCSOffset = o; }
    170 
    171   unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
    172   unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
    173   unsigned getDPRCalleeSavedGapSize() const   { return DPRCSAlignGapSize; }
    174   unsigned getDPRCalleeSavedAreaSize()  const { return DPRCSSize; }
    175 
    176   void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
    177   void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
    178   void setDPRCalleeSavedGapSize(unsigned s)   { DPRCSAlignGapSize = s; }
    179   void setDPRCalleeSavedAreaSize(unsigned s)  { DPRCSSize = s; }
    180 
    181   unsigned getArgumentStackSize() const { return ArgumentStackSize; }
    182   void setArgumentStackSize(unsigned size) { ArgumentStackSize = size; }
    183 
    184   void initPICLabelUId(unsigned UId) {
    185     PICLabelUId = UId;
    186   }
    187 
    188   unsigned getNumPICLabels() const {
    189     return PICLabelUId;
    190   }
    191 
    192   unsigned createPICLabelUId() {
    193     return PICLabelUId++;
    194   }
    195 
    196   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
    197   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
    198 
    199   bool hasITBlocks() const { return HasITBlocks; }
    200   void setHasITBlocks(bool h) { HasITBlocks = h; }
    201 
    202   bool isSplitCSR() const { return IsSplitCSR; }
    203   void setIsSplitCSR(bool s) { IsSplitCSR = s; }
    204 
    205   void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {
    206     if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)
    207       llvm_unreachable("Duplicate entries!");
    208   }
    209 
    210   unsigned getOriginalCPIdx(unsigned CloneIdx) const {
    211     DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);
    212     if (I != CPEClones.end())
    213       return I->second;
    214     else
    215       return -1U;
    216   }
    217 
    218   DenseMap<const MachineBasicBlock*, unsigned>::iterator getCoalescedWeight(
    219                                                   MachineBasicBlock* MBB) {
    220     auto It = CoalescedWeights.find(MBB);
    221     if (It == CoalescedWeights.end()) {
    222       It = CoalescedWeights.insert(std::make_pair(MBB, 0)).first;
    223     }
    224     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     PromotedGlobals.insert(GV);
    232   }
    233   SmallPtrSet<const GlobalVariable*, 2>& getGlobalsPromotedToConstantPool() {
    234     return PromotedGlobals;
    235   }
    236   int getPromotedConstpoolIncrease() const {
    237     return PromotedGlobalsIncrease;
    238   }
    239   void setPromotedConstpoolIncrease(int Sz) {
    240     PromotedGlobalsIncrease = Sz;
    241   }
    242 };
    243 
    244 } // end namespace llvm
    245 
    246 #endif // LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
    247