Home | History | Annotate | Download | only in ARM
      1 //===-- ARMMachineFuctionInfo.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 ARMMACHINEFUNCTIONINFO_H
     15 #define ARMMACHINEFUNCTIONINFO_H
     16 
     17 #include "ARMSubtarget.h"
     18 #include "llvm/ADT/BitVector.h"
     19 #include "llvm/CodeGen/MachineFunction.h"
     20 #include "llvm/Target/TargetMachine.h"
     21 #include "llvm/Target/TargetRegisterInfo.h"
     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;
     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;
     38 
     39   /// VarArgsRegSaveSize - Size of the register save area for vararg functions.
     40   ///
     41   unsigned VarArgsRegSaveSize;
     42 
     43   /// HasStackFrame - True if this function has a stack frame. Set by
     44   /// processFunctionBeforeCalleeSavedScan().
     45   bool HasStackFrame;
     46 
     47   /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by
     48   /// emitPrologue.
     49   bool RestoreSPFromFP;
     50 
     51   /// LRSpilledForFarJump - True if the LR register has been for spilled to
     52   /// enable far jump.
     53   bool LRSpilledForFarJump;
     54 
     55   /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
     56   /// spill stack offset.
     57   unsigned FramePtrSpillOffset;
     58 
     59   /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
     60   /// register spills areas. For Mac OS X:
     61   ///
     62   /// GPR callee-saved (1) : r4, r5, r6, r7, lr
     63   /// --------------------------------------------
     64   /// GPR callee-saved (2) : r8, r10, r11
     65   /// --------------------------------------------
     66   /// DPR callee-saved : d8 - d15
     67   ///
     68   /// Also see AlignedDPRCSRegs below. Not all D-regs need to go in area 3.
     69   /// Some may be spilled after the stack has been realigned.
     70   unsigned GPRCS1Offset;
     71   unsigned GPRCS2Offset;
     72   unsigned DPRCSOffset;
     73 
     74   /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
     75   /// areas.
     76   unsigned GPRCS1Size;
     77   unsigned GPRCS2Size;
     78   unsigned DPRCSSize;
     79 
     80   /// GPRCS1Frames, GPRCS2Frames, DPRCSFrames - Keeps track of frame indices
     81   /// which belong to these spill areas.
     82   BitVector GPRCS1Frames;
     83   BitVector GPRCS2Frames;
     84   BitVector DPRCSFrames;
     85 
     86   /// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in
     87   /// the aligned portion of the stack frame.  This is always a contiguous
     88   /// sequence of D-registers starting from d8.
     89   ///
     90   /// We do not keep track of the frame indices used for these registers - they
     91   /// behave like any other frame index in the aligned stack frame.  These
     92   /// registers also aren't included in DPRCSSize above.
     93   unsigned NumAlignedDPRCS2Regs;
     94 
     95   /// JumpTableUId - Unique id for jumptables.
     96   ///
     97   unsigned JumpTableUId;
     98 
     99   unsigned PICLabelUId;
    100 
    101   /// VarArgsFrameIndex - FrameIndex for start of varargs area.
    102   int VarArgsFrameIndex;
    103 
    104   /// HasITBlocks - True if IT blocks have been inserted.
    105   bool HasITBlocks;
    106 
    107   /// CPEClones - Track constant pool entries clones created by Constant Island
    108   /// pass.
    109   DenseMap<unsigned, unsigned> CPEClones;
    110 
    111   /// GlobalBaseReg - keeps track of the virtual register initialized for
    112   /// use as the global base register. This is used for PIC in some PIC
    113   /// relocation models.
    114   unsigned GlobalBaseReg;
    115 
    116 public:
    117   ARMFunctionInfo() :
    118     isThumb(false),
    119     hasThumb2(false),
    120     VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
    121     LRSpilledForFarJump(false),
    122     FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
    123     GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
    124     GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0),
    125     NumAlignedDPRCS2Regs(0),
    126     JumpTableUId(0), PICLabelUId(0),
    127     VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {}
    128 
    129   explicit ARMFunctionInfo(MachineFunction &MF) :
    130     isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
    131     hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()),
    132     VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
    133     LRSpilledForFarJump(false),
    134     FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
    135     GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
    136     GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32),
    137     JumpTableUId(0), PICLabelUId(0),
    138     VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {}
    139 
    140   bool isThumbFunction() const { return isThumb; }
    141   bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
    142   bool isThumb2Function() const { return isThumb && hasThumb2; }
    143 
    144   unsigned getVarArgsRegSaveSize() const { return VarArgsRegSaveSize; }
    145   void setVarArgsRegSaveSize(unsigned s) { VarArgsRegSaveSize = s; }
    146 
    147   bool hasStackFrame() const { return HasStackFrame; }
    148   void setHasStackFrame(bool s) { HasStackFrame = s; }
    149 
    150   bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
    151   void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }
    152 
    153   bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
    154   void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
    155 
    156   unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
    157   void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
    158 
    159   unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; }
    160   void setNumAlignedDPRCS2Regs(unsigned n) { NumAlignedDPRCS2Regs = n; }
    161 
    162   unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
    163   unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
    164   unsigned getDPRCalleeSavedAreaOffset()  const { return DPRCSOffset; }
    165 
    166   void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
    167   void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
    168   void setDPRCalleeSavedAreaOffset(unsigned o)  { DPRCSOffset = o; }
    169 
    170   unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
    171   unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
    172   unsigned getDPRCalleeSavedAreaSize()  const { return DPRCSSize; }
    173 
    174   void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
    175   void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
    176   void setDPRCalleeSavedAreaSize(unsigned s)  { DPRCSSize = s; }
    177 
    178   bool isGPRCalleeSavedArea1Frame(int fi) const {
    179     if (fi < 0 || fi >= (int)GPRCS1Frames.size())
    180       return false;
    181     return GPRCS1Frames[fi];
    182   }
    183   bool isGPRCalleeSavedArea2Frame(int fi) const {
    184     if (fi < 0 || fi >= (int)GPRCS2Frames.size())
    185       return false;
    186     return GPRCS2Frames[fi];
    187   }
    188   bool isDPRCalleeSavedAreaFrame(int fi) const {
    189     if (fi < 0 || fi >= (int)DPRCSFrames.size())
    190       return false;
    191     return DPRCSFrames[fi];
    192   }
    193 
    194   void addGPRCalleeSavedArea1Frame(int fi) {
    195     if (fi >= 0) {
    196       int Size = GPRCS1Frames.size();
    197       if (fi >= Size) {
    198         Size *= 2;
    199         if (fi >= Size)
    200           Size = fi+1;
    201         GPRCS1Frames.resize(Size);
    202       }
    203       GPRCS1Frames[fi] = true;
    204     }
    205   }
    206   void addGPRCalleeSavedArea2Frame(int fi) {
    207     if (fi >= 0) {
    208       int Size = GPRCS2Frames.size();
    209       if (fi >= Size) {
    210         Size *= 2;
    211         if (fi >= Size)
    212           Size = fi+1;
    213         GPRCS2Frames.resize(Size);
    214       }
    215       GPRCS2Frames[fi] = true;
    216     }
    217   }
    218   void addDPRCalleeSavedAreaFrame(int fi) {
    219     if (fi >= 0) {
    220       int Size = DPRCSFrames.size();
    221       if (fi >= Size) {
    222         Size *= 2;
    223         if (fi >= Size)
    224           Size = fi+1;
    225         DPRCSFrames.resize(Size);
    226       }
    227       DPRCSFrames[fi] = true;
    228     }
    229   }
    230 
    231   unsigned createJumpTableUId() {
    232     return JumpTableUId++;
    233   }
    234 
    235   unsigned getNumJumpTables() const {
    236     return JumpTableUId;
    237   }
    238 
    239   void initPICLabelUId(unsigned UId) {
    240     PICLabelUId = UId;
    241   }
    242 
    243   unsigned getNumPICLabels() const {
    244     return PICLabelUId;
    245   }
    246 
    247   unsigned createPICLabelUId() {
    248     return PICLabelUId++;
    249   }
    250 
    251   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
    252   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
    253 
    254   bool hasITBlocks() const { return HasITBlocks; }
    255   void setHasITBlocks(bool h) { HasITBlocks = h; }
    256 
    257   unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
    258   void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
    259 
    260   void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {
    261     if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)
    262       assert(0 && "Duplicate entries!");
    263   }
    264 
    265   unsigned getOriginalCPIdx(unsigned CloneIdx) const {
    266     DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);
    267     if (I != CPEClones.end())
    268       return I->second;
    269     else
    270       return -1U;
    271   }
    272 };
    273 } // End llvm namespace
    274 
    275 #endif // ARMMACHINEFUNCTIONINFO_H
    276