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