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