1f4a2713aSLionel Sambuc //===-- ARMMachineFuctionInfo.h - ARM machine function info -----*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file declares ARM-specific per-machine-function information.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14*0a6a1f1dSLionel Sambuc #ifndef LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
15*0a6a1f1dSLionel Sambuc #define LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
16f4a2713aSLionel Sambuc 
17f4a2713aSLionel Sambuc #include "ARMSubtarget.h"
18f4a2713aSLionel Sambuc #include "llvm/ADT/BitVector.h"
19*0a6a1f1dSLionel Sambuc #include "llvm/ADT/DenseMap.h"
20f4a2713aSLionel Sambuc #include "llvm/CodeGen/MachineFunction.h"
21f4a2713aSLionel Sambuc #include "llvm/Target/TargetMachine.h"
22f4a2713aSLionel Sambuc #include "llvm/Target/TargetRegisterInfo.h"
23f4a2713aSLionel Sambuc 
24f4a2713aSLionel Sambuc namespace llvm {
25f4a2713aSLionel Sambuc 
26f4a2713aSLionel Sambuc /// ARMFunctionInfo - This class is derived from MachineFunctionInfo and
27f4a2713aSLionel Sambuc /// contains private ARM-specific information for each MachineFunction.
28f4a2713aSLionel Sambuc class ARMFunctionInfo : public MachineFunctionInfo {
29f4a2713aSLionel Sambuc   virtual void anchor();
30f4a2713aSLionel Sambuc 
31f4a2713aSLionel Sambuc   /// isThumb - True if this function is compiled under Thumb mode.
32f4a2713aSLionel Sambuc   /// Used to initialized Align, so must precede it.
33f4a2713aSLionel Sambuc   bool isThumb;
34f4a2713aSLionel Sambuc 
35f4a2713aSLionel Sambuc   /// hasThumb2 - True if the target architecture supports Thumb2. Do not use
36f4a2713aSLionel Sambuc   /// to determine if function is compiled under Thumb mode, for that use
37f4a2713aSLionel Sambuc   /// 'isThumb'.
38f4a2713aSLionel Sambuc   bool hasThumb2;
39f4a2713aSLionel Sambuc 
40f4a2713aSLionel Sambuc   /// StByValParamsPadding - For parameter that is split between
41f4a2713aSLionel Sambuc   /// GPRs and memory; while recovering GPRs part, when
42*0a6a1f1dSLionel Sambuc   /// StackAlignment > 4, and GPRs-part-size mod StackAlignment != 0,
43f4a2713aSLionel Sambuc   /// we need to insert gap before parameter start address. It allows to
44f4a2713aSLionel Sambuc   /// "attach" GPR-part to the part that was passed via stack.
45f4a2713aSLionel Sambuc   unsigned StByValParamsPadding;
46f4a2713aSLionel Sambuc 
47f4a2713aSLionel Sambuc   /// VarArgsRegSaveSize - Size of the register save area for vararg functions.
48f4a2713aSLionel Sambuc   ///
49f4a2713aSLionel Sambuc   unsigned ArgRegsSaveSize;
50f4a2713aSLionel Sambuc 
51*0a6a1f1dSLionel Sambuc   /// ReturnRegsCount - Number of registers used up in the return.
52*0a6a1f1dSLionel Sambuc   unsigned ReturnRegsCount;
53*0a6a1f1dSLionel Sambuc 
54f4a2713aSLionel Sambuc   /// HasStackFrame - True if this function has a stack frame. Set by
55f4a2713aSLionel Sambuc   /// processFunctionBeforeCalleeSavedScan().
56f4a2713aSLionel Sambuc   bool HasStackFrame;
57f4a2713aSLionel Sambuc 
58f4a2713aSLionel Sambuc   /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by
59f4a2713aSLionel Sambuc   /// emitPrologue.
60f4a2713aSLionel Sambuc   bool RestoreSPFromFP;
61f4a2713aSLionel Sambuc 
62f4a2713aSLionel Sambuc   /// LRSpilledForFarJump - True if the LR register has been for spilled to
63f4a2713aSLionel Sambuc   /// enable far jump.
64f4a2713aSLionel Sambuc   bool LRSpilledForFarJump;
65f4a2713aSLionel Sambuc 
66f4a2713aSLionel Sambuc   /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
67f4a2713aSLionel Sambuc   /// spill stack offset.
68f4a2713aSLionel Sambuc   unsigned FramePtrSpillOffset;
69f4a2713aSLionel Sambuc 
70f4a2713aSLionel Sambuc   /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
71f4a2713aSLionel Sambuc   /// register spills areas. For Mac OS X:
72f4a2713aSLionel Sambuc   ///
73f4a2713aSLionel Sambuc   /// GPR callee-saved (1) : r4, r5, r6, r7, lr
74f4a2713aSLionel Sambuc   /// --------------------------------------------
75f4a2713aSLionel Sambuc   /// GPR callee-saved (2) : r8, r10, r11
76f4a2713aSLionel Sambuc   /// --------------------------------------------
77f4a2713aSLionel Sambuc   /// DPR callee-saved : d8 - d15
78f4a2713aSLionel Sambuc   ///
79f4a2713aSLionel Sambuc   /// Also see AlignedDPRCSRegs below. Not all D-regs need to go in area 3.
80f4a2713aSLionel Sambuc   /// Some may be spilled after the stack has been realigned.
81f4a2713aSLionel Sambuc   unsigned GPRCS1Offset;
82f4a2713aSLionel Sambuc   unsigned GPRCS2Offset;
83f4a2713aSLionel Sambuc   unsigned DPRCSOffset;
84f4a2713aSLionel Sambuc 
85f4a2713aSLionel Sambuc   /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
86f4a2713aSLionel Sambuc   /// areas.
87f4a2713aSLionel Sambuc   unsigned GPRCS1Size;
88f4a2713aSLionel Sambuc   unsigned GPRCS2Size;
89*0a6a1f1dSLionel Sambuc   unsigned DPRCSAlignGapSize;
90f4a2713aSLionel Sambuc   unsigned DPRCSSize;
91f4a2713aSLionel Sambuc 
92f4a2713aSLionel Sambuc   /// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in
93f4a2713aSLionel Sambuc   /// the aligned portion of the stack frame.  This is always a contiguous
94f4a2713aSLionel Sambuc   /// sequence of D-registers starting from d8.
95f4a2713aSLionel Sambuc   ///
96f4a2713aSLionel Sambuc   /// We do not keep track of the frame indices used for these registers - they
97f4a2713aSLionel Sambuc   /// behave like any other frame index in the aligned stack frame.  These
98f4a2713aSLionel Sambuc   /// registers also aren't included in DPRCSSize above.
99f4a2713aSLionel Sambuc   unsigned NumAlignedDPRCS2Regs;
100f4a2713aSLionel Sambuc 
101f4a2713aSLionel Sambuc   /// JumpTableUId - Unique id for jumptables.
102f4a2713aSLionel Sambuc   ///
103f4a2713aSLionel Sambuc   unsigned JumpTableUId;
104f4a2713aSLionel Sambuc 
105f4a2713aSLionel Sambuc   unsigned PICLabelUId;
106f4a2713aSLionel Sambuc 
107f4a2713aSLionel Sambuc   /// VarArgsFrameIndex - FrameIndex for start of varargs area.
108f4a2713aSLionel Sambuc   int VarArgsFrameIndex;
109f4a2713aSLionel Sambuc 
110f4a2713aSLionel Sambuc   /// HasITBlocks - True if IT blocks have been inserted.
111f4a2713aSLionel Sambuc   bool HasITBlocks;
112f4a2713aSLionel Sambuc 
113f4a2713aSLionel Sambuc   /// CPEClones - Track constant pool entries clones created by Constant Island
114f4a2713aSLionel Sambuc   /// pass.
115f4a2713aSLionel Sambuc   DenseMap<unsigned, unsigned> CPEClones;
116f4a2713aSLionel Sambuc 
117f4a2713aSLionel Sambuc   /// GlobalBaseReg - keeps track of the virtual register initialized for
118f4a2713aSLionel Sambuc   /// use as the global base register. This is used for PIC in some PIC
119f4a2713aSLionel Sambuc   /// relocation models.
120f4a2713aSLionel Sambuc   unsigned GlobalBaseReg;
121f4a2713aSLionel Sambuc 
122*0a6a1f1dSLionel Sambuc   /// ArgumentStackSize - amount of bytes on stack consumed by the arguments
123*0a6a1f1dSLionel Sambuc   /// being passed on the stack
124*0a6a1f1dSLionel Sambuc   unsigned ArgumentStackSize;
125*0a6a1f1dSLionel Sambuc 
126*0a6a1f1dSLionel Sambuc   /// CoalescedWeights - mapping of basic blocks to the rolling counter of
127*0a6a1f1dSLionel Sambuc   /// coalesced weights.
128*0a6a1f1dSLionel Sambuc   DenseMap<const MachineBasicBlock*, unsigned> CoalescedWeights;
129*0a6a1f1dSLionel Sambuc 
130f4a2713aSLionel Sambuc public:
ARMFunctionInfo()131f4a2713aSLionel Sambuc   ARMFunctionInfo() :
132f4a2713aSLionel Sambuc     isThumb(false),
133f4a2713aSLionel Sambuc     hasThumb2(false),
134*0a6a1f1dSLionel Sambuc     ArgRegsSaveSize(0), ReturnRegsCount(0), HasStackFrame(false),
135*0a6a1f1dSLionel Sambuc     RestoreSPFromFP(false),
136f4a2713aSLionel Sambuc     LRSpilledForFarJump(false),
137f4a2713aSLionel Sambuc     FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
138*0a6a1f1dSLionel Sambuc     GPRCS1Size(0), GPRCS2Size(0), DPRCSAlignGapSize(0), DPRCSSize(0),
139f4a2713aSLionel Sambuc     NumAlignedDPRCS2Regs(0),
140f4a2713aSLionel Sambuc     JumpTableUId(0), PICLabelUId(0),
141f4a2713aSLionel Sambuc     VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {}
142f4a2713aSLionel Sambuc 
143*0a6a1f1dSLionel Sambuc   explicit ARMFunctionInfo(MachineFunction &MF);
144f4a2713aSLionel Sambuc 
isThumbFunction()145f4a2713aSLionel Sambuc   bool isThumbFunction() const { return isThumb; }
isThumb1OnlyFunction()146f4a2713aSLionel Sambuc   bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
isThumb2Function()147f4a2713aSLionel Sambuc   bool isThumb2Function() const { return isThumb && hasThumb2; }
148f4a2713aSLionel Sambuc 
getStoredByValParamsPadding()149f4a2713aSLionel Sambuc   unsigned getStoredByValParamsPadding() const { return StByValParamsPadding; }
setStoredByValParamsPadding(unsigned p)150f4a2713aSLionel Sambuc   void setStoredByValParamsPadding(unsigned p) { StByValParamsPadding = p; }
151f4a2713aSLionel Sambuc 
152f4a2713aSLionel Sambuc   unsigned getArgRegsSaveSize(unsigned Align = 0) const {
153f4a2713aSLionel Sambuc     if (!Align)
154f4a2713aSLionel Sambuc       return ArgRegsSaveSize;
155f4a2713aSLionel Sambuc     return (ArgRegsSaveSize + Align - 1) & ~(Align - 1);
156f4a2713aSLionel Sambuc   }
setArgRegsSaveSize(unsigned s)157f4a2713aSLionel Sambuc   void setArgRegsSaveSize(unsigned s) { ArgRegsSaveSize = s; }
158f4a2713aSLionel Sambuc 
getReturnRegsCount()159*0a6a1f1dSLionel Sambuc   unsigned getReturnRegsCount() const { return ReturnRegsCount; }
setReturnRegsCount(unsigned s)160*0a6a1f1dSLionel Sambuc   void setReturnRegsCount(unsigned s) { ReturnRegsCount = s; }
161*0a6a1f1dSLionel Sambuc 
hasStackFrame()162f4a2713aSLionel Sambuc   bool hasStackFrame() const { return HasStackFrame; }
setHasStackFrame(bool s)163f4a2713aSLionel Sambuc   void setHasStackFrame(bool s) { HasStackFrame = s; }
164f4a2713aSLionel Sambuc 
shouldRestoreSPFromFP()165f4a2713aSLionel Sambuc   bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
setShouldRestoreSPFromFP(bool s)166f4a2713aSLionel Sambuc   void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }
167f4a2713aSLionel Sambuc 
isLRSpilledForFarJump()168f4a2713aSLionel Sambuc   bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
setLRIsSpilledForFarJump(bool s)169f4a2713aSLionel Sambuc   void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
170f4a2713aSLionel Sambuc 
getFramePtrSpillOffset()171f4a2713aSLionel Sambuc   unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
setFramePtrSpillOffset(unsigned o)172f4a2713aSLionel Sambuc   void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
173f4a2713aSLionel Sambuc 
getNumAlignedDPRCS2Regs()174f4a2713aSLionel Sambuc   unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; }
setNumAlignedDPRCS2Regs(unsigned n)175f4a2713aSLionel Sambuc   void setNumAlignedDPRCS2Regs(unsigned n) { NumAlignedDPRCS2Regs = n; }
176f4a2713aSLionel Sambuc 
getGPRCalleeSavedArea1Offset()177f4a2713aSLionel Sambuc   unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
getGPRCalleeSavedArea2Offset()178f4a2713aSLionel Sambuc   unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
getDPRCalleeSavedAreaOffset()179f4a2713aSLionel Sambuc   unsigned getDPRCalleeSavedAreaOffset()  const { return DPRCSOffset; }
180f4a2713aSLionel Sambuc 
setGPRCalleeSavedArea1Offset(unsigned o)181f4a2713aSLionel Sambuc   void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
setGPRCalleeSavedArea2Offset(unsigned o)182f4a2713aSLionel Sambuc   void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
setDPRCalleeSavedAreaOffset(unsigned o)183f4a2713aSLionel Sambuc   void setDPRCalleeSavedAreaOffset(unsigned o)  { DPRCSOffset = o; }
184f4a2713aSLionel Sambuc 
getGPRCalleeSavedArea1Size()185f4a2713aSLionel Sambuc   unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
getGPRCalleeSavedArea2Size()186f4a2713aSLionel Sambuc   unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
getDPRCalleeSavedGapSize()187*0a6a1f1dSLionel Sambuc   unsigned getDPRCalleeSavedGapSize() const   { return DPRCSAlignGapSize; }
getDPRCalleeSavedAreaSize()188f4a2713aSLionel Sambuc   unsigned getDPRCalleeSavedAreaSize()  const { return DPRCSSize; }
189f4a2713aSLionel Sambuc 
setGPRCalleeSavedArea1Size(unsigned s)190f4a2713aSLionel Sambuc   void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
setGPRCalleeSavedArea2Size(unsigned s)191f4a2713aSLionel Sambuc   void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
setDPRCalleeSavedGapSize(unsigned s)192*0a6a1f1dSLionel Sambuc   void setDPRCalleeSavedGapSize(unsigned s)   { DPRCSAlignGapSize = s; }
setDPRCalleeSavedAreaSize(unsigned s)193f4a2713aSLionel Sambuc   void setDPRCalleeSavedAreaSize(unsigned s)  { DPRCSSize = s; }
194f4a2713aSLionel Sambuc 
getArgumentStackSize()195*0a6a1f1dSLionel Sambuc   unsigned getArgumentStackSize() const { return ArgumentStackSize; }
setArgumentStackSize(unsigned size)196*0a6a1f1dSLionel Sambuc   void setArgumentStackSize(unsigned size) { ArgumentStackSize = size; }
197*0a6a1f1dSLionel Sambuc 
createJumpTableUId()198f4a2713aSLionel Sambuc   unsigned createJumpTableUId() {
199f4a2713aSLionel Sambuc     return JumpTableUId++;
200f4a2713aSLionel Sambuc   }
201f4a2713aSLionel Sambuc 
getNumJumpTables()202f4a2713aSLionel Sambuc   unsigned getNumJumpTables() const {
203f4a2713aSLionel Sambuc     return JumpTableUId;
204f4a2713aSLionel Sambuc   }
205f4a2713aSLionel Sambuc 
initPICLabelUId(unsigned UId)206f4a2713aSLionel Sambuc   void initPICLabelUId(unsigned UId) {
207f4a2713aSLionel Sambuc     PICLabelUId = UId;
208f4a2713aSLionel Sambuc   }
209f4a2713aSLionel Sambuc 
getNumPICLabels()210f4a2713aSLionel Sambuc   unsigned getNumPICLabels() const {
211f4a2713aSLionel Sambuc     return PICLabelUId;
212f4a2713aSLionel Sambuc   }
213f4a2713aSLionel Sambuc 
createPICLabelUId()214f4a2713aSLionel Sambuc   unsigned createPICLabelUId() {
215f4a2713aSLionel Sambuc     return PICLabelUId++;
216f4a2713aSLionel Sambuc   }
217f4a2713aSLionel Sambuc 
getVarArgsFrameIndex()218f4a2713aSLionel Sambuc   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
setVarArgsFrameIndex(int Index)219f4a2713aSLionel Sambuc   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
220f4a2713aSLionel Sambuc 
hasITBlocks()221f4a2713aSLionel Sambuc   bool hasITBlocks() const { return HasITBlocks; }
setHasITBlocks(bool h)222f4a2713aSLionel Sambuc   void setHasITBlocks(bool h) { HasITBlocks = h; }
223f4a2713aSLionel Sambuc 
getGlobalBaseReg()224f4a2713aSLionel Sambuc   unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
setGlobalBaseReg(unsigned Reg)225f4a2713aSLionel Sambuc   void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
226f4a2713aSLionel Sambuc 
recordCPEClone(unsigned CPIdx,unsigned CPCloneIdx)227f4a2713aSLionel Sambuc   void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {
228f4a2713aSLionel Sambuc     if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)
229*0a6a1f1dSLionel Sambuc       llvm_unreachable("Duplicate entries!");
230f4a2713aSLionel Sambuc   }
231f4a2713aSLionel Sambuc 
getOriginalCPIdx(unsigned CloneIdx)232f4a2713aSLionel Sambuc   unsigned getOriginalCPIdx(unsigned CloneIdx) const {
233f4a2713aSLionel Sambuc     DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);
234f4a2713aSLionel Sambuc     if (I != CPEClones.end())
235f4a2713aSLionel Sambuc       return I->second;
236f4a2713aSLionel Sambuc     else
237f4a2713aSLionel Sambuc       return -1U;
238f4a2713aSLionel Sambuc   }
239*0a6a1f1dSLionel Sambuc 
getCoalescedWeight(MachineBasicBlock * MBB)240*0a6a1f1dSLionel Sambuc   DenseMap<const MachineBasicBlock*, unsigned>::iterator getCoalescedWeight(
241*0a6a1f1dSLionel Sambuc                                                   MachineBasicBlock* MBB) {
242*0a6a1f1dSLionel Sambuc     auto It = CoalescedWeights.find(MBB);
243*0a6a1f1dSLionel Sambuc     if (It == CoalescedWeights.end()) {
244*0a6a1f1dSLionel Sambuc       It = CoalescedWeights.insert(std::make_pair(MBB, 0)).first;
245*0a6a1f1dSLionel Sambuc     }
246*0a6a1f1dSLionel Sambuc     return It;
247*0a6a1f1dSLionel Sambuc   }
248f4a2713aSLionel Sambuc };
249f4a2713aSLionel Sambuc } // End llvm namespace
250f4a2713aSLionel Sambuc 
251*0a6a1f1dSLionel Sambuc #endif
252