• 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 #include "global_tables.h"
17 #include "mir_symbol.h"
18 
19 #if MIR_FEATURE_FULL
20 namespace maple {
CreateMirType(uint32 primTypeIdx) const21 MIRType *TypeTable::CreateMirType(uint32 primTypeIdx) const
22 {
23     MIRTypeKind defaultKind = kTypeScalar;
24     auto primType = static_cast<PrimType>(primTypeIdx);
25     auto *mirType = new MIRType(defaultKind, primType);
26     return mirType;
27 }
28 
TypeTable()29 TypeTable::TypeTable()
30 {
31     Init();
32 }
33 
Init()34 void TypeTable::Init()
35 {
36     // enter the primitve types in type_table_
37     typeTable.push_back(static_cast<MIRType *>(nullptr));
38     DEBUG_ASSERT(typeTable.size() == static_cast<size_t>(PTY_void), "use PTY_void as the first index to type table");
39     uint32 primTypeIdx;
40     for (primTypeIdx = static_cast<uint32>(PTY_begin) + 1; primTypeIdx <= static_cast<uint32>(PTY_end); ++primTypeIdx) {
41         MIRType *type = CreateMirType(primTypeIdx);
42         type->SetTypeIndex(TyIdx {primTypeIdx});
43         typeTable.push_back(type);
44         PutToHashTable(type);
45     }
46     if (voidPtrType == nullptr) {
47         voidPtrType = GetOrCreatePointerType(*GetVoid(), PTY_ptr);
48     }
49     lastDefaultTyIdx.SetIdx(primTypeIdx);
50 }
51 
Reset()52 void TypeTable::Reset()
53 {
54     ReleaseTypes();
55     typeHashTable.clear();
56     ptrTypeMap.clear();
57     refTypeMap.clear();
58     typeTable.clear();
59     Init();
60 }
61 
ReleaseTypes()62 void TypeTable::ReleaseTypes()
63 {
64     for (auto index = static_cast<uint32>(PTY_void); index < typeTable.size(); ++index) {
65         delete typeTable[index];
66         typeTable[index] = nullptr;
67     }
68     voidPtrType = nullptr;
69 }
70 
~TypeTable()71 TypeTable::~TypeTable()
72 {
73     ReleaseTypes();
74 }
75 
PutToHashTable(MIRType * mirType)76 void TypeTable::PutToHashTable(MIRType *mirType)
77 {
78     (void)typeHashTable.insert(mirType);
79 }
80 
CreateAndUpdateMirTypeNode(MIRType & pType)81 MIRType *TypeTable::CreateAndUpdateMirTypeNode(MIRType &pType)
82 {
83     MIRType *nType = pType.CopyMIRTypeNode();
84     nType->SetTypeIndex(TyIdx(typeTable.size()));
85     typeTable.push_back(nType);
86 
87     if (pType.IsMIRPtrType()) {
88         auto &pty = static_cast<MIRPtrType &>(pType);
89         if (pty.GetTypeAttrs() == TypeAttrs()) {
90             if (pty.GetPrimType() != PTY_ref) {
91                 ptrTypeMap[pty.GetPointedTyIdx()] = nType->GetTypeIndex();
92             } else {
93                 refTypeMap[pty.GetPointedTyIdx()] = nType->GetTypeIndex();
94             }
95         } else {
96             (void)typeHashTable.insert(nType);
97         }
98     } else {
99         (void)typeHashTable.insert(nType);
100     }
101     return nType;
102 }
103 
GetOrCreateMIRTypeNode(MIRType & pType)104 MIRType *TypeTable::GetOrCreateMIRTypeNode(MIRType &pType)
105 {
106     if (pType.IsMIRPtrType()) {
107         auto &type = static_cast<MIRPtrType &>(pType);
108         if (type.GetTypeAttrs() == TypeAttrs()) {
109             auto *pMap = (type.GetPrimType() != PTY_ref ? &ptrTypeMap : &refTypeMap);
110             auto *otherPMap = (type.GetPrimType() == PTY_ref ? &ptrTypeMap : &refTypeMap);
111             {
112                 std::shared_lock<std::shared_timed_mutex> lock(mtx);
113                 const auto it = pMap->find(type.GetPointedTyIdx());
114                 if (it != pMap->end()) {
115                     return GetTypeFromTyIdx(it->second);
116                 }
117             }
118             std::unique_lock<std::shared_timed_mutex> lock(mtx);
119             CHECK_FATAL(!(type.GetPointedTyIdx().GetIdx() >= kPtyDerived && type.GetPrimType() == PTY_ref &&
120                           otherPMap->find(type.GetPointedTyIdx()) != otherPMap->end()),
121                         "GetOrCreateMIRType: ref pointed-to type %d has previous ptr occurrence",
122                         type.GetPointedTyIdx().GetIdx());
123             return CreateAndUpdateMirTypeNode(pType);
124         }
125     }
126     {
127         std::shared_lock<std::shared_timed_mutex> lock(mtx);
128         const auto it = typeHashTable.find(&pType);
129         if (it != typeHashTable.end()) {
130             return *it;
131         }
132     }
133     std::unique_lock<std::shared_timed_mutex> lock(mtx);
134     return CreateAndUpdateMirTypeNode(pType);
135 }
136 
137 MIRType *TypeTable::voidPtrType = nullptr;
138 // get or create a type that pointing to pointedTyIdx
GetOrCreatePointerType(const TyIdx & pointedTyIdx,PrimType primType,const TypeAttrs & attrs)139 MIRType *TypeTable::GetOrCreatePointerType(const TyIdx &pointedTyIdx, PrimType primType, const TypeAttrs &attrs)
140 {
141     MIRPtrType type(pointedTyIdx, primType);
142     type.SetTypeAttrs(attrs);
143     TyIdx tyIdx = GetOrCreateMIRType(&type);
144     DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreatePointerType");
145     return typeTable.at(tyIdx);
146 }
147 
GetOrCreatePointerType(const MIRType & pointTo,PrimType primType,const TypeAttrs & attrs)148 MIRType *TypeTable::GetOrCreatePointerType(const MIRType &pointTo, PrimType primType, const TypeAttrs &attrs)
149 {
150     return GetOrCreatePointerType(pointTo.GetTypeIndex(), primType, attrs);
151 }
152 
GetOrCreateFunctionType(const TyIdx & retTyIdx,const std::vector<TyIdx> & vecType,const std::vector<TypeAttrs> & vecAttrs,bool isVarg,const TypeAttrs & retAttrs)153 MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::vector<TyIdx> &vecType,
154                                             const std::vector<TypeAttrs> &vecAttrs, bool isVarg,
155                                             const TypeAttrs &retAttrs)
156 {
157     MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs);
158     if (isVarg) {
159         funcType.SetVarArgs();
160     }
161     TyIdx tyIdx = GetOrCreateMIRType(&funcType);
162     DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType");
163     return typeTable.at(tyIdx);
164 }
165 
PostInit()166 void FPConstTable::PostInit()
167 {
168     MIRType &typeFloat = *GlobalTables::GetTypeTable().GetPrimType(PTY_f32);
169     nanFloatConst = new MIRFloatConst(NAN, typeFloat);
170     infFloatConst = new MIRFloatConst(INFINITY, typeFloat);
171     minusInfFloatConst = new MIRFloatConst(-INFINITY, typeFloat);
172     minusZeroFloatConst = new MIRFloatConst(-0.0, typeFloat);
173     MIRType &typeDouble = *GlobalTables::GetTypeTable().GetPrimType(PTY_f64);
174     nanDoubleConst = new MIRDoubleConst(NAN, typeDouble);
175     infDoubleConst = new MIRDoubleConst(INFINITY, typeDouble);
176     minusInfDoubleConst = new MIRDoubleConst(-INFINITY, typeDouble);
177     minusZeroDoubleConst = new MIRDoubleConst(-0.0, typeDouble);
178 }
179 
GetOrCreateIntConst(uint64 val,MIRType & type)180 MIRIntConst *IntConstTable::GetOrCreateIntConst(uint64 val, MIRType &type)
181 {
182     return DoGetOrCreateIntConst(val, type);
183 }
184 
DoGetOrCreateIntConst(uint64 val,MIRType & type)185 MIRIntConst *IntConstTable::DoGetOrCreateIntConst(uint64 val, MIRType &type)
186 {
187     IntConstKey key(val, type.GetTypeIndex());
188     if (intConstTable.find(key) != intConstTable.end()) {
189         return intConstTable[key];
190     }
191     intConstTable[key] = new MIRIntConst(val, type);
192     return intConstTable[key];
193 }
194 
~IntConstTable()195 IntConstTable::~IntConstTable()
196 {
197     for (auto pair : intConstTable) {
198         delete pair.second;
199     }
200 }
201 
GetOrCreateFloatConst(float floatVal)202 MIRFloatConst *FPConstTable::GetOrCreateFloatConst(float floatVal)
203 {
204     if (std::isnan(floatVal)) {
205         return nanFloatConst;
206     }
207     if (std::isinf(floatVal)) {
208         return (floatVal < 0) ? minusInfFloatConst : infFloatConst;
209     }
210     if (floatVal == 0.0 && std::signbit(floatVal)) {
211         return minusZeroFloatConst;
212     }
213     return DoGetOrCreateFloatConst(floatVal);
214 }
215 
DoGetOrCreateFloatConst(float floatVal)216 MIRFloatConst *FPConstTable::DoGetOrCreateFloatConst(float floatVal)
217 {
218     const auto it = floatConstTable.find(floatVal);
219     if (it != floatConstTable.cend()) {
220         return it->second;
221     }
222     // create a new one
223     auto *floatConst = new MIRFloatConst(floatVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx {PTY_f32}));
224     floatConstTable[floatVal] = floatConst;
225     return floatConst;
226 }
227 
GetOrCreateDoubleConst(double doubleVal)228 MIRDoubleConst *FPConstTable::GetOrCreateDoubleConst(double doubleVal)
229 {
230     if (std::isnan(doubleVal)) {
231         return nanDoubleConst;
232     }
233     if (std::isinf(doubleVal)) {
234         return (doubleVal < 0) ? minusInfDoubleConst : infDoubleConst;
235     }
236     if (doubleVal == 0.0 && std::signbit(doubleVal)) {
237         return minusZeroDoubleConst;
238     }
239     return DoGetOrCreateDoubleConst(doubleVal);
240 }
241 
DoGetOrCreateDoubleConst(double doubleVal)242 MIRDoubleConst *FPConstTable::DoGetOrCreateDoubleConst(double doubleVal)
243 {
244     const auto it = doubleConstTable.find(doubleVal);
245     if (it != doubleConstTable.cend()) {
246         return it->second;
247     }
248     // create a new one
249     auto *doubleConst =
250         new MIRDoubleConst(doubleVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(PTY_f64)));
251     doubleConstTable[doubleVal] = doubleConst;
252     return doubleConst;
253 }
254 
~FPConstTable()255 FPConstTable::~FPConstTable()
256 {
257     delete nanFloatConst;
258     delete infFloatConst;
259     delete minusInfFloatConst;
260     delete minusZeroFloatConst;
261     delete nanDoubleConst;
262     delete infDoubleConst;
263     delete minusInfDoubleConst;
264     delete minusZeroDoubleConst;
265     for (const auto &floatConst : floatConstTable) {
266         delete floatConst.second;
267     }
268     for (const auto &doubleConst : doubleConstTable) {
269         delete doubleConst.second;
270     }
271 }
272 
GSymbolTable()273 GSymbolTable::GSymbolTable()
274 {
275     Init();
276 }
277 
Init()278 void GSymbolTable::Init()
279 {
280     symbolTable.push_back(static_cast<MIRSymbol *>(nullptr));
281 }
282 
Reset()283 void GSymbolTable::Reset()
284 {
285     ReleaseSymbols();
286     symbolTable.clear();
287     strIdxToStIdxMap.clear();
288     Init();
289 }
290 
ReleaseSymbols()291 void GSymbolTable::ReleaseSymbols()
292 {
293     for (MIRSymbol *symbol : symbolTable) {
294         delete symbol;
295     }
296 }
297 
~GSymbolTable()298 GSymbolTable::~GSymbolTable()
299 {
300     ReleaseSymbols();
301 }
302 
CreateSymbol(uint8 scopeID)303 MIRSymbol *GSymbolTable::CreateSymbol(uint8 scopeID)
304 {
305     auto *st = new MIRSymbol(symbolTable.size(), scopeID);
306     CHECK_FATAL(st != nullptr, "CreateSymbol failure");
307     symbolTable.push_back(st);
308     module->AddSymbol(st);
309     return st;
310 }
311 
AddToStringSymbolMap(const MIRSymbol & st)312 bool GSymbolTable::AddToStringSymbolMap(const MIRSymbol &st)
313 {
314     GStrIdx strIdx = st.GetNameStrIdx();
315     if (strIdxToStIdxMap[strIdx].FullIdx() != 0) {
316         return false;
317     }
318     strIdxToStIdxMap[strIdx] = st.GetStIdx();
319     return true;
320 }
321 
322 #ifdef ARK_LITECG_DEBUG
Dump(bool isLocal,int32 indent) const323 void GSymbolTable::Dump(bool isLocal, int32 indent) const
324 {
325     for (size_t i = 1; i < symbolTable.size(); ++i) {
326         const MIRSymbol *symbol = symbolTable[i];
327         if (symbol != nullptr) {
328             symbol->Dump(isLocal, indent);
329         }
330     }
331 }
332 #endif
333 
334 GlobalTables GlobalTables::globalTables;
GetGlobalTables()335 GlobalTables &GlobalTables::GetGlobalTables()
336 {
337     return globalTables;
338 }
339 }  // namespace maple
340 #endif  // MIR_FEATURE_FULL
341