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 MAPLE_IR_INCLUDE_MIR_PREG_H 17 #define MAPLE_IR_INCLUDE_MIR_PREG_H 18 #if MIR_FEATURE_FULL 19 #include <climits> 20 #include "mir_module.h" 21 #include "global_tables.h" 22 #endif // MIR_FEATURE_FULL 23 24 namespace maple { 25 extern void PrintIndentation(int32 indent); 26 27 // these special registers are encoded by negating the enumeration 28 enum SpecialReg : signed int { 29 kSregSp = 1, 30 kSregFp = 2, 31 kSregGp = 3, 32 kSregThrownval = 4, 33 kSregMethodhdl = 5, 34 kSregRetval0 = 6, 35 kSregRetval1 = 7, 36 kSregRetval2 = 8, 37 kSregRetval3 = 9, 38 kSregLast = 10, 39 }; 40 #if MIR_FEATURE_FULL 41 class MIRPreg { 42 public: MIRPreg(n,kPtyInvalid,nullptr)43 explicit MIRPreg(uint32 n = 0) : MIRPreg(n, kPtyInvalid, nullptr) {} 44 MIRPreg(uint32 n,PrimType ptyp)45 MIRPreg(uint32 n, PrimType ptyp) : primType(ptyp), pregNo(n) {} 46 MIRPreg(uint32 n,PrimType ptyp,MIRType * mType)47 MIRPreg(uint32 n, PrimType ptyp, MIRType *mType) : primType(ptyp), pregNo(n), mirType(mType) {} 48 49 ~MIRPreg() = default; 50 void SetNeedRC(bool newNeedRC = true) 51 { 52 this->needRC = newNeedRC; 53 } 54 NeedRC()55 bool NeedRC() const 56 { 57 return needRC; 58 } 59 IsRef()60 bool IsRef() const 61 { 62 return mirType != nullptr && primType == PTY_ref; 63 } 64 GetPrimType()65 PrimType GetPrimType() const 66 { 67 return primType; 68 } 69 SetPrimType(PrimType pty)70 void SetPrimType(PrimType pty) 71 { 72 primType = pty; 73 } 74 GetOp()75 Opcode GetOp() const 76 { 77 return op; 78 } 79 SetOp(Opcode o)80 void SetOp(Opcode o) 81 { 82 this->op = o; 83 } 84 GetPregNo()85 int32 GetPregNo() const 86 { 87 return pregNo; 88 } 89 SetPregNo(int32 newPregNo)90 void SetPregNo(int32 newPregNo) 91 { 92 this->pregNo = newPregNo; 93 } 94 GetMIRType()95 MIRType *GetMIRType() const 96 { 97 return mirType; 98 } 99 SetMIRType(MIRType * newMirType)100 void SetMIRType(MIRType *newMirType) 101 { 102 this->mirType = newMirType; 103 } 104 105 private: 106 PrimType primType = kPtyInvalid; 107 bool needRC = false; 108 Opcode op = OP_undef; // OP_constval, OP_addrof or OP_dread if rematerializable 109 int32 pregNo; // the number in maple IR after the % 110 MIRType *mirType = nullptr; 111 112 public: 113 union RematInfo { 114 const MIRConst *mirConst; // used only when op is OP_constval 115 const MIRSymbol *sym; // used only when op is OP_addrof or OP_dread 116 } rematInfo; 117 FieldID fieldID = 0; // used only when op is OP_addrof or OP_dread 118 bool addrUpper = false; // used only when op is OP_addrof to indicate upper bits of address 119 }; 120 121 class MIRPregTable { 122 public: MIRPregTable(MapleAllocator * allocator)123 explicit MIRPregTable(MapleAllocator *allocator) 124 : pregNoToPregIdxMap(allocator->Adapter()), pregTable(allocator->Adapter()), mAllocator(allocator) 125 { 126 pregTable.push_back(nullptr); 127 specPregTable[0].SetPregNo(0); 128 specPregTable[kSregSp].SetPregNo(-kSregSp); 129 specPregTable[kSregFp].SetPregNo(-kSregFp); 130 specPregTable[kSregGp].SetPregNo(-kSregGp); 131 specPregTable[kSregThrownval].SetPregNo(-kSregThrownval); 132 specPregTable[kSregMethodhdl].SetPregNo(-kSregMethodhdl); 133 specPregTable[kSregRetval0].SetPregNo(-kSregRetval0); 134 specPregTable[kSregRetval1].SetPregNo(-kSregRetval1); 135 for (uint32 i = 0; i < kSregLast; ++i) { 136 specPregTable[i].SetPrimType(PTY_unknown); 137 } 138 } 139 140 ~MIRPregTable(); 141 142 PregIdx CreatePreg(PrimType primType, MIRType *mtype = nullptr) 143 { 144 DEBUG_ASSERT(!mtype || mtype->GetPrimType() == PTY_ref || mtype->GetPrimType() == PTY_ptr, "ref or ptr type"); 145 uint32 index = ++maxPregNo; 146 auto *preg = mAllocator->GetMemPool()->New<MIRPreg>(index, primType, mtype); 147 return AddPreg(*preg); 148 } 149 ClonePreg(const MIRPreg & rfpreg)150 PregIdx ClonePreg(const MIRPreg &rfpreg) 151 { 152 PregIdx idx = CreatePreg(rfpreg.GetPrimType(), rfpreg.GetMIRType()); 153 MIRPreg *preg = pregTable[static_cast<uint32>(idx)]; 154 preg->SetNeedRC(rfpreg.NeedRC()); 155 return idx; 156 } 157 PregFromPregIdx(PregIdx pregidx)158 MIRPreg *PregFromPregIdx(PregIdx pregidx) 159 { 160 if (pregidx < 0) { // special register 161 return &specPregTable[-pregidx]; 162 } else { 163 return pregTable.at(static_cast<uint32>(pregidx)); 164 } 165 } 166 GetPregIdxFromPregno(uint32 pregNo)167 PregIdx GetPregIdxFromPregno(uint32 pregNo) 168 { 169 auto it = pregNoToPregIdxMap.find(pregNo); 170 return (it == pregNoToPregIdxMap.end()) ? PregIdx(0) : it->second; 171 } 172 DumpPregsWithTypes(int32 indent)173 void DumpPregsWithTypes(int32 indent) 174 { 175 MapleVector<MIRPreg *> &pregtable = pregTable; 176 for (uint32 i = 1; i < pregtable.size(); i++) { 177 MIRPreg *mirpreg = pregtable[i]; 178 if (mirpreg->GetMIRType() == nullptr) { 179 continue; 180 } 181 PrintIndentation(indent); 182 LogInfo::MapleLogger() << "reg "; 183 LogInfo::MapleLogger() << "%" << mirpreg->GetPregNo(); 184 LogInfo::MapleLogger() << " "; 185 mirpreg->GetMIRType()->Dump(0); 186 LogInfo::MapleLogger() << " " << (mirpreg->NeedRC() ? 1 : 0); 187 LogInfo::MapleLogger() << "\n"; 188 } 189 } 190 Size()191 size_t Size() const 192 { 193 return pregTable.size(); 194 } 195 AddPreg(MIRPreg & preg)196 PregIdx AddPreg(MIRPreg &preg) 197 { 198 PregIdx idx = static_cast<PregIdx>(pregTable.size()); 199 pregTable.push_back(&preg); 200 DEBUG_ASSERT(pregNoToPregIdxMap.find(preg.GetPregNo()) == pregNoToPregIdxMap.end(), 201 "The same pregno is already taken"); 202 pregNoToPregIdxMap[preg.GetPregNo()] = idx; 203 return idx; 204 } 205 206 PregIdx EnterPregNo(uint32 pregNo, PrimType ptyp, MIRType *ty = nullptr) 207 { 208 PregIdx idx = GetPregIdxFromPregno(pregNo); 209 if (idx == 0) { 210 if (pregNo > maxPregNo) { 211 maxPregNo = pregNo; 212 } 213 MIRPreg *preg = mAllocator->GetMemPool()->New<MIRPreg>(pregNo, ptyp, ty); 214 return AddPreg(*preg); 215 } 216 return idx; 217 } 218 GetPregTable()219 MapleVector<MIRPreg *> &GetPregTable() 220 { 221 return pregTable; 222 } 223 GetPregTable()224 const MapleVector<MIRPreg *> &GetPregTable() const 225 { 226 return pregTable; 227 } 228 GetPregTableItem(const uint32 index)229 const MIRPreg *GetPregTableItem(const uint32 index) const 230 { 231 CHECK_FATAL(index < pregTable.size(), "array index out of range"); 232 return pregTable[index]; 233 } 234 SetPregNoToPregIdxMapItem(uint32 key,PregIdx value)235 void SetPregNoToPregIdxMapItem(uint32 key, PregIdx value) 236 { 237 pregNoToPregIdxMap[key] = value; 238 } 239 GetMaxPregNo()240 uint32 GetMaxPregNo() const 241 { 242 return maxPregNo; 243 } 244 SetMaxPregNo(uint32 index)245 void SetMaxPregNo(uint32 index) 246 { 247 maxPregNo = index; 248 } 249 SpecPregSize()250 size_t SpecPregSize() 251 { 252 return kSregLast; 253 } 254 255 private: 256 uint32 maxPregNo = 0; // the max pregNo that has been allocated 257 MapleMap<uint32, PregIdx> pregNoToPregIdxMap; // for quick lookup based on pregno 258 MapleVector<MIRPreg *> pregTable; 259 MIRPreg specPregTable[kSregLast]; // for the MIRPreg nodes corresponding to special registers 260 MapleAllocator *mAllocator; 261 }; 262 263 #endif // MIR_FEATURE_FULL 264 } // namespace maple 265 #endif // MAPLE_IR_INCLUDE_MIR_PREG_H 266