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