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/CodeGen/MachineFunction.h"
     19 #include "llvm/Target/TargetRegisterInfo.h"
     20 #include "llvm/Target/TargetMachine.h"
     21 #include "llvm/ADT/BitVector.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 public:
    112   ARMFunctionInfo() :
    113     isThumb(false),
    114     hasThumb2(false),
    115     VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
    116     LRSpilledForFarJump(false),
    117     FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
    118     GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
    119     GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0),
    120     NumAlignedDPRCS2Regs(0),
    121     JumpTableUId(0), PICLabelUId(0),
    122     VarArgsFrameIndex(0), HasITBlocks(false) {}
    123 
    124   explicit ARMFunctionInfo(MachineFunction &MF) :
    125     isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
    126     hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()),
    127     VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
    128     LRSpilledForFarJump(false),
    129     FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
    130     GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
    131     GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32),
    132     JumpTableUId(0), PICLabelUId(0),
    133     VarArgsFrameIndex(0), HasITBlocks(false) {}
    134 
    135   bool isThumbFunction() const { return isThumb; }
    136   bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
    137   bool isThumb2Function() const { return isThumb && hasThumb2; }
    138 
    139   unsigned getVarArgsRegSaveSize() const { return VarArgsRegSaveSize; }
    140   void setVarArgsRegSaveSize(unsigned s) { VarArgsRegSaveSize = s; }
    141 
    142   bool hasStackFrame() const { return HasStackFrame; }
    143   void setHasStackFrame(bool s) { HasStackFrame = s; }
    144 
    145   bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
    146   void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }
    147 
    148   bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
    149   void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
    150 
    151   unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
    152   void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
    153 
    154   unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; }
    155   void setNumAlignedDPRCS2Regs(unsigned n) { NumAlignedDPRCS2Regs = n; }
    156 
    157   unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
    158   unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
    159   unsigned getDPRCalleeSavedAreaOffset()  const { return DPRCSOffset; }
    160 
    161   void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
    162   void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
    163   void setDPRCalleeSavedAreaOffset(unsigned o)  { DPRCSOffset = o; }
    164 
    165   unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
    166   unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
    167   unsigned getDPRCalleeSavedAreaSize()  const { return DPRCSSize; }
    168 
    169   void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
    170   void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
    171   void setDPRCalleeSavedAreaSize(unsigned s)  { DPRCSSize = s; }
    172 
    173   bool isGPRCalleeSavedArea1Frame(int fi) const {
    174     if (fi < 0 || fi >= (int)GPRCS1Frames.size())
    175       return false;
    176     return GPRCS1Frames[fi];
    177   }
    178   bool isGPRCalleeSavedArea2Frame(int fi) const {
    179     if (fi < 0 || fi >= (int)GPRCS2Frames.size())
    180       return false;
    181     return GPRCS2Frames[fi];
    182   }
    183   bool isDPRCalleeSavedAreaFrame(int fi) const {
    184     if (fi < 0 || fi >= (int)DPRCSFrames.size())
    185       return false;
    186     return DPRCSFrames[fi];
    187   }
    188 
    189   void addGPRCalleeSavedArea1Frame(int fi) {
    190     if (fi >= 0) {
    191       int Size = GPRCS1Frames.size();
    192       if (fi >= Size) {
    193         Size *= 2;
    194         if (fi >= Size)
    195           Size = fi+1;
    196         GPRCS1Frames.resize(Size);
    197       }
    198       GPRCS1Frames[fi] = true;
    199     }
    200   }
    201   void addGPRCalleeSavedArea2Frame(int fi) {
    202     if (fi >= 0) {
    203       int Size = GPRCS2Frames.size();
    204       if (fi >= Size) {
    205         Size *= 2;
    206         if (fi >= Size)
    207           Size = fi+1;
    208         GPRCS2Frames.resize(Size);
    209       }
    210       GPRCS2Frames[fi] = true;
    211     }
    212   }
    213   void addDPRCalleeSavedAreaFrame(int fi) {
    214     if (fi >= 0) {
    215       int Size = DPRCSFrames.size();
    216       if (fi >= Size) {
    217         Size *= 2;
    218         if (fi >= Size)
    219           Size = fi+1;
    220         DPRCSFrames.resize(Size);
    221       }
    222       DPRCSFrames[fi] = true;
    223     }
    224   }
    225 
    226   unsigned createJumpTableUId() {
    227     return JumpTableUId++;
    228   }
    229 
    230   unsigned getNumJumpTables() const {
    231     return JumpTableUId;
    232   }
    233 
    234   void initPICLabelUId(unsigned UId) {
    235     PICLabelUId = UId;
    236   }
    237 
    238   unsigned getNumPICLabels() const {
    239     return PICLabelUId;
    240   }
    241 
    242   unsigned createPICLabelUId() {
    243     return PICLabelUId++;
    244   }
    245 
    246   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
    247   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
    248 
    249   bool hasITBlocks() const { return HasITBlocks; }
    250   void setHasITBlocks(bool h) { HasITBlocks = h; }
    251 
    252   void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {
    253     if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)
    254       assert(0 && "Duplicate entries!");
    255   }
    256 
    257   unsigned getOriginalCPIdx(unsigned CloneIdx) const {
    258     DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);
    259     if (I != CPEClones.end())
    260       return I->second;
    261     else
    262       return -1U;
    263   }
    264 };
    265 } // End llvm namespace
    266 
    267 #endif // ARMMACHINEFUNCTIONINFO_H
    268