• 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     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