• 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_SYMBOL_H
17 #define MAPLE_IR_INCLUDE_MIR_SYMBOL_H
18 #include <sstream>
19 #include "mir_const.h"
20 #include "mir_preg.h"
21 #include "src_position.h"
22 #include "triple.h"
23 
24 constexpr int kScopeLocal = 2;   // the default scope level for function variables
25 constexpr int kScopeGlobal = 1;  // the scope level for global variables
26 
27 namespace maple {
28 enum MIRSymKind { kStInvalid, kStVar, kStFunc, kStConst, kStPreg };
29 
30 const std::string kConstString = "_C_STR_";
31 const std::string kConstStringPtr = "_PTR_C_STR_";
32 
33 enum MIRStorageClass : uint8 {
34     kScInvalid,
35     kScAuto,
36     kScAliased,
37     kScFormal,
38     kScExtern,
39     kScGlobal,
40     kScPstatic,  // PU-static
41     kScFstatic,  // file-static
42     kScText,
43     kScTypeInfo,      // used for eh type st
44     kScTypeInfoName,  // used for eh type st name
45     kScTypeCxxAbi,    // used for eh inherited from c++ __cxxabiv1
46     kScEHRegionSupp,  // used for tables that control C++ exception handling
47     kScUnused
48 };
49 
50 // to represent a single symbol
51 class MIRSymbol {
52 public:
53     union SymbolType {  // a symbol can either be a const or a function or a preg which currently used for formal
54         MIRConst *konst;
55         MIRFunction *mirFunc;
56         MIRPreg *preg;  // the MIRSymKind must be kStPreg
57     };
58 
59     MIRSymbol() = default;
MIRSymbol(uint32 idx,uint8 scp)60     MIRSymbol(uint32 idx, uint8 scp) : stIdx(scp, idx) {}
61     ~MIRSymbol() = default;
62 
SetIsTmp(bool temp)63     void SetIsTmp(bool temp)
64     {
65         isTmp = temp;
66     }
67 
GetIsTmp()68     bool GetIsTmp() const
69     {
70         return isTmp;
71     }
72 
SetNeedForwDecl()73     void SetNeedForwDecl()
74     {
75         needForwDecl = true;
76     }
77 
IsNeedForwDecl()78     bool IsNeedForwDecl() const
79     {
80         return needForwDecl;
81     }
82 
SetInstrumented()83     void SetInstrumented()
84     {
85         instrumented = true;
86     }
87 
IsInstrumented()88     bool IsInstrumented() const
89     {
90         return instrumented;
91     }
92 
SetIsImported(bool imported)93     void SetIsImported(bool imported)
94     {
95         isImported = imported;
96     }
97 
GetIsImported()98     bool GetIsImported() const
99     {
100         return isImported;
101     }
102 
SetWPOFakeParm()103     void SetWPOFakeParm()
104     {
105         wpoFakeParam = true;
106     }
107 
IsWpoFakeParm()108     bool IsWpoFakeParm() const
109     {
110         return wpoFakeParam;
111     }
112 
IsWpoFakeRet()113     bool IsWpoFakeRet() const
114     {
115         return wpoFakeRet;
116     }
117 
SetWPOFakeRet()118     void SetWPOFakeRet()
119     {
120         wpoFakeRet = true;
121     }
122 
SetIsTmpUnused(bool unused)123     void SetIsTmpUnused(bool unused)
124     {
125         isTmpUnused = unused;
126     }
127 
SetIsImportedDecl(bool imported)128     void SetIsImportedDecl(bool imported)
129     {
130         isImportedDecl = imported;
131     }
132 
GetIsImportedDecl()133     bool GetIsImportedDecl() const
134     {
135         return isImportedDecl;
136     }
137 
IsTmpUnused()138     bool IsTmpUnused() const
139     {
140         return isTmpUnused;
141     }
142 
SetAppearsInCode(bool appears)143     void SetAppearsInCode(bool appears)
144     {
145         appearsInCode = appears;
146     }
147 
GetAppearsInCode()148     bool GetAppearsInCode() const
149     {
150         return appearsInCode;
151     }
152 
SetTyIdx(TyIdx newTyIdx)153     void SetTyIdx(TyIdx newTyIdx)
154     {
155         this->tyIdx = newTyIdx;
156     }
157 
GetTyIdx()158     TyIdx GetTyIdx() const
159     {
160         return tyIdx;
161     }
162 
SetInferredTyIdx(TyIdx newInferredTyIdx)163     void SetInferredTyIdx(TyIdx newInferredTyIdx)
164     {
165         this->inferredTyIdx = newInferredTyIdx;
166     }
167 
GetInferredTyIdx()168     TyIdx GetInferredTyIdx() const
169     {
170         return inferredTyIdx;
171     }
172 
SetStIdx(StIdx newStIdx)173     void SetStIdx(StIdx newStIdx)
174     {
175         this->stIdx = newStIdx;
176     }
177 
GetStIdx()178     StIdx GetStIdx() const
179     {
180         return stIdx;
181     }
182 
SetSKind(MIRSymKind m)183     void SetSKind(MIRSymKind m)
184     {
185         sKind = m;
186     }
187 
GetSKind()188     MIRSymKind GetSKind() const
189     {
190         return sKind;
191     }
192 
GetScopeIdx()193     uint32 GetScopeIdx() const
194     {
195         return stIdx.Scope();
196     }
197 
GetStIndex()198     uint32 GetStIndex() const
199     {
200         return stIdx.Idx();
201     }
202 
IsLocal()203     bool IsLocal() const
204     {
205         return stIdx.Islocal();
206     }
207 
IsGlobal()208     bool IsGlobal() const
209     {
210         return stIdx.IsGlobal();
211     }
212 
GetAttrs()213     const TypeAttrs &GetAttrs() const
214     {
215         return typeAttrs;
216     }
217 
GetAttrs()218     TypeAttrs &GetAttrs()
219     {
220         return typeAttrs;
221     }
222 
SetAttrs(TypeAttrs attr)223     void SetAttrs(TypeAttrs attr)
224     {
225         typeAttrs = attr;
226     }
227 
228     // AddAttrs adds more attributes instead of overrides the current one
AddAttrs(TypeAttrs attr)229     void AddAttrs(TypeAttrs attr)
230     {
231         typeAttrs.SetAttrFlag(typeAttrs.GetAttrFlag() | attr.GetAttrFlag());
232         typeAttrs.AddAttrBoundary(attr.GetAttrBoundary());
233     }
234 
GetAttr(AttrKind attrKind)235     bool GetAttr(AttrKind attrKind) const
236     {
237         return typeAttrs.GetAttr(attrKind);
238     }
239 
SetAttr(AttrKind attrKind)240     void SetAttr(AttrKind attrKind)
241     {
242         typeAttrs.SetAttr(attrKind);
243     }
244 
ResetAttr(AttrKind attrKind)245     void ResetAttr(AttrKind attrKind)
246     {
247         typeAttrs.ResetAttr(attrKind);
248     }
249 
IsVolatile()250     bool IsVolatile() const
251     {
252         return typeAttrs.GetAttr(ATTR_volatile);
253     }
254 
IsThreadLocal()255     bool IsThreadLocal() const
256     {
257         return typeAttrs.GetAttr(ATTR_tls_static) || typeAttrs.GetAttr(ATTR_tls_dynamic);
258     }
259 
IsStatic()260     bool IsStatic() const
261     {
262         return typeAttrs.GetAttr(ATTR_static);
263     }
264 
IsPUStatic()265     bool IsPUStatic() const
266     {
267         return GetStorageClass() == kScPstatic;
268     }
269 
IsWeak()270     bool IsWeak() const
271     {
272         return typeAttrs.GetAttr(ATTR_weak);
273     }
274 
IsPrivate()275     bool IsPrivate() const
276     {
277         return typeAttrs.GetAttr(ATTR_private);
278     }
279 
IsRefType()280     bool IsRefType() const
281     {
282         return typeAttrs.GetAttr(ATTR_localrefvar);
283     }
284 
SetNameStrIdx(GStrIdx strIdx)285     void SetNameStrIdx(GStrIdx strIdx)
286     {
287         nameStrIdx = strIdx;
288     }
289 
290     void SetNameStrIdx(const std::string &name);
291 
GetNameStrIdx()292     GStrIdx GetNameStrIdx() const
293     {
294         return nameStrIdx;
295     }
296 
GetStorageClass()297     MIRStorageClass GetStorageClass() const
298     {
299         return storageClass;
300     }
301 
SetStorageClass(MIRStorageClass cl)302     void SetStorageClass(MIRStorageClass cl)
303     {
304         storageClass = cl;
305     }
306 
IsReadOnly()307     bool IsReadOnly() const
308     {
309         return kScFstatic == storageClass && kStConst == sKind;
310     }
311 
IsConst()312     bool IsConst() const
313     {
314         return sKind == kStConst || (sKind == kStVar && value.konst != nullptr);
315     }
316 
317     MIRType *GetType() const;
318 
GetName()319     const std::string &GetName() const
320     {
321         return GlobalTables::GetStrTable().GetStringFromStrIdx(nameStrIdx);
322     }
323 
GetKonst()324     MIRConst *GetKonst() const
325     {
326         DEBUG_ASSERT((sKind == kStConst || sKind == kStVar), "must be const symbol");
327         return value.konst;
328     }
329 
SetKonst(MIRConst * mirconst)330     void SetKonst(MIRConst *mirconst)
331     {
332         DEBUG_ASSERT((sKind == kStConst || sKind == kStVar), "must be const symbol");
333         value.konst = mirconst;
334     }
335 
SetIsDeleted()336     void SetIsDeleted()
337     {
338         isDeleted = true;
339     }
340 
ResetIsDeleted()341     void ResetIsDeleted()
342     {
343         isDeleted = false;
344     }
345 
IsDeleted()346     bool IsDeleted() const
347     {
348         return isDeleted;
349     }
350 
IsVar()351     bool IsVar() const
352     {
353         return sKind == kStVar;
354     }
355 
IsPreg()356     bool IsPreg() const
357     {
358         return sKind == kStPreg;
359     }
360 
GetValue()361     SymbolType GetValue() const
362     {
363         return value;
364     }
365 
SetValue(SymbolType newValue)366     void SetValue(SymbolType newValue)
367     {
368         this->value = newValue;
369     }
370 
GetSrcPosition()371     SrcPosition &GetSrcPosition()
372     {
373         return srcPosition;
374     }
375 
GetSrcPosition()376     const SrcPosition &GetSrcPosition() const
377     {
378         return srcPosition;
379     }
380 
SetSrcPosition(const SrcPosition & position)381     void SetSrcPosition(const SrcPosition &position)
382     {
383         srcPosition = position;
384     }
385 
GetPreg()386     MIRPreg *GetPreg()
387     {
388         DEBUG_ASSERT(IsPreg(), "must be Preg");
389         return value.preg;
390     }
391 
GetPreg()392     const MIRPreg *GetPreg() const
393     {
394         CHECK_FATAL(IsPreg(), "must be Preg");
395         return value.preg;
396     }
397 
SetPreg(MIRPreg * preg)398     void SetPreg(MIRPreg *preg)
399     {
400         CHECK_FATAL(IsPreg(), "must be Preg");
401         value.preg = preg;
402     }
403 
CanBeIgnored()404     bool CanBeIgnored() const
405     {
406         return isDeleted;
407     }
408 
SetLocalRefVar()409     void SetLocalRefVar()
410     {
411         SetAttr(ATTR_localrefvar);
412     }
413 
ResetLocalRefVar()414     void ResetLocalRefVar()
415     {
416         ResetAttr(ATTR_localrefvar);
417     }
418 
GetFunction()419     MIRFunction *GetFunction() const
420     {
421         DEBUG_ASSERT(sKind == kStFunc, "must be function symbol");
422         return value.mirFunc;
423     }
424 
SetFunction(MIRFunction * func)425     void SetFunction(MIRFunction *func)
426     {
427         DEBUG_ASSERT(sKind == kStFunc, "must be function symbol");
428         value.mirFunc = func;
429     }
430 
431 #ifdef ARK_LITECG_DEBUG
432     bool HasAddrOfValues() const;
433     bool IsLiteral() const;
434     bool IsLiteralPtr() const;
435     bool PointsToConstString() const;
436     bool IsConstString() const;
437     bool IsClassInitBridge() const;
438     bool IsReflectionStrTab() const;
439     bool IsReflectionHashTabBucket() const;
440     bool IsReflectionInfo() const;
441     bool IsReflectionFieldsInfo() const;
442     bool IsReflectionFieldsInfoCompact() const;
443     bool IsReflectionSuperclassInfo() const;
444     bool IsReflectionFieldOffsetData() const;
445     bool IsReflectionMethodAddrData() const;
446     bool IsReflectionMethodSignature() const;
447     bool IsReflectionClassInfo() const;
448     bool IsReflectionClassInfoPtr() const;
449     bool IsReflectionClassInfoRO() const;
450     bool IsITabConflictInfo() const;
451     bool IsReflectionPrimitiveClassInfo() const;
452     bool IsReflectionMethodsInfo() const;
453     bool IsReflectionMethodsInfoCompact() const;
454     bool IsRegJNITab() const;
455     bool IsRegJNIFuncTab() const;
456     bool IsMuidTab() const;
457     bool IsMuidRoTab() const;
458     bool IsCodeLayoutInfo() const;
459     std::string GetMuidTabName() const;
460     bool IsMuidFuncDefTab() const;
461     bool IsMuidFuncDefOrigTab() const;
462     bool IsMuidFuncInfTab() const;
463     bool IsMuidFuncUndefTab() const;
464     bool IsMuidDataDefTab() const;
465     bool IsMuidDataDefOrigTab() const;
466     bool IsMuidDataUndefTab() const;
467     bool IsMuidRangeTab() const;
468     bool IsArrayClassCache() const;
469     bool IsArrayClassCacheName() const;
470     bool IsGctibSym() const;
471     void Dump(bool isLocal, int32 indent, bool suppressInit = false, const MIRSymbolTable *localsymtab = nullptr) const;
472     void DumpAsLiteralVar() const;
473 #endif
474     bool operator==(const MIRSymbol &msym) const
475     {
476         return nameStrIdx == msym.nameStrIdx;
477     }
478 
479     bool operator!=(const MIRSymbol &msym) const
480     {
481         return nameStrIdx != msym.nameStrIdx;
482     }
483 
484     bool operator<(const MIRSymbol &msym) const
485     {
486         return nameStrIdx < msym.nameStrIdx;
487     }
488 
LastPrintedLineNumRef()489     static uint32 &LastPrintedLineNumRef()
490     {
491         return lastPrintedLineNum;
492     }
493 
LastPrintedColumnNumRef()494     static uint16 &LastPrintedColumnNumRef()
495     {
496         return lastPrintedColumnNum;
497     }
498 
HasPotentialAssignment()499     bool HasPotentialAssignment() const
500     {
501         return hasPotentialAssignment;
502     }
503 
SetHasPotentialAssignment()504     void SetHasPotentialAssignment()
505     {
506         hasPotentialAssignment = true;
507     }
508 
SetAsmAttr(const UStrIdx & idx)509     void SetAsmAttr(const UStrIdx &idx)
510     {
511         asmAttr = idx;
512     }
513 
GetAsmAttr()514     const UStrIdx &GetAsmAttr() const
515     {
516         return asmAttr;
517     }
518 
SetWeakrefAttr(const std::pair<bool,UStrIdx> & idx)519     void SetWeakrefAttr(const std::pair<bool, UStrIdx> &idx)
520     {
521         weakrefAttr = idx;
522     }
523 
GetWeakrefAttr()524     const std::pair<bool, UStrIdx> &GetWeakrefAttr() const
525     {
526         return weakrefAttr;
527     }
528 
IsFormal()529     bool IsFormal() const
530     {
531         return storageClass == kScFormal;
532     }
533 
LMBCAllocateOffSpecialReg()534     bool LMBCAllocateOffSpecialReg() const
535     {
536         if (isDeleted) {
537             return false;
538         }
539         switch (storageClass) {
540             case kScAuto:
541                 return true;
542             case kScPstatic:
543             case kScFstatic:
544                 return value.konst == nullptr && !hasPotentialAssignment;
545             default:
546                 return false;
547         }
548     }
549 
GetSymbolAlign()550     uint8 GetSymbolAlign() const
551     {
552         uint8 align = GetAttrs().GetAlignValue();
553         if (align == 0) {
554             align = static_cast<uint8>(GetType()->GetAlign());
555             if (Triple::GetTriple().IsAarch64BeOrLe()) {
556                 align = static_cast<uint8>(log2(align));
557             }
558         }
559         return align;
560     }
561 
562     // Please keep order of the fields, avoid paddings.
563 private:
564     TyIdx tyIdx {0};
565     TyIdx inferredTyIdx {kInitTyIdx};
566     MIRStorageClass storageClass {kScInvalid};
567     MIRSymKind sKind {kStInvalid};
568     bool isTmp = false;
569     bool needForwDecl = false;  // addrof of this symbol used in initialization, NOT serialized
570     bool wpoFakeParam = false;  // fake symbol introduced in wpo phase for a parameter, NOT serialized
571     bool wpoFakeRet = false;    // fake symbol introduced in wpo phase for return value, NOT serialized
572     bool isDeleted = false;     // tell if it is deleted, NOT serialized
573     bool instrumented = false;  // a local ref pointer instrumented by RC opt, NOT serialized
574     bool isImported = false;
575     bool isImportedDecl = false;
576     bool isTmpUnused = false;             // when parse the mplt_inline file, mark all the new symbol as tmpunused
577     bool appearsInCode = false;           // only used for kStFunc
578     bool hasPotentialAssignment = false;  // for global static vars, init as false and will be set true
579                                           // if assigned by stmt or the address of itself is taken
580     StIdx stIdx {0, 0};
581     TypeAttrs typeAttrs;
582     GStrIdx nameStrIdx {0};
583     std::pair<bool, UStrIdx> weakrefAttr {false, 0};
584 
585 public:
586     UStrIdx asmAttr {0};      // if not 0, the string for the name in C's asm attribute
587     UStrIdx sectionAttr {0};  // if not 0, the string for the name in C's section attribute
588 private:
589     SymbolType value = {nullptr};
590     SrcPosition srcPosition;  // where the symbol is defined
591     // following cannot be assumed final even though they are declared final
592     static GStrIdx reflectClassNameIdx;
593     static GStrIdx reflectMethodNameIdx;
594     static GStrIdx reflectFieldNameIdx;
595     static uint32 lastPrintedLineNum;  // used during printing ascii output
596     static uint16 lastPrintedColumnNum;
597 };
598 
599 class MIRSymbolTable {
600 public:
MIRSymbolTable(const MapleAllocator & allocator)601     explicit MIRSymbolTable(const MapleAllocator &allocator)
602         : mAllocator(allocator), strIdxToStIdxMap(mAllocator.Adapter()), symbolTable({nullptr}, mAllocator.Adapter())
603     {
604     }
605 
606     ~MIRSymbolTable() = default;
607 
IsValidIdx(uint32 idx)608     bool IsValidIdx(uint32 idx) const
609     {
610         return idx < symbolTable.size();
611     }
612 
613     MIRSymbol *GetSymbolFromStIdx(uint32 idx, bool checkFirst = false) const
614     {
615         if (checkFirst && idx >= symbolTable.size()) {
616             return nullptr;
617         }
618         CHECK_FATAL(IsValidIdx(idx), "symbol table index out of range");
619         return symbolTable[idx];
620     }
621 
CreateSymbol(uint8 scopeID)622     MIRSymbol *CreateSymbol(uint8 scopeID)
623     {
624         auto *st = mAllocator.GetMemPool()->New<MIRSymbol>(symbolTable.size(), scopeID);
625         symbolTable.push_back(st);
626         return st;
627     }
628 
PushNullSymbol()629     void PushNullSymbol()
630     {
631         symbolTable.push_back(nullptr);
632     }
633 
634     // add sym from other symbol table, happens in inline
AddStOutside(MIRSymbol * sym)635     bool AddStOutside(MIRSymbol *sym)
636     {
637         if (sym == nullptr) {
638             return false;
639         }
640         sym->SetStIdx(StIdx(sym->GetScopeIdx(), symbolTable.size()));
641         symbolTable.push_back(sym);
642         return AddToStringSymbolMap(*sym);
643     }
644 
AddToStringSymbolMap(const MIRSymbol & st)645     bool AddToStringSymbolMap(const MIRSymbol &st)
646     {
647         GStrIdx strIdx = st.GetNameStrIdx();
648         if (strIdxToStIdxMap[strIdx].FullIdx() != 0) {
649             return false;
650         }
651         strIdxToStIdxMap[strIdx] = st.GetStIdx();
652         return true;
653     }
654 
GetStIdxFromStrIdx(GStrIdx idx)655     StIdx GetStIdxFromStrIdx(GStrIdx idx) const
656     {
657         auto it = strIdxToStIdxMap.find(idx);
658         return (it == strIdxToStIdxMap.end()) ? StIdx() : it->second;
659     }
660 
661     MIRSymbol *GetSymbolFromStrIdx(GStrIdx idx, bool checkFirst = false)
662     {
663         return GetSymbolFromStIdx(GetStIdxFromStrIdx(idx).Idx(), checkFirst);
664     }
665 
666 #ifdef ARK_LITECG_DEBUG
667     void Dump(bool isLocal, int32 indent = 0, bool printDeleted = false, MIRFlavor flavor = kFlavorUnknown) const;
668 #endif
669 
GetSymbolTableSize()670     size_t GetSymbolTableSize() const
671     {
672         return symbolTable.size();
673     }
674 
GetTable()675     MapleVector<MIRSymbol *> &GetTable()
676     {
677         return symbolTable;
678     }
679 
GetTable()680     const MapleVector<MIRSymbol *> &GetTable() const
681     {
682         return symbolTable;
683     }
684 
GetSymbolAt(uint32 idx)685     const MIRSymbol *GetSymbolAt(uint32 idx) const
686     {
687         DEBUG_ASSERT(idx < symbolTable.size(), "symbol id out of table range");
688         return symbolTable[idx];
689     }
690 
GetSymbolAt(uint32 idx)691     MIRSymbol *GetSymbolAt(uint32 idx)
692     {
693         return const_cast<MIRSymbol *>(const_cast<const MIRSymbolTable *>(this)->GetSymbolAt(idx));
694     }
695 
Clear()696     void Clear()
697     {
698         symbolTable.clear();
699         strIdxToStIdxMap.clear();
700     }
701 
CloneLocalSymbol(const MIRSymbol & oldSym)702     MIRSymbol *CloneLocalSymbol(const MIRSymbol &oldSym) const
703     {
704         auto *memPool = mAllocator.GetMemPool();
705         auto *newSym = memPool->New<MIRSymbol>(oldSym);
706         if (oldSym.GetSKind() == kStConst) {
707             newSym->SetKonst(oldSym.GetKonst()->Clone(*memPool));
708         } else if (oldSym.GetSKind() == kStPreg) {
709             newSym->SetPreg(memPool->New<MIRPreg>(*oldSym.GetPreg()));
710         } else if (oldSym.GetSKind() == kStFunc) {
711             CHECK_FATAL(false, "%s has unexpected local func symbol", oldSym.GetName().c_str());
712         }
713         return newSym;
714     }
715 
716 private:
717     MapleAllocator mAllocator;
718     // hash table mapping string index to st index
719     MapleMap<GStrIdx, StIdx> strIdxToStIdxMap;
720     // map symbol idx to symbol node
721     MapleVector<MIRSymbol *> symbolTable;
722 };
723 
724 class MIRLabelTable {
725 public:
MIRLabelTable(MapleAllocator & allocator)726     explicit MIRLabelTable(MapleAllocator &allocator)
727         : addrTakenLabels(allocator.Adapter()),
728           caseLabelSet(allocator.Adapter()),
729           mAllocator(allocator),
730           strIdxToLabIdxMap(std::less<GStrIdx>(), mAllocator.Adapter()),
731           labelTable(mAllocator.Adapter())
732     {
733         labelTable.push_back(GStrIdx(kDummyLabel));  // push dummy label index 0
734     }
735 
736     ~MIRLabelTable() = default;
737 
CreateLabel()738     LabelIdx CreateLabel()
739     {
740         LabelIdx labelIdx = labelTable.size();
741         GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::to_string(labelIdx));
742         labelTable.push_back(strIdx);
743         return labelIdx;
744     }
745 
AddLabel(GStrIdx nameIdx)746     LabelIdx AddLabel(GStrIdx nameIdx)
747     {
748         LabelIdx labelIdx = labelTable.size();
749         labelTable.push_back(nameIdx);
750         strIdxToLabIdxMap[nameIdx] = labelIdx;
751         return labelIdx;
752     }
753 
GetLabelIdxFromStrIdx(GStrIdx idx)754     LabelIdx GetLabelIdxFromStrIdx(GStrIdx idx) const
755     {
756         auto it = strIdxToLabIdxMap.find(idx);
757         if (it == strIdxToLabIdxMap.end()) {
758             return LabelIdx();
759         }
760         return it->second;
761     }
762 
763     void AddToStringLabelMap(LabelIdx labelIdx);
GetLabelTableSize()764     size_t GetLabelTableSize() const
765     {
766         return labelTable.size();
767     }
768 
GetName(LabelIdx labelIdx)769     const std::string &GetName(LabelIdx labelIdx) const
770     {
771         CHECK_FATAL(labelIdx < labelTable.size(), "index out of range in MIRLabelTable::GetName");
772         return GlobalTables::GetStrTable().GetStringFromStrIdx(labelTable[labelIdx]);
773     }
774 
Size()775     size_t Size() const
776     {
777         return labelTable.size();
778     }
779 
GetDummyLabel()780     static uint32 GetDummyLabel()
781     {
782         return kDummyLabel;
783     }
784 
GetSymbolFromStIdx(LabelIdx idx)785     GStrIdx GetSymbolFromStIdx(LabelIdx idx) const
786     {
787         CHECK_FATAL(idx < labelTable.size(), "label table index out of range");
788         return labelTable[idx];
789     }
790 
SetSymbolFromStIdx(LabelIdx idx,GStrIdx strIdx)791     void SetSymbolFromStIdx(LabelIdx idx, GStrIdx strIdx)
792     {
793         CHECK_FATAL(idx < labelTable.size(), "label table index out of range");
794         labelTable[idx] = strIdx;
795     }
796 
GetLabelTable()797     MapleVector<GStrIdx> GetLabelTable()
798     {
799         return labelTable;
800     }
801 
GetAddrTakenLabels()802     const MapleUnorderedSet<LabelIdx> &GetAddrTakenLabels() const
803     {
804         return addrTakenLabels;
805     }
806 
GetAddrTakenLabels()807     MapleUnorderedSet<LabelIdx> &GetAddrTakenLabels()
808     {
809         return addrTakenLabels;
810     }
811 
GetStrIdxToLabelIdxMap()812     const MapleMap<GStrIdx, LabelIdx> &GetStrIdxToLabelIdxMap() const
813     {
814         return strIdxToLabIdxMap;
815     }
EraseStrIdxToLabelIdxElem(GStrIdx idx)816     void EraseStrIdxToLabelIdxElem(GStrIdx idx)
817     {
818         strIdxToLabIdxMap.erase(idx);
819     }
820 
821     MapleUnorderedSet<LabelIdx> addrTakenLabels;  // those appeared in MIRLblConst
822     MapleUnorderedSet<LabelIdx> caseLabelSet;     // labels marking starts of switch cases
823 
824 private:
825     static constexpr uint32 kDummyLabel = 0;
826     MapleAllocator mAllocator;
827     MapleMap<GStrIdx, LabelIdx> strIdxToLabIdxMap;
828     MapleVector<GStrIdx> labelTable;  // map label idx to label name
829 };
830 }  // namespace maple
831 #endif  // MAPLE_IR_INCLUDE_MIR_SYMBOL_H
832