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 /// 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 116 public: 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