ARMMachineFunctionInfo.h revision 234353
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
111public:
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