• 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_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()39     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()48     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()57     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()78     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()86     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()112     const std::vector<MIRType *> &GetTypeTable() const
113     {
114         return typeTable;
115     }
116 
GetTypeHashTable()117     auto &GetTypeHashTable() const
118     {
119         return typeHashTable;
120     }
121 
GetPtrTypeMap()122     auto &GetPtrTypeMap() const
123     {
124         return ptrTypeMap;
125     }
126 
GetRefTypeMap()127     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)136     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 
GetTypeFromTyIdx(uint32 index)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 
GetPrimTypeFromTyIdx(const TyIdx & tyIdx)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 
GetOrCreateMIRType(MIRType * pType)156     TyIdx GetOrCreateMIRType(MIRType *pType)
157     {
158         return GetOrCreateMIRTypeNode(*pType)->GetTypeIndex();
159     }
160 
GetTypeTableSize()161     uint32 GetTypeTableSize() const
162     {
163         return static_cast<uint32>(typeTable.size());
164     }
165 
166     // Get primtive types.
GetPrimType(PrimType primType)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 
GetFloat()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 
GetDouble()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 
GetUInt1()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 
GetUInt8()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 
GetInt8()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 
GetUInt16()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 
GetInt16()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 
GetInt32()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 
GetUInt32()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 
GetInt64()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 
GetUInt64()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 
GetPtr()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
GetUIntType()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 
GetPtrType()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
GetUIntType()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 
GetPtrType()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
GetCompactPtr()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
GetCompactPtr()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
GetRef()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 
GetAddr64()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 
GetVoid()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());
GetVoidPtr()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 {
operatorHash323         size_t operator()(const MIRTypePtr &ty) const
324         {
325             return ty->GetHashIndex();
326         }
327     };
328 
329     struct Equal {
operatorEqual330         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
CreateType(const MIRType & oldType)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 
PushNull()345     void PushNull()
346     {
347         typeTable.push_back(nullptr);
348     }
PopBack()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:
operator()368     size_t operator()(const std::string *str) const
369     {
370         return std::hash<std::string> {}(*str);
371     }
372 
operator()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:
operator()381     bool operator()(const std::string *str1, const std::string *str2) const
382     {
383         return *str1 == *str2;
384     }
385 
operator()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 
~StringTable()401     ~StringTable()
402     {
403         ReleaseStrings();
404     }
405 
Init()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 
Reset()413     void Reset()
414     {
415         ReleaseStrings();
416         stringTable.clear();
417         Init();
418     }
419 
ReleaseStrings()420     void ReleaseStrings()
421     {
422         stringTableMap.clear();
423         for (auto it : stringTable) {
424             delete it;
425         }
426     }
427 
GetStrIdxFromName(const T & str)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 
GetOrCreateStrIdxFromName(const T & str)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 
StringTableSize()449     size_t StringTableSize() const
450     {
451         return stringTable.size();
452     }
453 
GetStringFromStrIdx(U strIdx)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 
GetStringFromStrIdx(uint32 idx)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 
Create()483     static std::unique_ptr<FPConstTable> Create()
484     {
485         auto p = std::make_unique<FPConstTable>();
486         p->PostInit();
487         return p;
488     }
489 
490 private:
FPConstTable()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     friend std::unique_ptr<FPConstTable> std::make_unique<FPConstTable>();
509 };
510 
511 class IntConstTable {
512 public:
513     IntConstTable(const IntConstTable &p) = delete;
514     IntConstTable &operator=(const IntConstTable &p) = delete;
515     ~IntConstTable();
516 
517     MIRIntConst *GetOrCreateIntConst(uint64 val, MIRType &type);
518 
Create()519     static std::unique_ptr<IntConstTable> Create()
520     {
521         auto p = std::make_unique<IntConstTable>();
522         return p;
523     }
524 
525 private:
526     IntConstTable() = default;
527     MIRIntConst *DoGetOrCreateIntConst(uint64 val, MIRType &type);
528     std::shared_timed_mutex mtx;
529     std::unordered_map<IntConstKey, MIRIntConst *, IntConstHash, IntConstCmp> intConstTable;
530 
531     friend std::unique_ptr<IntConstTable> std::make_unique<IntConstTable>();
532 };
533 
534 // STypeNameTable is only used to store class and interface types.
535 // Each module maintains its own MIRTypeNameTable.
536 class STypeNameTable {
537 public:
538     STypeNameTable() = default;
539     virtual ~STypeNameTable() = default;
540 
Reset()541     void Reset()
542     {
543         gStrIdxToTyIdxMap.clear();
544     }
545 
GetGStridxToTyidxMap()546     const std::unordered_map<GStrIdx, TyIdx, GStrIdxHash> &GetGStridxToTyidxMap() const
547     {
548         return gStrIdxToTyIdxMap;
549     }
550 
GetTyIdxFromGStrIdx(GStrIdx idx)551     TyIdx GetTyIdxFromGStrIdx(GStrIdx idx) const
552     {
553         const auto it = gStrIdxToTyIdxMap.find(idx);
554         if (it == gStrIdxToTyIdxMap.cend()) {
555             return TyIdx(0);
556         }
557         return it->second;
558     }
559 
SetGStrIdxToTyIdx(GStrIdx gStrIdx,TyIdx tyIdx)560     void SetGStrIdxToTyIdx(GStrIdx gStrIdx, TyIdx tyIdx)
561     {
562         gStrIdxToTyIdxMap[gStrIdx] = tyIdx;
563     }
564 
565 private:
566     std::unordered_map<GStrIdx, TyIdx, GStrIdxHash> gStrIdxToTyIdxMap;
567 };
568 
569 class FunctionTable {
570 public:
FunctionTable()571     FunctionTable()
572     {
573         Init();
574     }
575 
576     virtual ~FunctionTable() = default;
577 
Init()578     void Init()
579     {
580         // puIdx 0 is reserved
581         funcTable.push_back(nullptr);
582     }
583 
Reset()584     void Reset()
585     {
586         funcTable.clear();
587         Init();
588     }
589 
GetFuncTable()590     std::vector<MIRFunction *> &GetFuncTable()
591     {
592         return funcTable;
593     }
594 
GetFunctionFromPuidx(PUIdx pIdx)595     MIRFunction *GetFunctionFromPuidx(PUIdx pIdx) const
596     {
597         CHECK_FATAL(pIdx < funcTable.size(), "Invalid puIdx");
598         return funcTable.at(pIdx);
599     }
600 
SetFunctionItem(uint32 pIdx,MIRFunction * func)601     void SetFunctionItem(uint32 pIdx, MIRFunction *func)
602     {
603         CHECK_FATAL(pIdx < funcTable.size(), "Invalid puIdx");
604         funcTable[pIdx] = func;
605     }
606 
607 private:
608     std::vector<MIRFunction *> funcTable;  // index is PUIdx
609 };
610 
611 class GSymbolTable {
612 public:
613     GSymbolTable();
614     GSymbolTable(const GSymbolTable &) = delete;
615     GSymbolTable &operator=(const GSymbolTable &) = delete;
616     ~GSymbolTable();
617 
618     void Init();
619     void Reset();
620     void ReleaseSymbols();
621 
GetModule()622     MIRModule *GetModule()
623     {
624         return module;
625     }
626 
SetModule(MIRModule * m)627     void SetModule(MIRModule *m)
628     {
629         module = m;
630     }
631 
IsValidIdx(size_t idx)632     bool IsValidIdx(size_t idx) const
633     {
634         return idx < symbolTable.size();
635     }
636 
637     MIRSymbol *GetSymbolFromStidx(uint32 idx, bool checkFirst = false) const
638     {
639         if (checkFirst && idx >= symbolTable.size()) {
640             return nullptr;
641         }
642         DEBUG_ASSERT(IsValidIdx(idx), "symbol table index out of range");
643         return symbolTable[idx];
644     }
645 
SetStrIdxStIdxMap(GStrIdx strIdx,StIdx stIdx)646     void SetStrIdxStIdxMap(GStrIdx strIdx, StIdx stIdx)
647     {
648         strIdxToStIdxMap[strIdx] = stIdx;
649     }
650 
GetStIdxFromStrIdx(GStrIdx idx)651     StIdx GetStIdxFromStrIdx(GStrIdx idx) const
652     {
653         const auto it = strIdxToStIdxMap.find(idx);
654         if (it == strIdxToStIdxMap.cend()) {
655             return StIdx();
656         }
657         return it->second;
658     }
659 
660     MIRSymbol *GetSymbolFromStrIdx(GStrIdx idx, bool checkFirst = false) const
661     {
662         return GetSymbolFromStidx(GetStIdxFromStrIdx(idx).Idx(), checkFirst);
663     }
664 
GetTable()665     auto &GetTable()
666     {
667         return symbolTable;
668     }
669 
GetSymbolTableSize()670     size_t GetSymbolTableSize() const
671     {
672         return symbolTable.size();
673     }
674 
GetSymbol(uint32 idx)675     MIRSymbol *GetSymbol(uint32 idx) const
676     {
677         DEBUG_ASSERT(idx < symbolTable.size(), "array index out of range");
678         return symbolTable.at(idx);
679     }
680 
681     MIRSymbol *CreateSymbol(uint8 scopeID);
682     bool AddToStringSymbolMap(const MIRSymbol &st);
683 #ifdef ARK_LITECG_DEBUG
684     void Dump(bool isLocal, int32 indent = 0) const;
685 #endif
686 
687 private:
688     MIRModule *module = nullptr;
689     // hash table mapping string index to st index
690     std::unordered_map<GStrIdx, StIdx, GStrIdxHash> strIdxToStIdxMap;
691     std::vector<MIRSymbol *> symbolTable;  // map symbol idx to symbol node
692 };
693 
694 class ConstPool {
695 public:
GetConstU16StringPool()696     std::unordered_map<std::u16string, MIRSymbol *> &GetConstU16StringPool()
697     {
698         return constU16StringPool;
699     }
700 
Reset()701     void Reset()
702     {
703         constMap.clear();
704         importedLiteralNames.clear();
705         constU16StringPool.clear();
706     }
707 
InsertConstPool(GStrIdx strIdx,MIRConst * cst)708     void InsertConstPool(GStrIdx strIdx, MIRConst *cst)
709     {
710         (void)constMap.emplace(strIdx, cst);
711     }
712 
GetConstFromPool(GStrIdx strIdx)713     MIRConst *GetConstFromPool(GStrIdx strIdx)
714     {
715         return constMap[strIdx];
716     }
717 
PutLiteralNameAsImported(GStrIdx gIdx)718     void PutLiteralNameAsImported(GStrIdx gIdx)
719     {
720         (void)importedLiteralNames.insert(gIdx);
721     }
722 
LookUpLiteralNameFromImported(GStrIdx gIdx)723     bool LookUpLiteralNameFromImported(GStrIdx gIdx)
724     {
725         return importedLiteralNames.find(gIdx) != importedLiteralNames.end();
726     }
727 
728 protected:
729     std::unordered_map<GStrIdx, MIRConst *, GStrIdxHash> constMap;
730     std::set<GStrIdx> importedLiteralNames;
731 
732 private:
733     std::unordered_map<std::u16string, MIRSymbol *> constU16StringPool;
734 };
735 
736 class GlobalTables {
737 public:
738     static GlobalTables &GetGlobalTables();
739 
GetStrTable()740     static StringTable<std::string, GStrIdx> &GetStrTable()
741     {
742         return globalTables.gStringTable;
743     }
744 
GetUStrTable()745     static StringTable<std::string, UStrIdx> &GetUStrTable()
746     {
747         return globalTables.uStrTable;
748     }
749 
GetU16StrTable()750     static StringTable<std::u16string, U16StrIdx> &GetU16StrTable()
751     {
752         return globalTables.u16StringTable;
753     }
754 
GetTypeTable()755     static TypeTable &GetTypeTable()
756     {
757         return globalTables.typeTable;
758     }
759 
GetFpConstTable()760     static FPConstTable &GetFpConstTable()
761     {
762         return *(globalTables.fpConstTablePtr);
763     }
764 
GetTypeNameTable()765     static STypeNameTable &GetTypeNameTable()
766     {
767         return globalTables.typeNameTable;
768     }
769 
GetFunctionTable()770     static FunctionTable &GetFunctionTable()
771     {
772         return globalTables.functionTable;
773     }
774 
GetGsymTable()775     static GSymbolTable &GetGsymTable()
776     {
777         return globalTables.gSymbolTable;
778     }
779 
GetConstPool()780     static ConstPool &GetConstPool()
781     {
782         return globalTables.constPool;
783     }
784 
GetIntConstTable()785     static IntConstTable &GetIntConstTable()
786     {
787         return *(globalTables.intConstTablePtr);
788     }
789 
Reset()790     static void Reset()
791     {
792         globalTables.typeTable.Reset();
793         globalTables.typeNameTable.Reset();
794         globalTables.functionTable.Reset();
795         globalTables.gSymbolTable.Reset();
796         globalTables.constPool.Reset();
797         globalTables.fpConstTablePtr = FPConstTable::Create();
798         globalTables.intConstTablePtr = IntConstTable::Create();
799         globalTables.gStringTable.Reset();
800         globalTables.uStrTable.Reset();
801         globalTables.u16StringTable.Reset();
802     }
803 
804     GlobalTables(const GlobalTables &globalTables) = delete;
805     GlobalTables(const GlobalTables &&globalTables) = delete;
806     GlobalTables &operator=(const GlobalTables &globalTables) = delete;
807     GlobalTables &operator=(const GlobalTables &&globalTables) = delete;
808 
809 private:
GlobalTables()810     GlobalTables() : fpConstTablePtr(FPConstTable::Create()), intConstTablePtr(IntConstTable::Create())
811     {
812         gStringTable.Init();
813         uStrTable.Init();
814         u16StringTable.Init();
815     }
816     virtual ~GlobalTables() = default;
817     static GlobalTables globalTables;
818 
819     TypeTable typeTable;
820     STypeNameTable typeNameTable;
821     FunctionTable functionTable;
822     GSymbolTable gSymbolTable;
823     ConstPool constPool;
824     std::unique_ptr<FPConstTable> fpConstTablePtr;
825     std::unique_ptr<IntConstTable> intConstTablePtr;
826     StringTable<std::string, GStrIdx> gStringTable;
827     StringTable<std::string, UStrIdx> uStrTable;
828     StringTable<std::u16string, U16StrIdx> u16StringTable;
829 };
830 
GetTypeFromTyIdx(TyIdx idx)831 inline MIRType &GetTypeFromTyIdx(TyIdx idx)
832 {
833     return *(GlobalTables::GetTypeTable().GetTypeFromTyIdx(idx));
834 }
835 }  // namespace maple
836 #endif  // MAPLE_IR_INCLUDE_GLOBAL_TABLES_H
837