• 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_type.h"
18 #include "mir_symbol.h"
19 
20 #if MIR_FEATURE_FULL
21 namespace maple {
CreateMirType(uint32 primTypeIdx) const22 MIRType *TypeTable::CreateMirType(uint32 primTypeIdx) const
23 {
24     MIRTypeKind defaultKind = (primTypeIdx == PTY_constStr ? kTypeConstString : kTypeScalar);
25     auto primType = static_cast<PrimType>(primTypeIdx);
26     auto *mirType = new MIRType(defaultKind, primType);
27     return mirType;
28 }
29 
TypeTable()30 TypeTable::TypeTable()
31 {
32     Init();
33 }
34 
Init()35 void TypeTable::Init()
36 {
37     // enter the primitve types in type_table_
38     typeTable.push_back(static_cast<MIRType *>(nullptr));
39     DEBUG_ASSERT(typeTable.size() == static_cast<size_t>(PTY_void), "use PTY_void as the first index to type table");
40     uint32 primTypeIdx;
41     for (primTypeIdx = static_cast<uint32>(PTY_begin) + 1; primTypeIdx <= static_cast<uint32>(PTY_end); ++primTypeIdx) {
42         MIRType *type = CreateMirType(primTypeIdx);
43         type->SetTypeIndex(TyIdx {primTypeIdx});
44         typeTable.push_back(type);
45         PutToHashTable(type);
46     }
47     if (voidPtrType == nullptr) {
48         voidPtrType = GetOrCreatePointerType(*GetVoid(), PTY_ptr);
49     }
50     lastDefaultTyIdx.SetIdx(primTypeIdx);
51 }
52 
Reset()53 void TypeTable::Reset()
54 {
55     ReleaseTypes();
56     typeHashTable.clear();
57     ptrTypeMap.clear();
58     refTypeMap.clear();
59     typeTable.clear();
60     Init();
61 }
62 
ReleaseTypes()63 void TypeTable::ReleaseTypes()
64 {
65     for (auto index = static_cast<uint32>(PTY_void); index < typeTable.size(); ++index) {
66         delete typeTable[index];
67         typeTable[index] = nullptr;
68     }
69     voidPtrType = nullptr;
70 }
71 
SetTypeWithTyIdx(const TyIdx & tyIdx,MIRType & type)72 void TypeTable::SetTypeWithTyIdx(const TyIdx &tyIdx, MIRType &type)
73 {
74     CHECK_FATAL(tyIdx < typeTable.size(), "array index out of range");
75     MIRType *oldType = typeTable.at(tyIdx);
76     typeTable.at(tyIdx) = &type;
77     if (oldType != nullptr && oldType != &type) {
78         (void)typeHashTable.erase(oldType);
79         (void)typeHashTable.insert(&type);
80         delete oldType;
81     }
82 }
83 
~TypeTable()84 TypeTable::~TypeTable()
85 {
86     ReleaseTypes();
87 }
88 
PutToHashTable(MIRType * mirType)89 void TypeTable::PutToHashTable(MIRType *mirType)
90 {
91     (void)typeHashTable.insert(mirType);
92 }
93 
UpdateMIRType(const MIRType & pType,const TyIdx tyIdx)94 void TypeTable::UpdateMIRType(const MIRType &pType, const TyIdx tyIdx)
95 {
96     MIRType *nType = pType.CopyMIRTypeNode();
97     ASSERT_NOT_NULL(nType);
98     nType->SetTypeIndex(tyIdx);
99     SetTypeWithTyIdx(tyIdx, *nType);
100 }
101 
102 // used only by bin_mpl_import
CreateMirTypeNodeAt(MIRType & pType,TyIdx tyIdxUsed,MIRModule * module,bool isObject,bool isIncomplete)103 void TypeTable::CreateMirTypeNodeAt(MIRType &pType, TyIdx tyIdxUsed, MIRModule *module, bool isObject,
104                                     bool isIncomplete)
105 {
106     MIRType *nType = pType.CopyMIRTypeNode();
107     nType->SetTypeIndex(tyIdxUsed);
108     typeTable[tyIdxUsed] = nType;
109 
110     if (pType.IsMIRPtrType()) {
111         auto &pty = static_cast<MIRPtrType &>(pType);
112         if (pty.GetTypeAttrs() == TypeAttrs()) {
113             if (pty.GetPrimType() != PTY_ref) {
114                 ptrTypeMap[pty.GetPointedTyIdx()] = nType->GetTypeIndex();
115             } else {
116                 refTypeMap[pty.GetPointedTyIdx()] = nType->GetTypeIndex();
117             }
118         } else {
119             (void)typeHashTable.insert(nType);
120         }
121     } else {
122         (void)typeHashTable.insert(nType);
123     }
124 
125     GStrIdx stridx = pType.GetNameStrIdx();
126     if (stridx != 0u) {
127         module->GetTypeNameTab()->SetGStrIdxToTyIdx(stridx, tyIdxUsed);
128         module->PushbackTypeDefOrder(stridx);
129         if (isObject) {
130             module->AddClass(tyIdxUsed);
131             if (!isIncomplete) {
132                 GlobalTables::GetTypeNameTable().SetGStrIdxToTyIdx(stridx, tyIdxUsed);
133             }
134         }
135     }
136 }
137 
CreateAndUpdateMirTypeNode(MIRType & pType)138 MIRType *TypeTable::CreateAndUpdateMirTypeNode(MIRType &pType)
139 {
140     MIRType *nType = pType.CopyMIRTypeNode();
141     nType->SetTypeIndex(TyIdx(typeTable.size()));
142     typeTable.push_back(nType);
143 
144     if (pType.IsMIRPtrType()) {
145         auto &pty = static_cast<MIRPtrType &>(pType);
146         if (pty.GetTypeAttrs() == TypeAttrs()) {
147             if (pty.GetPrimType() != PTY_ref) {
148                 ptrTypeMap[pty.GetPointedTyIdx()] = nType->GetTypeIndex();
149             } else {
150                 refTypeMap[pty.GetPointedTyIdx()] = nType->GetTypeIndex();
151             }
152         } else {
153             (void)typeHashTable.insert(nType);
154         }
155     } else {
156         (void)typeHashTable.insert(nType);
157     }
158     return nType;
159 }
160 
GetOrCreateMIRTypeNode(MIRType & pType)161 MIRType *TypeTable::GetOrCreateMIRTypeNode(MIRType &pType)
162 {
163     if (pType.IsMIRPtrType()) {
164         auto &type = static_cast<MIRPtrType &>(pType);
165         if (type.GetTypeAttrs() == TypeAttrs()) {
166             auto *pMap = (type.GetPrimType() != PTY_ref ? &ptrTypeMap : &refTypeMap);
167             auto *otherPMap = (type.GetPrimType() == PTY_ref ? &ptrTypeMap : &refTypeMap);
168             {
169                 std::shared_lock<std::shared_timed_mutex> lock(mtx);
170                 const auto it = pMap->find(type.GetPointedTyIdx());
171                 if (it != pMap->end()) {
172                     return GetTypeFromTyIdx(it->second);
173                 }
174             }
175             std::unique_lock<std::shared_timed_mutex> lock(mtx);
176             CHECK_FATAL(!(type.GetPointedTyIdx().GetIdx() >= kPtyDerived && type.GetPrimType() == PTY_ref &&
177                           otherPMap->find(type.GetPointedTyIdx()) != otherPMap->end()),
178                         "GetOrCreateMIRType: ref pointed-to type %d has previous ptr occurrence",
179                         type.GetPointedTyIdx().GetIdx());
180             return CreateAndUpdateMirTypeNode(pType);
181         }
182     }
183     {
184         std::shared_lock<std::shared_timed_mutex> lock(mtx);
185         const auto it = typeHashTable.find(&pType);
186         if (it != typeHashTable.end()) {
187             return *it;
188         }
189     }
190     std::unique_lock<std::shared_timed_mutex> lock(mtx);
191     return CreateAndUpdateMirTypeNode(pType);
192 }
193 
194 MIRType *TypeTable::voidPtrType = nullptr;
195 // get or create a type that pointing to pointedTyIdx
GetOrCreatePointerType(const TyIdx & pointedTyIdx,PrimType primType,const TypeAttrs & attrs)196 MIRType *TypeTable::GetOrCreatePointerType(const TyIdx &pointedTyIdx, PrimType primType, const TypeAttrs &attrs)
197 {
198     MIRPtrType type(pointedTyIdx, primType);
199     type.SetTypeAttrs(attrs);
200     TyIdx tyIdx = GetOrCreateMIRType(&type);
201     DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreatePointerType");
202     return typeTable.at(tyIdx);
203 }
204 
GetOrCreatePointerType(const MIRType & pointTo,PrimType primType,const TypeAttrs & attrs)205 MIRType *TypeTable::GetOrCreatePointerType(const MIRType &pointTo, PrimType primType, const TypeAttrs &attrs)
206 {
207     if (pointTo.GetPrimType() == PTY_constStr) {
208         primType = PTY_ptr;
209     }
210     return GetOrCreatePointerType(pointTo.GetTypeIndex(), primType, attrs);
211 }
212 
GetPointedTypeIfApplicable(MIRType & type) const213 const MIRType *TypeTable::GetPointedTypeIfApplicable(MIRType &type) const
214 {
215     if (type.GetKind() != kTypePointer) {
216         return &type;
217     }
218     auto &ptrType = static_cast<MIRPtrType &>(type);
219     return GetTypeFromTyIdx(ptrType.GetPointedTyIdx());
220 }
GetPointedTypeIfApplicable(MIRType & type)221 MIRType *TypeTable::GetPointedTypeIfApplicable(MIRType &type)
222 {
223     return const_cast<MIRType *>(const_cast<const TypeTable *>(this)->GetPointedTypeIfApplicable(type));
224 }
225 
GetOrCreateArrayType(const MIRType & elem,uint8 dim,const uint64 * sizeArray,const TypeAttrs & attrs)226 MIRArrayType *TypeTable::GetOrCreateArrayType(const MIRType &elem, uint8 dim, const uint64 *sizeArray,
227                                               const TypeAttrs &attrs)
228 {
229     std::vector<uint64> sizeVector;
230     for (size_t i = 0; i < dim; ++i) {
231         sizeVector.push_back(sizeArray != nullptr ? sizeArray[i] : 0);
232     }
233     MIRArrayType arrayType(elem.GetTypeIndex(), sizeVector);
234     arrayType.SetTypeAttrs(attrs);
235     TyIdx tyIdx = GetOrCreateMIRType(&arrayType);
236     return static_cast<MIRArrayType *>(typeTable[tyIdx]);
237 }
238 
239 // For one dimension array
GetOrCreateArrayType(const MIRType & elem,uint64 size,const TypeAttrs & attrs)240 MIRArrayType *TypeTable::GetOrCreateArrayType(const MIRType &elem, uint64 size, const TypeAttrs &attrs)
241 {
242     return GetOrCreateArrayType(elem, 1, &size, attrs);
243 }
244 
GetOrCreateFarrayType(const MIRType & elem)245 MIRType *TypeTable::GetOrCreateFarrayType(const MIRType &elem)
246 {
247     MIRFarrayType type;
248     type.SetElemtTyIdx(elem.GetTypeIndex());
249     TyIdx tyIdx = GetOrCreateMIRType(&type);
250     DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFarrayType");
251     return typeTable.at(tyIdx);
252 }
253 
GetOrCreateJarrayType(const MIRType & elem)254 MIRType *TypeTable::GetOrCreateJarrayType(const MIRType &elem)
255 {
256     MIRJarrayType type;
257     type.SetElemtTyIdx(elem.GetTypeIndex());
258     TyIdx tyIdx = GetOrCreateMIRType(&type);
259     DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateJarrayType");
260     return typeTable.at(tyIdx);
261 }
262 
GetOrCreateFunctionType(const TyIdx & retTyIdx,const std::vector<TyIdx> & vecType,const std::vector<TypeAttrs> & vecAttrs,bool isVarg,const TypeAttrs & retAttrs)263 MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::vector<TyIdx> &vecType,
264                                             const std::vector<TypeAttrs> &vecAttrs, bool isVarg,
265                                             const TypeAttrs &retAttrs)
266 {
267     MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs);
268     if (isVarg) {
269         funcType.SetVarArgs();
270     }
271     TyIdx tyIdx = GetOrCreateMIRType(&funcType);
272     DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType");
273     return typeTable.at(tyIdx);
274 }
275 
GetOrCreateStructOrUnion(const std::string & name,const FieldVector & fields,const FieldVector & parentFields,MIRModule & module,bool forStruct,const TypeAttrs & attrs)276 MIRType *TypeTable::GetOrCreateStructOrUnion(const std::string &name, const FieldVector &fields,
277                                              const FieldVector &parentFields, MIRModule &module, bool forStruct,
278                                              const TypeAttrs &attrs)
279 {
280     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
281     MIRStructType type(forStruct ? kTypeStruct : kTypeUnion, strIdx);
282     type.SetFields(fields);
283     type.SetParentFields(parentFields);
284     type.SetTypeAttrs(attrs);
285 
286     TyIdx tyIdx = GetOrCreateMIRType(&type);
287     // Global?
288     module.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx);
289     module.PushbackTypeDefOrder(strIdx);
290     DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateStructOrUnion");
291     return typeTable.at(tyIdx);
292 }
293 
PushIntoFieldVector(FieldVector & fields,const std::string & name,const MIRType & type)294 void TypeTable::PushIntoFieldVector(FieldVector &fields, const std::string &name, const MIRType &type)
295 {
296     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
297     fields.push_back(FieldPair(strIdx, TyIdxFieldAttrPair(type.GetTypeIndex(), FieldAttrs())));
298 }
299 
GetOrCreateClassOrInterface(const std::string & name,MIRModule & module,bool forClass)300 MIRType *TypeTable::GetOrCreateClassOrInterface(const std::string &name, MIRModule &module, bool forClass)
301 {
302     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
303     TyIdx tyIdx = module.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx);
304     if (!tyIdx) {
305         if (forClass) {
306             MIRClassType type(kTypeClassIncomplete, strIdx);  // for class type
307             tyIdx = GetOrCreateMIRType(&type);
308         } else {
309             MIRInterfaceType type(kTypeInterfaceIncomplete, strIdx);  // for interface type
310             tyIdx = GetOrCreateMIRType(&type);
311         }
312         module.PushbackTypeDefOrder(strIdx);
313         module.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx);
314         if (typeTable[tyIdx]->GetNameStrIdx() == 0u) {
315             typeTable[tyIdx]->SetNameStrIdx(strIdx);
316         }
317     }
318     DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateClassOrInterface");
319     return typeTable.at(tyIdx);
320 }
321 
AddFieldToStructType(MIRStructType & structType,const std::string & fieldName,const MIRType & fieldType)322 void TypeTable::AddFieldToStructType(MIRStructType &structType, const std::string &fieldName, const MIRType &fieldType)
323 {
324     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fieldName);
325     FieldAttrs fieldAttrs;
326     fieldAttrs.SetAttr(FLDATTR_final);  // Mark compiler-generated struct fields as final to improve AliasAnalysis
327     structType.GetFields().push_back(FieldPair(strIdx, TyIdxFieldAttrPair(fieldType.GetTypeIndex(), fieldAttrs)));
328 }
329 
PostInit()330 void FPConstTable::PostInit()
331 {
332     MIRType &typeFloat = *GlobalTables::GetTypeTable().GetPrimType(PTY_f32);
333     nanFloatConst = new MIRFloatConst(NAN, typeFloat);
334     infFloatConst = new MIRFloatConst(INFINITY, typeFloat);
335     minusInfFloatConst = new MIRFloatConst(-INFINITY, typeFloat);
336     minusZeroFloatConst = new MIRFloatConst(-0.0, typeFloat);
337     MIRType &typeDouble = *GlobalTables::GetTypeTable().GetPrimType(PTY_f64);
338     nanDoubleConst = new MIRDoubleConst(NAN, typeDouble);
339     infDoubleConst = new MIRDoubleConst(INFINITY, typeDouble);
340     minusInfDoubleConst = new MIRDoubleConst(-INFINITY, typeDouble);
341     minusZeroDoubleConst = new MIRDoubleConst(-0.0, typeDouble);
342 }
343 
GetOrCreateIntConst(const IntVal & val,MIRType & type)344 MIRIntConst *IntConstTable::GetOrCreateIntConst(const IntVal &val, MIRType &type)
345 {
346     if (ThreadEnv::IsMeParallel()) {
347         return DoGetOrCreateIntConstTreadSafe(val.GetExtValue(), type);
348     }
349     return DoGetOrCreateIntConst(val.GetExtValue(), type);
350 }
351 
GetOrCreateIntConst(uint64 val,MIRType & type)352 MIRIntConst *IntConstTable::GetOrCreateIntConst(uint64 val, MIRType &type)
353 {
354     if (ThreadEnv::IsMeParallel()) {
355         return DoGetOrCreateIntConstTreadSafe(val, type);
356     }
357     return DoGetOrCreateIntConst(val, type);
358 }
359 
DoGetOrCreateIntConst(uint64 val,MIRType & type)360 MIRIntConst *IntConstTable::DoGetOrCreateIntConst(uint64 val, MIRType &type)
361 {
362     IntConstKey key(val, type.GetTypeIndex());
363     if (intConstTable.find(key) != intConstTable.end()) {
364         return intConstTable[key];
365     }
366     intConstTable[key] = new MIRIntConst(val, type);
367     return intConstTable[key];
368 }
369 
DoGetOrCreateIntConstTreadSafe(uint64 val,MIRType & type)370 MIRIntConst *IntConstTable::DoGetOrCreateIntConstTreadSafe(uint64 val, MIRType &type)
371 {
372     IntConstKey key(val, type.GetTypeIndex());
373     {
374         std::shared_lock<std::shared_timed_mutex> lock(mtx);
375         if (intConstTable.find(key) != intConstTable.end()) {
376             return intConstTable[key];
377         }
378     }
379     std::unique_lock<std::shared_timed_mutex> lock(mtx);
380     intConstTable[key] = new MIRIntConst(val, type);
381     return intConstTable[key];
382 }
383 
~IntConstTable()384 IntConstTable::~IntConstTable()
385 {
386     for (auto pair : intConstTable) {
387         delete pair.second;
388     }
389 }
390 
GetOrCreateFloatConst(float floatVal)391 MIRFloatConst *FPConstTable::GetOrCreateFloatConst(float floatVal)
392 {
393     if (std::isnan(floatVal)) {
394         return nanFloatConst;
395     }
396     if (std::isinf(floatVal)) {
397         return (floatVal < 0) ? minusInfFloatConst : infFloatConst;
398     }
399     if (floatVal == 0.0 && std::signbit(floatVal)) {
400         return minusZeroFloatConst;
401     }
402     if (ThreadEnv::IsMeParallel()) {
403         return DoGetOrCreateFloatConstThreadSafe(floatVal);
404     }
405     return DoGetOrCreateFloatConst(floatVal);
406 }
407 
DoGetOrCreateFloatConst(float floatVal)408 MIRFloatConst *FPConstTable::DoGetOrCreateFloatConst(float floatVal)
409 {
410     const auto it = floatConstTable.find(floatVal);
411     if (it != floatConstTable.cend()) {
412         return it->second;
413     }
414     // create a new one
415     auto *floatConst = new MIRFloatConst(floatVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx {PTY_f32}));
416     floatConstTable[floatVal] = floatConst;
417     return floatConst;
418 }
419 
DoGetOrCreateFloatConstThreadSafe(float floatVal)420 MIRFloatConst *FPConstTable::DoGetOrCreateFloatConstThreadSafe(float floatVal)
421 {
422     {
423         std::shared_lock<std::shared_timed_mutex> lock(floatMtx);
424         const auto it = floatConstTable.find(floatVal);
425         if (it != floatConstTable.cend()) {
426             return it->second;
427         }
428     }
429     // create a new one
430     std::unique_lock<std::shared_timed_mutex> lock(floatMtx);
431     auto *floatConst = new MIRFloatConst(floatVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx {PTY_f32}));
432     floatConstTable[floatVal] = floatConst;
433     return floatConst;
434 }
435 
GetOrCreateDoubleConst(double doubleVal)436 MIRDoubleConst *FPConstTable::GetOrCreateDoubleConst(double doubleVal)
437 {
438     if (std::isnan(doubleVal)) {
439         return nanDoubleConst;
440     }
441     if (std::isinf(doubleVal)) {
442         return (doubleVal < 0) ? minusInfDoubleConst : infDoubleConst;
443     }
444     if (doubleVal == 0.0 && std::signbit(doubleVal)) {
445         return minusZeroDoubleConst;
446     }
447     if (ThreadEnv::IsMeParallel()) {
448         return DoGetOrCreateDoubleConstThreadSafe(doubleVal);
449     }
450     return DoGetOrCreateDoubleConst(doubleVal);
451 }
452 
DoGetOrCreateDoubleConst(double doubleVal)453 MIRDoubleConst *FPConstTable::DoGetOrCreateDoubleConst(double doubleVal)
454 {
455     const auto it = doubleConstTable.find(doubleVal);
456     if (it != doubleConstTable.cend()) {
457         return it->second;
458     }
459     // create a new one
460     auto *doubleConst =
461         new MIRDoubleConst(doubleVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(PTY_f64)));
462     doubleConstTable[doubleVal] = doubleConst;
463     return doubleConst;
464 }
465 
DoGetOrCreateDoubleConstThreadSafe(double doubleVal)466 MIRDoubleConst *FPConstTable::DoGetOrCreateDoubleConstThreadSafe(double doubleVal)
467 {
468     {
469         std::shared_lock<std::shared_timed_mutex> lock(doubleMtx);
470         const auto it = doubleConstTable.find(doubleVal);
471         if (it != doubleConstTable.cend()) {
472             return it->second;
473         }
474     }
475     // create a new one
476     std::unique_lock<std::shared_timed_mutex> lock(doubleMtx);
477     auto *doubleConst =
478         new MIRDoubleConst(doubleVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(PTY_f64)));
479     doubleConstTable[doubleVal] = doubleConst;
480     return doubleConst;
481 }
482 
~FPConstTable()483 FPConstTable::~FPConstTable()
484 {
485     delete nanFloatConst;
486     delete infFloatConst;
487     delete minusInfFloatConst;
488     delete minusZeroFloatConst;
489     delete nanDoubleConst;
490     delete infDoubleConst;
491     delete minusInfDoubleConst;
492     delete minusZeroDoubleConst;
493     for (const auto &floatConst : floatConstTable) {
494         delete floatConst.second;
495     }
496     for (const auto &doubleConst : doubleConstTable) {
497         delete doubleConst.second;
498     }
499 }
500 
GSymbolTable()501 GSymbolTable::GSymbolTable()
502 {
503     Init();
504 }
505 
Init()506 void GSymbolTable::Init()
507 {
508     symbolTable.push_back(static_cast<MIRSymbol *>(nullptr));
509 }
510 
Reset()511 void GSymbolTable::Reset()
512 {
513     ReleaseSymbols();
514     symbolTable.clear();
515     strIdxToStIdxMap.clear();
516     Init();
517 }
518 
ReleaseSymbols()519 void GSymbolTable::ReleaseSymbols()
520 {
521     for (MIRSymbol *symbol : symbolTable) {
522         delete symbol;
523     }
524 }
525 
~GSymbolTable()526 GSymbolTable::~GSymbolTable()
527 {
528     ReleaseSymbols();
529 }
530 
CreateSymbol(uint8 scopeID)531 MIRSymbol *GSymbolTable::CreateSymbol(uint8 scopeID)
532 {
533     auto *st = new MIRSymbol(symbolTable.size(), scopeID);
534     CHECK_FATAL(st != nullptr, "CreateSymbol failure");
535     symbolTable.push_back(st);
536     module->AddSymbol(st);
537     return st;
538 }
539 
AddToStringSymbolMap(const MIRSymbol & st)540 bool GSymbolTable::AddToStringSymbolMap(const MIRSymbol &st)
541 {
542     GStrIdx strIdx = st.GetNameStrIdx();
543     if (strIdxToStIdxMap[strIdx].FullIdx() != 0) {
544         return false;
545     }
546     strIdxToStIdxMap[strIdx] = st.GetStIdx();
547     return true;
548 }
549 
RemoveFromStringSymbolMap(const MIRSymbol & st)550 bool GSymbolTable::RemoveFromStringSymbolMap(const MIRSymbol &st)
551 {
552     const auto it = strIdxToStIdxMap.find(st.GetNameStrIdx());
553     if (it != strIdxToStIdxMap.cend()) {
554         strIdxToStIdxMap.erase(it);
555         return true;
556     }
557     return false;
558 }
559 
Dump(bool isLocal,int32 indent) const560 void GSymbolTable::Dump(bool isLocal, int32 indent) const
561 {
562     for (size_t i = 1; i < symbolTable.size(); ++i) {
563         const MIRSymbol *symbol = symbolTable[i];
564         if (symbol != nullptr) {
565             symbol->Dump(isLocal, indent);
566         }
567     }
568 }
569 
570 GlobalTables GlobalTables::globalTables;
GetGlobalTables()571 GlobalTables &GlobalTables::GetGlobalTables()
572 {
573     return globalTables;
574 }
575 }  // namespace maple
576 #endif  // MIR_FEATURE_FULL
577