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