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