• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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