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_GLOBAL_TABLES_H
17 #define MAPLE_IR_INCLUDE_GLOBAL_TABLES_H
18 #include <iostream>
19 #include <memory>
20 #include <functional>
21 #include <mutex>
22 #include <shared_mutex>
23 #include "mempool.h"
24 #include "mempool_allocator.h"
25 #include "types_def.h"
26 #include "prim_types.h"
27 #include "mir_module.h"
28 #include "namemangler.h"
29 #include "mir_type.h"
30 #include "mir_const.h"
31 
32 namespace maple {
33 
34 class BinaryMplImport;  // circular dependency exists, no other choice
35 
36 // to facilitate the use of unordered_map
37 class TyIdxHash {
38 public:
operator ()(const TyIdx &tyIdx) const39     std::size_t operator()(const TyIdx &tyIdx) const
40     {
41         return std::hash<uint32> {}(tyIdx);
42     }
43 };
44 
45 // to facilitate the use of unordered_map
46 class GStrIdxHash {
47 public:
operator ()(const GStrIdx &gStrIdx) const48     std::size_t operator()(const GStrIdx &gStrIdx) const
49     {
50         return std::hash<uint32> {}(gStrIdx);
51     }
52 };
53 
54 // to facilitate the use of unordered_map
55 class UStrIdxHash {
56 public:
operator ()(const UStrIdx &uStrIdx) const57     std::size_t operator()(const UStrIdx &uStrIdx) const
58     {
59         return std::hash<uint32> {}(uStrIdx);
60     }
61 };
62 
63 class IntConstKey {
64     friend class IntConstHash;
65     friend class IntConstCmp;
66 
67 public:
IntConstKey(int64 v, TyIdx tyIdx)68     IntConstKey(int64 v, TyIdx tyIdx) : val(v), tyIdx(tyIdx) {}
~IntConstKey()69     virtual ~IntConstKey() {}
70 
71 private:
72     int64 val;
73     TyIdx tyIdx;
74 };
75 
76 class IntConstHash {
77 public:
operator ()(const IntConstKey &key) const78     std::size_t operator()(const IntConstKey &key) const
79     {
80         return std::hash<int64> {}(key.val) ^ (std::hash<uint64> {}(static_cast<uint64>(key.tyIdx)) << 1);
81     }
82 };
83 
84 class IntConstCmp {
85 public:
operator ()(const IntConstKey &lkey, const IntConstKey &rkey) const86     bool operator()(const IntConstKey &lkey, const IntConstKey &rkey) const
87     {
88         return lkey.val == rkey.val && lkey.tyIdx == rkey.tyIdx;
89     }
90 };
91 
92 class TypeTable {
93     friend BinaryMplImport;
94 
95 public:
96     static MIRType *voidPtrType;
97 
98     TypeTable();
99     TypeTable(const TypeTable &) = delete;
100     TypeTable &operator=(const TypeTable &) = delete;
101     ~TypeTable();
102 
103     void Init();
104     void Reset();
105     void ReleaseTypes();
106 
GetTypeTable()107     std::vector<MIRType *> &GetTypeTable()
108     {
109         return typeTable;
110     }
111 
GetTypeTable() const112     const std::vector<MIRType *> &GetTypeTable() const
113     {
114         return typeTable;
115     }
116 
GetTypeHashTable() const117     auto &GetTypeHashTable() const
118     {
119         return typeHashTable;
120     }
121 
GetPtrTypeMap() const122     auto &GetPtrTypeMap() const
123     {
124         return ptrTypeMap;
125     }
126 
GetRefTypeMap() const127     auto &GetRefTypeMap() const
128     {
129         return refTypeMap;
130     }
131 
GetTypeFromTyIdx(TyIdx tyIdx)132     MIRType *GetTypeFromTyIdx(TyIdx tyIdx)
133     {
134         return const_cast<MIRType *>(const_cast<const TypeTable *>(this)->GetTypeFromTyIdx(tyIdx));
135     }
GetTypeFromTyIdx(TyIdx tyIdx) const136     const MIRType *GetTypeFromTyIdx(TyIdx tyIdx) const
137     {
138         CHECK_FATAL(tyIdx < typeTable.size(), "array index out of range");
139         return typeTable.at(tyIdx);
140     }
141 
142     MIRType *GetTypeFromTyIdx(uint32 index) const
143     {
144         CHECK_FATAL(index < typeTable.size(), "array index out of range");
145         return typeTable.at(index);
146     }
147 
148     PrimType GetPrimTypeFromTyIdx(const TyIdx &tyIdx) const
149     {
150         CHECK_FATAL(tyIdx < typeTable.size(), "array index out of range");
151         return typeTable.at(tyIdx)->GetPrimType();
152     }
153 
154     MIRType *GetOrCreateMIRTypeNode(MIRType &ptype);
155 
156     TyIdx GetOrCreateMIRType(MIRType *pType)
157     {
158         return GetOrCreateMIRTypeNode(*pType)->GetTypeIndex();
159     }
160 
161     uint32 GetTypeTableSize() const
162     {
163         return static_cast<uint32>(typeTable.size());
164     }
165 
166     // Get primtive types.
167     MIRType *GetPrimType(PrimType primType) const
168     {
169         DEBUG_ASSERT(primType < typeTable.size(), "array index out of range");
170         return typeTable.at(primType);
171     }
172 
173     MIRType *GetFloat() const
174     {
175         DEBUG_ASSERT(PTY_f32 < typeTable.size(), "array index out of range");
176         return typeTable.at(PTY_f32);
177     }
178 
179     MIRType *GetDouble() const
180     {
181         DEBUG_ASSERT(PTY_f64 < typeTable.size(), "array index out of range");
182         return typeTable.at(PTY_f64);
183     }
184 
185     MIRType *GetUInt1() const
186     {
187         DEBUG_ASSERT(PTY_u1 < typeTable.size(), "array index out of range");
188         return typeTable.at(PTY_u1);
189     }
190 
191     MIRType *GetUInt8() const
192     {
193         DEBUG_ASSERT(PTY_u8 < typeTable.size(), "array index out of range");
194         return typeTable.at(PTY_u8);
195     }
196 
197     MIRType *GetInt8() const
198     {
199         DEBUG_ASSERT(PTY_i8 < typeTable.size(), "array index out of range");
200         return typeTable.at(PTY_i8);
201     }
202 
203     MIRType *GetUInt16() const
204     {
205         DEBUG_ASSERT(PTY_u16 < typeTable.size(), "array index out of range");
206         return typeTable.at(PTY_u16);
207     }
208 
209     MIRType *GetInt16() const
210     {
211         DEBUG_ASSERT(PTY_i16 < typeTable.size(), "array index out of range");
212         return typeTable.at(PTY_i16);
213     }
214 
215     MIRType *GetInt32() const
216     {
217         DEBUG_ASSERT(PTY_i32 < typeTable.size(), "array index out of range");
218         return typeTable.at(PTY_i32);
219     }
220 
221     MIRType *GetUInt32() const
222     {
223         DEBUG_ASSERT(PTY_u32 < typeTable.size(), "array index out of range");
224         return typeTable.at(PTY_u32);
225     }
226 
227     MIRType *GetInt64() const
228     {
229         DEBUG_ASSERT(PTY_i64 < typeTable.size(), "array index out of range");
230         return typeTable.at(PTY_i64);
231     }
232 
233     MIRType *GetUInt64() const
234     {
235         DEBUG_ASSERT(PTY_u64 < typeTable.size(), "array index out of range");
236         return typeTable.at(PTY_u64);
237     }
238 
239     MIRType *GetPtr() const
240     {
241         DEBUG_ASSERT(PTY_ptr < typeTable.size(), "array index out of range");
242         return typeTable.at(PTY_ptr);
243     }
244 
245 #ifdef USE_ARM32_MACRO
246     MIRType *GetUIntType() const
247     {
248         DEBUG_ASSERT(PTY_u32 < typeTable.size(), "array index out of range");
249         return typeTable.at(PTY_u32);
250     }
251 
252     MIRType *GetPtrType() const
253     {
254         DEBUG_ASSERT(PTY_u32 < typeTable.size(), "array index out of range");
255         return typeTable.at(PTY_u32);
256     }
257 #else
258     MIRType *GetUIntType() const
259     {
260         DEBUG_ASSERT(PTY_u64 < typeTable.size(), "array index out of range");
261         return typeTable.at(PTY_u64);
262     }
263 
264     MIRType *GetPtrType() const
265     {
266         DEBUG_ASSERT(PTY_ptr < typeTable.size(), "array index out of range");
267         return typeTable.at(PTY_ptr);
268     }
269 #endif
270 
271 #ifdef USE_32BIT_REF
272     MIRType *GetCompactPtr() const
273     {
274         DEBUG_ASSERT(PTY_u32 < typeTable.size(), "array index out of range");
275         return typeTable.at(PTY_u32);
276     }
277 
278 #else
279     MIRType *GetCompactPtr() const
280     {
281         DEBUG_ASSERT(PTY_u64 < typeTable.size(), "array index out of range");
282         return typeTable.at(PTY_u64);
283     }
284 
285 #endif
286     MIRType *GetRef() const
287     {
288         DEBUG_ASSERT(PTY_ref < typeTable.size(), "array index out of range");
289         return typeTable.at(PTY_ref);
290     }
291 
292     MIRType *GetAddr64() const
293     {
294         DEBUG_ASSERT(PTY_a64 < typeTable.size(), "array index out of range");
295         return typeTable.at(PTY_a64);
296     }
297 
298     MIRType *GetVoid() const
299     {
300         DEBUG_ASSERT(PTY_void < typeTable.size(), "array index out of range");
301         return typeTable.at(PTY_void);
302     }
303 
304     // Get or Create derived types.
305     MIRType *GetOrCreatePointerType(const TyIdx &pointedTyIdx, PrimType primType = PTY_ptr,
306                                     const TypeAttrs &attrs = TypeAttrs());
307     MIRType *GetOrCreatePointerType(const MIRType &pointTo, PrimType primType = PTY_ptr,
308                                     const TypeAttrs &attrs = TypeAttrs());
309     MIRType *GetVoidPtr() const
310     {
311         DEBUG_ASSERT(voidPtrType != nullptr, "voidPtrType should not be null");
312         return voidPtrType;
313     }
314 
315     MIRType *GetOrCreateFunctionType(const TyIdx &, const std::vector<TyIdx> &, const std::vector<TypeAttrs> &,
316                                      bool isVarg = false, const TypeAttrs &retAttrs = TypeAttrs());
317 
318     TyIdx lastDefaultTyIdx;
319 
320 private:
321     using MIRTypePtr = MIRType *;
322     struct Hash {
323         size_t operator()(const MIRTypePtr &ty) const
324         {
325             return ty->GetHashIndex();
326         }
327     };
328 
329     struct Equal {
330         bool operator()(const MIRTypePtr &tx, const MIRTypePtr &ty) const
331         {
332             return tx->EqualTo(*ty);
333         }
334     };
335 
336     // create an entry in typeTable for the type node
337     MIRType *CreateType(const MIRType &oldType)
338     {
339         MIRType *newType = oldType.CopyMIRTypeNode();
340         newType->SetTypeIndex(TyIdx(typeTable.size()));
341         typeTable.push_back(newType);
342         return newType;
343     }
344 
345     void PushNull()
346     {
347         typeTable.push_back(nullptr);
348     }
349     void PopBack()
350     {
351         typeTable.pop_back();
352     }
353 
354     MIRType *CreateAndUpdateMirTypeNode(MIRType &pType);
355 
356     MIRType *CreateMirType(uint32 primTypeIdx) const;
357     void PutToHashTable(MIRType *mirType);
358 
359     std::unordered_set<MIRTypePtr, Hash, Equal> typeHashTable;
360     std::unordered_map<TyIdx, TyIdx, TyIdxHash> ptrTypeMap;
361     std::unordered_map<TyIdx, TyIdx, TyIdxHash> refTypeMap;
362     std::vector<MIRType *> typeTable;
363     mutable std::shared_timed_mutex mtx;
364 };
365 
366 class StrPtrHash {
367 public:
368     size_t operator()(const std::string *str) const
369     {
370         return std::hash<std::string> {}(*str);
371     }
372 
373     size_t operator()(const std::u16string *str) const
374     {
375         return std::hash<std::u16string> {}(*str);
376     }
377 };
378 
379 class StrPtrEqual {
380 public:
381     bool operator()(const std::string *str1, const std::string *str2) const
382     {
383         return *str1 == *str2;
384     }
385 
386     bool operator()(const std::u16string *str1, const std::u16string *str2) const
387     {
388         return *str1 == *str2;
389     }
390 };
391 
392 // T can be std::string or std::u16string
393 // U can be GStrIdx, UStrIdx, or U16StrIdx
394 template <typename T, typename U>
395 class StringTable {
396 public:
397     StringTable() = default;
398     StringTable(const StringTable &) = delete;
399     StringTable &operator=(const StringTable &) = delete;
400 
401     ~StringTable()
402     {
403         ReleaseStrings();
404     }
405 
406     void Init()
407     {
408         // initialize 0th entry of stringTable with an empty string
409         T *ptr = new T;
410         stringTable.push_back(ptr);
411     }
412 
413     void Reset()
414     {
415         ReleaseStrings();
416         stringTable.clear();
417         Init();
418     }
419 
420     void ReleaseStrings()
421     {
422         stringTableMap.clear();
423         for (auto it : stringTable) {
424             delete it;
425         }
426     }
427 
428     U GetStrIdxFromName(const T &str) const
429     {
430         auto it = stringTableMap.find(&str);
431         if (it == stringTableMap.end()) {
432             return U(0);
433         }
434         return it->second;
435     }
436 
437     U GetOrCreateStrIdxFromName(const T &str)
438     {
439         U strIdx = GetStrIdxFromName(str);
440         if (strIdx == 0u) {
441             strIdx.reset(stringTable.size());
442             T *newStr = new T(str);
443             stringTable.push_back(newStr);
444             stringTableMap[newStr] = strIdx;
445         }
446         return strIdx;
447     }
448 
449     size_t StringTableSize() const
450     {
451         return stringTable.size();
452     }
453 
454     const T &GetStringFromStrIdx(U strIdx) const
455     {
456         DEBUG_ASSERT(strIdx < stringTable.size(), "array index out of range");
457         return *stringTable[strIdx];
458     }
459 
460     const T &GetStringFromStrIdx(uint32 idx) const
461     {
462         DEBUG_ASSERT(idx < stringTable.size(), "array index out of range");
463         return *stringTable[idx];
464     }
465 
466 private:
467     std::vector<const T *> stringTable;  // index is uint32
468     std::unordered_map<const T *, U, StrPtrHash, StrPtrEqual> stringTableMap;
469     mutable std::shared_timed_mutex mtx;
470 };
471 
472 class FPConstTable {
473 public:
474     FPConstTable(const FPConstTable &p) = delete;
475     FPConstTable &operator=(const FPConstTable &p) = delete;
476     ~FPConstTable();
477 
478     // get the const from floatConstTable or create a new one
479     MIRFloatConst *GetOrCreateFloatConst(float fval);
480     // get the const from doubleConstTable or create a new one
481     MIRDoubleConst *GetOrCreateDoubleConst(double fval);
482 
483     static std::unique_ptr<FPConstTable> Create()
484     {
485         auto p = std::unique_ptr<FPConstTable>(new FPConstTable());
486         p->PostInit();
487         return p;
488     }
489 
490 private:
491     FPConstTable() : floatConstTable(), doubleConstTable() {};
492     void PostInit();
493     MIRFloatConst *DoGetOrCreateFloatConst(float);
494     MIRDoubleConst *DoGetOrCreateDoubleConst(double);
495     std::shared_timed_mutex floatMtx;
496     std::shared_timed_mutex doubleMtx;
497     std::unordered_map<float, MIRFloatConst *> floatConstTable;     // map float const value to the table;
498     std::unordered_map<double, MIRDoubleConst *> doubleConstTable;  // map double const value to the table;
499     MIRFloatConst *nanFloatConst = nullptr;
500     MIRFloatConst *infFloatConst = nullptr;
501     MIRFloatConst *minusInfFloatConst = nullptr;
502     MIRFloatConst *minusZeroFloatConst = nullptr;
503     MIRDoubleConst *nanDoubleConst = nullptr;
504     MIRDoubleConst *infDoubleConst = nullptr;
505     MIRDoubleConst *minusInfDoubleConst = nullptr;
506     MIRDoubleConst *minusZeroDoubleConst = nullptr;
507 };
508 
509 class IntConstTable {
510 public:
511     IntConstTable(const IntConstTable &p) = delete;
512     IntConstTable &operator=(const IntConstTable &p) = delete;
513     ~IntConstTable();
514 
515     MIRIntConst *GetOrCreateIntConst(uint64 val, MIRType &type);
516 
517     static std::unique_ptr<IntConstTable> Create()
518     {
519         auto p = std::unique_ptr<IntConstTable>(new IntConstTable());
520         return p;
521     }
522 
523 private:
524     IntConstTable() = default;
525     MIRIntConst *DoGetOrCreateIntConst(uint64 val, MIRType &type);
526     std::shared_timed_mutex mtx;
527     std::unordered_map<IntConstKey, MIRIntConst *, IntConstHash, IntConstCmp> intConstTable;
528 };
529 
530 // STypeNameTable is only used to store class and interface types.
531 // Each module maintains its own MIRTypeNameTable.
532 class STypeNameTable {
533 public:
534     STypeNameTable() = default;
535     virtual ~STypeNameTable() = default;
536 
537     void Reset()
538     {
539         gStrIdxToTyIdxMap.clear();
540     }
541 
542     const std::unordered_map<GStrIdx, TyIdx, GStrIdxHash> &GetGStridxToTyidxMap() const
543     {
544         return gStrIdxToTyIdxMap;
545     }
546 
547     TyIdx GetTyIdxFromGStrIdx(GStrIdx idx) const
548     {
549         const auto it = gStrIdxToTyIdxMap.find(idx);
550         if (it == gStrIdxToTyIdxMap.cend()) {
551             return TyIdx(0);
552         }
553         return it->second;
554     }
555 
556     void SetGStrIdxToTyIdx(GStrIdx gStrIdx, TyIdx tyIdx)
557     {
558         gStrIdxToTyIdxMap[gStrIdx] = tyIdx;
559     }
560 
561 private:
562     std::unordered_map<GStrIdx, TyIdx, GStrIdxHash> gStrIdxToTyIdxMap;
563 };
564 
565 class FunctionTable {
566 public:
567     FunctionTable()
568     {
569         Init();
570     }
571 
572     virtual ~FunctionTable() = default;
573 
574     void Init()
575     {
576         // puIdx 0 is reserved
577         funcTable.push_back(nullptr);
578     }
579 
580     void Reset()
581     {
582         funcTable.clear();
583         Init();
584     }
585 
586     std::vector<MIRFunction *> &GetFuncTable()
587     {
588         return funcTable;
589     }
590 
591     MIRFunction *GetFunctionFromPuidx(PUIdx pIdx) const
592     {
593         CHECK_FATAL(pIdx < funcTable.size(), "Invalid puIdx");
594         return funcTable.at(pIdx);
595     }
596 
597     void SetFunctionItem(uint32 pIdx, MIRFunction *func)
598     {
599         CHECK_FATAL(pIdx < funcTable.size(), "Invalid puIdx");
600         funcTable[pIdx] = func;
601     }
602 
603 private:
604     std::vector<MIRFunction *> funcTable;  // index is PUIdx
605 };
606 
607 class GSymbolTable {
608 public:
609     GSymbolTable();
610     GSymbolTable(const GSymbolTable &) = delete;
611     GSymbolTable &operator=(const GSymbolTable &) = delete;
612     ~GSymbolTable();
613 
614     void Init();
615     void Reset();
616     void ReleaseSymbols();
617 
618     MIRModule *GetModule()
619     {
620         return module;
621     }
622 
623     void SetModule(MIRModule *m)
624     {
625         module = m;
626     }
627 
628     bool IsValidIdx(size_t idx) const
629     {
630         return idx < symbolTable.size();
631     }
632 
633     MIRSymbol *GetSymbolFromStidx(uint32 idx, bool checkFirst = false) const
634     {
635         if (checkFirst && idx >= symbolTable.size()) {
636             return nullptr;
637         }
638         DEBUG_ASSERT(IsValidIdx(idx), "symbol table index out of range");
639         return symbolTable[idx];
640     }
641 
642     void SetStrIdxStIdxMap(GStrIdx strIdx, StIdx stIdx)
643     {
644         strIdxToStIdxMap[strIdx] = stIdx;
645     }
646 
647     StIdx GetStIdxFromStrIdx(GStrIdx idx) const
648     {
649         const auto it = strIdxToStIdxMap.find(idx);
650         if (it == strIdxToStIdxMap.cend()) {
651             return StIdx();
652         }
653         return it->second;
654     }
655 
656     MIRSymbol *GetSymbolFromStrIdx(GStrIdx idx, bool checkFirst = false) const
657     {
658         return GetSymbolFromStidx(GetStIdxFromStrIdx(idx).Idx(), checkFirst);
659     }
660 
661     auto &GetTable()
662     {
663         return symbolTable;
664     }
665 
666     size_t GetSymbolTableSize() const
667     {
668         return symbolTable.size();
669     }
670 
671     MIRSymbol *GetSymbol(uint32 idx) const
672     {
673         DEBUG_ASSERT(idx < symbolTable.size(), "array index out of range");
674         return symbolTable.at(idx);
675     }
676 
677     MIRSymbol *CreateSymbol(uint8 scopeID);
678     bool AddToStringSymbolMap(const MIRSymbol &st);
679 #ifdef ARK_LITECG_DEBUG
680     void Dump(bool isLocal, int32 indent = 0) const;
681 #endif
682 
683 private:
684     MIRModule *module = nullptr;
685     // hash table mapping string index to st index
686     std::unordered_map<GStrIdx, StIdx, GStrIdxHash> strIdxToStIdxMap;
687     std::vector<MIRSymbol *> symbolTable;  // map symbol idx to symbol node
688 };
689 
690 class ConstPool {
691 public:
692     std::unordered_map<std::u16string, MIRSymbol *> &GetConstU16StringPool()
693     {
694         return constU16StringPool;
695     }
696 
697     void Reset()
698     {
699         constMap.clear();
700         importedLiteralNames.clear();
701         constU16StringPool.clear();
702     }
703 
704     void InsertConstPool(GStrIdx strIdx, MIRConst *cst)
705     {
706         (void)constMap.emplace(strIdx, cst);
707     }
708 
709     MIRConst *GetConstFromPool(GStrIdx strIdx)
710     {
711         return constMap[strIdx];
712     }
713 
714     void PutLiteralNameAsImported(GStrIdx gIdx)
715     {
716         (void)importedLiteralNames.insert(gIdx);
717     }
718 
719     bool LookUpLiteralNameFromImported(GStrIdx gIdx)
720     {
721         return importedLiteralNames.find(gIdx) != importedLiteralNames.end();
722     }
723 
724 protected:
725     std::unordered_map<GStrIdx, MIRConst *, GStrIdxHash> constMap;
726     std::set<GStrIdx> importedLiteralNames;
727 
728 private:
729     std::unordered_map<std::u16string, MIRSymbol *> constU16StringPool;
730 };
731 
732 class GlobalTables {
733 public:
734     static GlobalTables &GetGlobalTables();
735 
736     static StringTable<std::string, GStrIdx> &GetStrTable()
737     {
738         return globalTables.gStringTable;
739     }
740 
741     static StringTable<std::string, UStrIdx> &GetUStrTable()
742     {
743         return globalTables.uStrTable;
744     }
745 
746     static StringTable<std::u16string, U16StrIdx> &GetU16StrTable()
747     {
748         return globalTables.u16StringTable;
749     }
750 
751     static TypeTable &GetTypeTable()
752     {
753         return globalTables.typeTable;
754     }
755 
756     static FPConstTable &GetFpConstTable()
757     {
758         return *(globalTables.fpConstTablePtr);
759     }
760 
761     static STypeNameTable &GetTypeNameTable()
762     {
763         return globalTables.typeNameTable;
764     }
765 
766     static FunctionTable &GetFunctionTable()
767     {
768         return globalTables.functionTable;
769     }
770 
771     static GSymbolTable &GetGsymTable()
772     {
773         return globalTables.gSymbolTable;
774     }
775 
776     static ConstPool &GetConstPool()
777     {
778         return globalTables.constPool;
779     }
780 
781     static IntConstTable &GetIntConstTable()
782     {
783         return *(globalTables.intConstTablePtr);
784     }
785 
786     static void Reset()
787     {
788         globalTables.typeTable.Reset();
789         globalTables.typeNameTable.Reset();
790         globalTables.functionTable.Reset();
791         globalTables.gSymbolTable.Reset();
792         globalTables.constPool.Reset();
793         globalTables.fpConstTablePtr = FPConstTable::Create();
794         globalTables.intConstTablePtr = IntConstTable::Create();
795         globalTables.gStringTable.Reset();
796         globalTables.uStrTable.Reset();
797         globalTables.u16StringTable.Reset();
798     }
799 
800     GlobalTables(const GlobalTables &globalTables) = delete;
801     GlobalTables(const GlobalTables &&globalTables) = delete;
802     GlobalTables &operator=(const GlobalTables &globalTables) = delete;
803     GlobalTables &operator=(const GlobalTables &&globalTables) = delete;
804 
805 private:
806     GlobalTables() : fpConstTablePtr(FPConstTable::Create()), intConstTablePtr(IntConstTable::Create())
807     {
808         gStringTable.Init();
809         uStrTable.Init();
810         u16StringTable.Init();
811     }
812     virtual ~GlobalTables() = default;
813     static GlobalTables globalTables;
814 
815     TypeTable typeTable;
816     STypeNameTable typeNameTable;
817     FunctionTable functionTable;
818     GSymbolTable gSymbolTable;
819     ConstPool constPool;
820     std::unique_ptr<FPConstTable> fpConstTablePtr;
821     std::unique_ptr<IntConstTable> intConstTablePtr;
822     StringTable<std::string, GStrIdx> gStringTable;
823     StringTable<std::string, UStrIdx> uStrTable;
824     StringTable<std::u16string, U16StrIdx> u16StringTable;
825 };
826 
827 inline MIRType &GetTypeFromTyIdx(TyIdx idx)
828 {
829     return *(GlobalTables::GetTypeTable().GetTypeFromTyIdx(idx));
830 }
831 }  // namespace maple
832 #endif  // MAPLE_IR_INCLUDE_GLOBAL_TABLES_H
833