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