|
44 | 44 | #include "llvm/MC/SectionKind.h"
|
45 | 45 | #include "llvm/Support/Casting.h"
|
46 | 46 | #include "llvm/Support/CommandLine.h"
|
| 47 | +#include "llvm/Support/EndianStream.h" |
47 | 48 | #include "llvm/Support/ErrorHandling.h"
|
48 | 49 | #include "llvm/Support/MemoryBuffer.h"
|
49 | 50 | #include "llvm/Support/Path.h"
|
@@ -547,16 +548,42 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
|
547 | 548 | if (GroupSym)
|
548 | 549 | Group = GroupSym->getName();
|
549 | 550 | assert(!(LinkedToSym && LinkedToSym->getName().empty()));
|
550 |
| - // Do the lookup, if we have a hit, return it. |
551 |
| - auto IterBool = ELFUniquingMap.insert(std::make_pair( |
552 |
| - ELFSectionKey{Section.str(), Group, |
553 |
| - LinkedToSym ? LinkedToSym->getName() : "", UniqueID}, |
554 |
| - nullptr)); |
555 |
| - auto &Entry = *IterBool.first; |
556 |
| - if (!IterBool.second) |
557 |
| - return Entry.second; |
558 | 551 |
|
559 |
| - StringRef CachedName = Entry.first.SectionName; |
| 552 | + // Sections are differentiated by the quadruple (section_name, group_name, |
| 553 | + // unique_id, link_to_symbol_name). Sections sharing the same quadruple are |
| 554 | + // combined into one section. As an optimization, non-unique sections without |
| 555 | + // group or linked-to symbol have a shorter unique-ing key. |
| 556 | + std::pair<StringMap<MCSectionELF *>::iterator, bool> EntryNewPair; |
| 557 | + // Length of the section name, which are the first SectionLen bytes of the key |
| 558 | + unsigned SectionLen; |
| 559 | + if (GroupSym || LinkedToSym || UniqueID != MCSection::NonUniqueID) { |
| 560 | + SmallString<128> Buffer; |
| 561 | + Section.toVector(Buffer); |
| 562 | + SectionLen = Buffer.size(); |
| 563 | + Buffer.push_back(0); // separator which cannot occur in the name |
| 564 | + if (GroupSym) |
| 565 | + Buffer.append(GroupSym->getName()); |
| 566 | + Buffer.push_back(0); // separator which cannot occur in the name |
| 567 | + if (LinkedToSym) |
| 568 | + Buffer.append(LinkedToSym->getName()); |
| 569 | + support::endian::write(Buffer, UniqueID, endianness::native); |
| 570 | + StringRef UniqueMapKey = StringRef(Buffer); |
| 571 | + EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr)); |
| 572 | + } else if (!Section.isSingleStringRef()) { |
| 573 | + SmallString<128> Buffer; |
| 574 | + StringRef UniqueMapKey = Section.toStringRef(Buffer); |
| 575 | + SectionLen = UniqueMapKey.size(); |
| 576 | + EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr)); |
| 577 | + } else { |
| 578 | + StringRef UniqueMapKey = Section.getSingleStringRef(); |
| 579 | + SectionLen = UniqueMapKey.size(); |
| 580 | + EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr)); |
| 581 | + } |
| 582 | + |
| 583 | + if (!EntryNewPair.second) |
| 584 | + return EntryNewPair.first->second; |
| 585 | + |
| 586 | + StringRef CachedName = EntryNewPair.first->getKey().take_front(SectionLen); |
560 | 587 |
|
561 | 588 | SectionKind Kind;
|
562 | 589 | if (Flags & ELF::SHF_ARM_PURECODE)
|
@@ -600,7 +627,7 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
|
600 | 627 | MCSectionELF *Result =
|
601 | 628 | createELFSectionImpl(CachedName, Type, Flags, Kind, EntrySize, GroupSym,
|
602 | 629 | IsComdat, UniqueID, LinkedToSym);
|
603 |
| - Entry.second = Result; |
| 630 | + EntryNewPair.first->second = Result; |
604 | 631 |
|
605 | 632 | recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(),
|
606 | 633 | Result->getUniqueID(), Result->getEntrySize());
|
|
0 commit comments