1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef MAPLEBE_INCLUDE_CG_REG_INFO_H 17 #define MAPLEBE_INCLUDE_CG_REG_INFO_H 18 19 #include "isa.h" 20 #include "insn.h" 21 22 namespace maplebe { 23 constexpr size_t kSpillMemOpndNum = 4; 24 constexpr uint32 kBaseVirtualRegNO = 200; /* avoid conflicts between virtual and physical */ 25 constexpr uint32 kRegIncrStepLen = 80; /* reg number increate step length */ 26 27 class VirtualRegNode { 28 public: 29 VirtualRegNode() = default; 30 VirtualRegNode(RegType type,uint32 size)31 VirtualRegNode(RegType type, uint32 size) : regType(type), size(size), regNO(kInvalidRegNO) {} 32 33 virtual ~VirtualRegNode() = default; 34 AssignPhysicalRegister(regno_t phyRegNO)35 void AssignPhysicalRegister(regno_t phyRegNO) 36 { 37 regNO = phyRegNO; 38 } 39 GetType()40 RegType GetType() const 41 { 42 return regType; 43 } 44 GetSize()45 uint32 GetSize() const 46 { 47 return size; 48 } 49 50 private: 51 RegType regType = kRegTyUndef; 52 uint32 size = 0; /* size in bytes */ 53 regno_t regNO = kInvalidRegNO; /* physical register assigned by register allocation */ 54 }; 55 56 class VregInfo { 57 public: 58 /* Only one place to allocate vreg within cg. 59 'static' can be removed and initialized here if only allocation is from only one source. */ 60 static uint32 virtualRegCount; 61 static uint32 maxRegCount; 62 static std::vector<VirtualRegNode> vRegTable; 63 static std::unordered_map<regno_t, RegOperand *> vRegOperandTable; 64 static bool initialized; 65 VregInfo()66 VregInfo() 67 { 68 if (initialized) { 69 initialized = false; 70 return; 71 } 72 initialized = true; 73 virtualRegCount = kBaseVirtualRegNO; 74 maxRegCount = kBaseVirtualRegNO; 75 vRegTable.clear(); 76 vRegOperandTable.clear(); 77 } 78 79 ~VregInfo() = default; 80 GetNextVregNO(RegType type,uint32 size)81 uint32 GetNextVregNO(RegType type, uint32 size) 82 { 83 /* when vReg reach to maxRegCount, maxRegCount limit adds 80 every time */ 84 /* and vRegTable increases 80 elements. */ 85 if (virtualRegCount >= maxRegCount) { 86 DEBUG_ASSERT(virtualRegCount < maxRegCount + 1, "MAINTAIN FAILED"); 87 maxRegCount += kRegIncrStepLen; 88 VRegTableResize(maxRegCount); 89 } 90 #if TARGAARCH64 || TARGX86_64 || TARGRISCV64 91 if (size < k4ByteSize) { 92 size = k4ByteSize; 93 } 94 if (Triple::GetTriple().IsAarch64BeOrLe()) { 95 /* cannot handle 128 size register */ 96 if (type == kRegTyInt && size > k8ByteSize) { 97 size = k8ByteSize; 98 } 99 } 100 DEBUG_ASSERT(size == k4ByteSize || size == k8ByteSize || size == k16ByteSize, "check size"); 101 #endif 102 VRegTableValuesSet(virtualRegCount, type, size); 103 104 uint32 temp = virtualRegCount; 105 ++virtualRegCount; 106 return temp; 107 } Inc(uint32 v)108 void Inc(uint32 v) const 109 { 110 virtualRegCount += v; 111 } GetCount()112 uint32 GetCount() const 113 { 114 return virtualRegCount; 115 } SetCount(uint32 v)116 void SetCount(uint32 v) const 117 { 118 /* Vreg number can only increase. */ 119 if (virtualRegCount < v) { 120 virtualRegCount = v; 121 } 122 } 123 124 /* maxRegCount related stuff */ GetMaxRegCount()125 uint32 GetMaxRegCount() const 126 { 127 return maxRegCount; 128 } SetMaxRegCount(uint32 num)129 void SetMaxRegCount(uint32 num) 130 { 131 maxRegCount = num; 132 } IncMaxRegCount(uint32 num)133 void IncMaxRegCount(uint32 num) const 134 { 135 maxRegCount += num; 136 } 137 138 /* vRegTable related stuff */ VRegTableResize(uint32 sz)139 void VRegTableResize(uint32 sz) 140 { 141 vRegTable.resize(sz); 142 } VRegTableSize()143 uint32 VRegTableSize() const 144 { 145 return static_cast<uint32>(vRegTable.size()); 146 } VRegTableGetSize(uint32 idx)147 uint32 VRegTableGetSize(uint32 idx) const 148 { 149 return vRegTable[idx].GetSize(); 150 } VRegTableGetType(uint32 idx)151 RegType VRegTableGetType(uint32 idx) const 152 { 153 return vRegTable[idx].GetType(); 154 } VRegTableElementGet(uint32 idx)155 VirtualRegNode &VRegTableElementGet(uint32 idx) const 156 { 157 return vRegTable[idx]; 158 } VRegTableElementSet(uint32 idx,VirtualRegNode * node)159 void VRegTableElementSet(uint32 idx, VirtualRegNode *node) 160 { 161 vRegTable[idx] = *node; 162 } VRegTableValuesSet(uint32 idx,RegType rt,uint32 sz)163 void VRegTableValuesSet(uint32 idx, RegType rt, uint32 sz) const 164 { 165 new (&vRegTable[idx]) VirtualRegNode(rt, sz); 166 } VRegOperandTableSet(regno_t regNO,RegOperand * rp)167 void VRegOperandTableSet(regno_t regNO, RegOperand *rp) const 168 { 169 vRegOperandTable[regNO] = rp; 170 } 171 }; 172 using VRegNo = regno_t; 173 using PRegNo = regno_t; 174 using RegNoPair = std::pair<VRegNo, PRegNo>; 175 176 class RegisterInfo { 177 public: RegisterInfo(MapleAllocator & mallocator)178 explicit RegisterInfo(MapleAllocator &mallocator) 179 : allIntRegs(mallocator.Adapter()), allFpRegs(mallocator.Adapter()), allregs(mallocator.Adapter()) 180 { 181 } 182 ~RegisterInfo()183 virtual ~RegisterInfo() 184 { 185 cgFunc = nullptr; 186 } 187 188 virtual void Init() = 0; 189 virtual void Fini() = 0; AddToAllRegs(regno_t regNo)190 void AddToAllRegs(regno_t regNo) 191 { 192 (void)allregs.insert(regNo); 193 } GetAllRegs()194 const MapleSet<regno_t> &GetAllRegs() const 195 { 196 return allregs; 197 } AddToIntRegs(regno_t regNo)198 void AddToIntRegs(regno_t regNo) 199 { 200 (void)allIntRegs.insert(regNo); 201 } GetIntRegs()202 const MapleSet<regno_t> &GetIntRegs() const 203 { 204 return allIntRegs; 205 } AddToFpRegs(regno_t regNo)206 void AddToFpRegs(regno_t regNo) 207 { 208 (void)allFpRegs.insert(regNo); 209 } GetFpRegs()210 const MapleSet<regno_t> &GetFpRegs() const 211 { 212 return allFpRegs; 213 } SetCurrFunction(CGFunc & func)214 void SetCurrFunction(CGFunc &func) 215 { 216 cgFunc = &func; 217 } GetCurrFunction()218 CGFunc *GetCurrFunction() const 219 { 220 return cgFunc; 221 } 222 // When some registers are allocated to the callee, the caller stores a part of the registers 223 // and the callee stores another part of the registers. 224 // For these registers, it is a better choice to assign them as caller-save registers. IsPrefCallerSaveRegs(RegType type,uint32 size)225 virtual bool IsPrefCallerSaveRegs(RegType type, uint32 size) const 226 { 227 return false; 228 } IsCallerSavePartRegister(regno_t regNO,uint32 size)229 virtual bool IsCallerSavePartRegister(regno_t regNO, uint32 size) const 230 { 231 return false; 232 } 233 virtual RegOperand *GetOrCreatePhyRegOperand(regno_t regNO, uint32 size, RegType kind, uint32 flag = 0) = 0; 234 virtual bool IsGPRegister(regno_t regNO) const = 0; 235 virtual uint32 GetIntParamRegIdx(regno_t regNO) const = 0; 236 virtual uint32 GetFpParamRegIdx(regno_t regNO) const = 0; 237 virtual bool IsAvailableReg(regno_t regNO) const = 0; 238 virtual bool IsCalleeSavedReg(regno_t regno) const = 0; 239 virtual bool IsYieldPointReg(regno_t regNO) const = 0; 240 virtual bool IsUnconcernedReg(regno_t regNO) const = 0; 241 virtual bool IsVirtualRegister(const RegOperand ®Opnd) = 0; 242 virtual bool IsVirtualRegister(regno_t regno) = 0; 243 virtual uint32 GetIntRegsParmsNum() = 0; 244 virtual uint32 GetIntRetRegsNum() = 0; 245 virtual uint32 GetFpRetRegsNum() = 0; 246 virtual uint32 GetFloatRegsParmsNum() = 0; 247 virtual regno_t GetLastParamsIntReg() = 0; 248 virtual regno_t GetLastParamsFpReg() = 0; 249 virtual regno_t GetIntRetReg(uint32 idx) = 0; 250 virtual regno_t GetFpRetReg(uint32 idx) = 0; 251 virtual uint32 GetReservedSpillReg() = 0; 252 virtual uint32 GetSecondReservedSpillReg() = 0; 253 virtual uint32 GetAllRegNum() = 0; 254 virtual uint32 GetNormalUseOperandNum() = 0; 255 virtual regno_t GetInvalidReg() = 0; 256 virtual bool IsSpillRegInRA(regno_t regNO, bool has3RegOpnd) = 0; 257 virtual Insn *BuildStrInsn(uint32 regSize, PrimType stype, RegOperand &phyOpnd, MemOperand &memOpnd) = 0; 258 virtual Insn *BuildLdrInsn(uint32 regSize, PrimType stype, RegOperand &phyOpnd, MemOperand &memOpnd) = 0; 259 virtual bool IsMovFromRegtoReg(MOperator mOp, Insn &insn) = 0; 260 virtual MemOperand *GetOrCreatSpillMem(regno_t vrNum, uint32 bitSize) = 0; 261 virtual MemOperand *AdjustMemOperandIfOffsetOutOfRange(MemOperand *memOpnd, const RegNoPair ®NoPair, bool isDest, 262 Insn &insn, bool &isOutOfRange) = 0; 263 virtual void FreeSpillRegMem(regno_t vrNum) = 0; 264 265 private: 266 MapleSet<regno_t> allIntRegs; 267 MapleSet<regno_t> allFpRegs; 268 MapleSet<regno_t> allregs; 269 CGFunc *cgFunc = nullptr; 270 }; 271 } /* namespace maplebe */ 272 273 #endif /* MAPLEBE_INCLUDE_CG_REG_INFO_H */ 274