1 //===-- ARMMachineFunctionInfo.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 LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H 15 #define LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H 16 17 #include "ARMSubtarget.h" 18 #include "llvm/ADT/DenseMap.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 > 4, and GPRs-part-size mod StackAlignment != 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 /// ReturnRegsCount - Number of registers used up in the return. 51 unsigned ReturnRegsCount; 52 53 /// HasStackFrame - True if this function has a stack frame. Set by 54 /// determineCalleeSaves(). 55 bool HasStackFrame; 56 57 /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by 58 /// emitPrologue. 59 bool RestoreSPFromFP; 60 61 /// LRSpilledForFarJump - True if the LR register has been for spilled to 62 /// enable far jump. 63 bool LRSpilledForFarJump; 64 65 /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer 66 /// spill stack offset. 67 unsigned FramePtrSpillOffset; 68 69 /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved 70 /// register spills areas. For Mac OS X: 71 /// 72 /// GPR callee-saved (1) : r4, r5, r6, r7, lr 73 /// -------------------------------------------- 74 /// GPR callee-saved (2) : r8, r10, r11 75 /// -------------------------------------------- 76 /// DPR callee-saved : d8 - d15 77 /// 78 /// Also see AlignedDPRCSRegs below. Not all D-regs need to go in area 3. 79 /// Some may be spilled after the stack has been realigned. 80 unsigned GPRCS1Offset; 81 unsigned GPRCS2Offset; 82 unsigned DPRCSOffset; 83 84 /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills 85 /// areas. 86 unsigned GPRCS1Size; 87 unsigned GPRCS2Size; 88 unsigned DPRCSAlignGapSize; 89 unsigned DPRCSSize; 90 91 /// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in 92 /// the aligned portion of the stack frame. This is always a contiguous 93 /// sequence of D-registers starting from d8. 94 /// 95 /// We do not keep track of the frame indices used for these registers - they 96 /// behave like any other frame index in the aligned stack frame. These 97 /// registers also aren't included in DPRCSSize above. 98 unsigned NumAlignedDPRCS2Regs; 99 100 unsigned PICLabelUId; 101 102 /// VarArgsFrameIndex - FrameIndex for start of varargs area. 103 int VarArgsFrameIndex; 104 105 /// HasITBlocks - True if IT blocks have been inserted. 106 bool HasITBlocks; 107 108 /// CPEClones - Track constant pool entries clones created by Constant Island 109 /// pass. 110 DenseMap<unsigned, unsigned> CPEClones; 111 112 /// ArgumentStackSize - amount of bytes on stack consumed by the arguments 113 /// being passed on the stack 114 unsigned ArgumentStackSize; 115 116 /// CoalescedWeights - mapping of basic blocks to the rolling counter of 117 /// coalesced weights. 118 DenseMap<const MachineBasicBlock*, unsigned> CoalescedWeights; 119 120 /// True if this function has a subset of CSRs that is handled explicitly via 121 /// copies. 122 bool IsSplitCSR; 123 124 /// Globals that have had their storage promoted into the constant pool. 125 SmallPtrSet<const GlobalVariable*,2> PromotedGlobals; 126 127 /// The amount the literal pool has been increasedby due to promoted globals. 128 int PromotedGlobalsIncrease; 129 130 public: 131 ARMFunctionInfo() : 132 isThumb(false), 133 hasThumb2(false), 134 ArgRegsSaveSize(0), ReturnRegsCount(0), HasStackFrame(false), 135 RestoreSPFromFP(false), 136 LRSpilledForFarJump(false), 137 FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0), 138 GPRCS1Size(0), GPRCS2Size(0), DPRCSAlignGapSize(0), DPRCSSize(0), 139 NumAlignedDPRCS2Regs(0), PICLabelUId(0), 140 VarArgsFrameIndex(0), HasITBlocks(false), IsSplitCSR(false), 141 PromotedGlobalsIncrease(0) {} 142 143 explicit ARMFunctionInfo(MachineFunction &MF); 144 145 bool isThumbFunction() const { return isThumb; } 146 bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; } 147 bool isThumb2Function() const { return isThumb && hasThumb2; } 148 149 unsigned getStoredByValParamsPadding() const { return StByValParamsPadding; } 150 void setStoredByValParamsPadding(unsigned p) { StByValParamsPadding = p; } 151 152 unsigned getArgRegsSaveSize() const { return ArgRegsSaveSize; } 153 void setArgRegsSaveSize(unsigned s) { ArgRegsSaveSize = s; } 154 155 unsigned getReturnRegsCount() const { return ReturnRegsCount; } 156 void setReturnRegsCount(unsigned s) { ReturnRegsCount = s; } 157 158 bool hasStackFrame() const { return HasStackFrame; } 159 void setHasStackFrame(bool s) { HasStackFrame = s; } 160 161 bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; } 162 void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; } 163 164 bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; } 165 void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; } 166 167 unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; } 168 void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; } 169 170 unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; } 171 void setNumAlignedDPRCS2Regs(unsigned n) { NumAlignedDPRCS2Regs = n; } 172 173 unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; } 174 unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; } 175 unsigned getDPRCalleeSavedAreaOffset() const { return DPRCSOffset; } 176 177 void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; } 178 void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; } 179 void setDPRCalleeSavedAreaOffset(unsigned o) { DPRCSOffset = o; } 180 181 unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; } 182 unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; } 183 unsigned getDPRCalleeSavedGapSize() const { return DPRCSAlignGapSize; } 184 unsigned getDPRCalleeSavedAreaSize() const { return DPRCSSize; } 185 186 void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; } 187 void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; } 188 void setDPRCalleeSavedGapSize(unsigned s) { DPRCSAlignGapSize = s; } 189 void setDPRCalleeSavedAreaSize(unsigned s) { DPRCSSize = s; } 190 191 unsigned getArgumentStackSize() const { return ArgumentStackSize; } 192 void setArgumentStackSize(unsigned size) { ArgumentStackSize = size; } 193 194 void initPICLabelUId(unsigned UId) { 195 PICLabelUId = UId; 196 } 197 198 unsigned getNumPICLabels() const { 199 return PICLabelUId; 200 } 201 202 unsigned createPICLabelUId() { 203 return PICLabelUId++; 204 } 205 206 int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } 207 void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; } 208 209 bool hasITBlocks() const { return HasITBlocks; } 210 void setHasITBlocks(bool h) { HasITBlocks = h; } 211 212 bool isSplitCSR() const { return IsSplitCSR; } 213 void setIsSplitCSR(bool s) { IsSplitCSR = s; } 214 215 void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) { 216 if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second) 217 llvm_unreachable("Duplicate entries!"); 218 } 219 220 unsigned getOriginalCPIdx(unsigned CloneIdx) const { 221 DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx); 222 if (I != CPEClones.end()) 223 return I->second; 224 else 225 return -1U; 226 } 227 228 DenseMap<const MachineBasicBlock*, unsigned>::iterator getCoalescedWeight( 229 MachineBasicBlock* MBB) { 230 auto It = CoalescedWeights.find(MBB); 231 if (It == CoalescedWeights.end()) { 232 It = CoalescedWeights.insert(std::make_pair(MBB, 0)).first; 233 } 234 return It; 235 } 236 237 /// Indicate to the backend that \c GV has had its storage changed to inside 238 /// a constant pool. This means it no longer needs to be emitted as a 239 /// global variable. 240 void markGlobalAsPromotedToConstantPool(const GlobalVariable *GV) { 241 PromotedGlobals.insert(GV); 242 } 243 SmallPtrSet<const GlobalVariable*, 2>& getGlobalsPromotedToConstantPool() { 244 return PromotedGlobals; 245 } 246 int getPromotedConstpoolIncrease() const { 247 return PromotedGlobalsIncrease; 248 } 249 void setPromotedConstpoolIncrease(int Sz) { 250 PromotedGlobalsIncrease = Sz; 251 } 252 }; 253 } // End llvm namespace 254 255 #endif 256