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