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
23namespace llvm {
24
25/// ARMFunctionInfo - This class is derived from MachineFunctionInfo and
26/// contains private ARM-specific information for each MachineFunction.
27class 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
116public:
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