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