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 
     29   /// isThumb - True if this function is compiled under Thumb mode.
     30   /// Used to initialized Align, so must precede it.
     31   bool isThumb;
     32 
     33   /// hasThumb2 - True if the target architecture supports Thumb2. Do not use
     34   /// to determine if function is compiled under Thumb mode, for that use
     35   /// 'isThumb'.
     36   bool hasThumb2;
     37 
     38   /// VarArgsRegSaveSize - Size of the register save area for vararg functions.
     39   ///
     40   unsigned VarArgsRegSaveSize;
     41 
     42   /// HasStackFrame - True if this function has a stack frame. Set by
     43   /// processFunctionBeforeCalleeSavedScan().
     44   bool HasStackFrame;
     45 
     46   /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by
     47   /// emitPrologue.
     48   bool RestoreSPFromFP;
     49 
     50   /// LRSpilledForFarJump - True if the LR register has been for spilled to
     51   /// enable far jump.
     52   bool LRSpilledForFarJump;
     53 
     54   /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
     55   /// spill stack offset.
     56   unsigned FramePtrSpillOffset;
     57 
     58   /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
     59   /// register spills areas. For Mac OS X:
     60   ///
     61   /// GPR callee-saved (1) : r4, r5, r6, r7, lr
     62   /// --------------------------------------------
     63   /// GPR callee-saved (2) : r8, r10, r11
     64   /// --------------------------------------------
     65   /// DPR callee-saved : d8 - d15
     66   unsigned GPRCS1Offset;
     67   unsigned GPRCS2Offset;
     68   unsigned DPRCSOffset;
     69 
     70   /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
     71   /// areas.
     72   unsigned GPRCS1Size;
     73   unsigned GPRCS2Size;
     74   unsigned DPRCSSize;
     75 
     76   /// GPRCS1Frames, GPRCS2Frames, DPRCSFrames - Keeps track of frame indices
     77   /// which belong to these spill areas.
     78   BitVector GPRCS1Frames;
     79   BitVector GPRCS2Frames;
     80   BitVector DPRCSFrames;
     81 
     82   /// JumpTableUId - Unique id for jumptables.
     83   ///
     84   unsigned JumpTableUId;
     85 
     86   unsigned PICLabelUId;
     87 
     88   /// VarArgsFrameIndex - FrameIndex for start of varargs area.
     89   int VarArgsFrameIndex;
     90 
     91   /// HasITBlocks - True if IT blocks have been inserted.
     92   bool HasITBlocks;
     93 
     94   /// CPEClones - Track constant pool entries clones created by Constant Island
     95   /// pass.
     96   DenseMap<unsigned, unsigned> CPEClones;
     97 
     98 public:
     99   ARMFunctionInfo() :
    100     isThumb(false),
    101     hasThumb2(false),
    102     VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
    103     LRSpilledForFarJump(false),
    104     FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
    105     GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
    106     GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0),
    107     JumpTableUId(0), PICLabelUId(0),
    108     VarArgsFrameIndex(0), HasITBlocks(false) {}
    109 
    110   explicit ARMFunctionInfo(MachineFunction &MF) :
    111     isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
    112     hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()),
    113     VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
    114     LRSpilledForFarJump(false),
    115     FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
    116     GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
    117     GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32),
    118     JumpTableUId(0), PICLabelUId(0),
    119     VarArgsFrameIndex(0), HasITBlocks(false) {}
    120 
    121   bool isThumbFunction() const { return isThumb; }
    122   bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
    123   bool isThumb2Function() const { return isThumb && hasThumb2; }
    124 
    125   unsigned getVarArgsRegSaveSize() const { return VarArgsRegSaveSize; }
    126   void setVarArgsRegSaveSize(unsigned s) { VarArgsRegSaveSize = s; }
    127 
    128   bool hasStackFrame() const { return HasStackFrame; }
    129   void setHasStackFrame(bool s) { HasStackFrame = s; }
    130 
    131   bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
    132   void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }
    133 
    134   bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
    135   void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
    136 
    137   unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
    138   void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
    139 
    140   unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
    141   unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
    142   unsigned getDPRCalleeSavedAreaOffset()  const { return DPRCSOffset; }
    143 
    144   void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
    145   void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
    146   void setDPRCalleeSavedAreaOffset(unsigned o)  { DPRCSOffset = o; }
    147 
    148   unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
    149   unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
    150   unsigned getDPRCalleeSavedAreaSize()  const { return DPRCSSize; }
    151 
    152   void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
    153   void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
    154   void setDPRCalleeSavedAreaSize(unsigned s)  { DPRCSSize = s; }
    155 
    156   bool isGPRCalleeSavedArea1Frame(int fi) const {
    157     if (fi < 0 || fi >= (int)GPRCS1Frames.size())
    158       return false;
    159     return GPRCS1Frames[fi];
    160   }
    161   bool isGPRCalleeSavedArea2Frame(int fi) const {
    162     if (fi < 0 || fi >= (int)GPRCS2Frames.size())
    163       return false;
    164     return GPRCS2Frames[fi];
    165   }
    166   bool isDPRCalleeSavedAreaFrame(int fi) const {
    167     if (fi < 0 || fi >= (int)DPRCSFrames.size())
    168       return false;
    169     return DPRCSFrames[fi];
    170   }
    171 
    172   void addGPRCalleeSavedArea1Frame(int fi) {
    173     if (fi >= 0) {
    174       int Size = GPRCS1Frames.size();
    175       if (fi >= Size) {
    176         Size *= 2;
    177         if (fi >= Size)
    178           Size = fi+1;
    179         GPRCS1Frames.resize(Size);
    180       }
    181       GPRCS1Frames[fi] = true;
    182     }
    183   }
    184   void addGPRCalleeSavedArea2Frame(int fi) {
    185     if (fi >= 0) {
    186       int Size = GPRCS2Frames.size();
    187       if (fi >= Size) {
    188         Size *= 2;
    189         if (fi >= Size)
    190           Size = fi+1;
    191         GPRCS2Frames.resize(Size);
    192       }
    193       GPRCS2Frames[fi] = true;
    194     }
    195   }
    196   void addDPRCalleeSavedAreaFrame(int fi) {
    197     if (fi >= 0) {
    198       int Size = DPRCSFrames.size();
    199       if (fi >= Size) {
    200         Size *= 2;
    201         if (fi >= Size)
    202           Size = fi+1;
    203         DPRCSFrames.resize(Size);
    204       }
    205       DPRCSFrames[fi] = true;
    206     }
    207   }
    208 
    209   unsigned createJumpTableUId() {
    210     return JumpTableUId++;
    211   }
    212 
    213   unsigned getNumJumpTables() const {
    214     return JumpTableUId;
    215   }
    216 
    217   void initPICLabelUId(unsigned UId) {
    218     PICLabelUId = UId;
    219   }
    220 
    221   unsigned getNumPICLabels() const {
    222     return PICLabelUId;
    223   }
    224 
    225   unsigned createPICLabelUId() {
    226     return PICLabelUId++;
    227   }
    228 
    229   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
    230   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
    231 
    232   bool hasITBlocks() const { return HasITBlocks; }
    233   void setHasITBlocks(bool h) { HasITBlocks = h; }
    234 
    235   void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {
    236     if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)
    237       assert(0 && "Duplicate entries!");
    238   }
    239 
    240   unsigned getOriginalCPIdx(unsigned CloneIdx) const {
    241     DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);
    242     if (I != CPEClones.end())
    243       return I->second;
    244     else
    245       return -1U;
    246   }
    247 };
    248 } // End llvm namespace
    249 
    250 #endif // ARMMACHINEFUNCTIONINFO_H
    251