1- // ===- BPSectionOrderer.cpp- -----------------------------------------------===//
1+ // ===- BPSectionOrderer.cpp -----------------------------------------------===//
22//
33// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44// See https://llvm.org/LICENSE.txt for license information.
77// ===----------------------------------------------------------------------===//
88
99#include " BPSectionOrderer.h"
10+ #include " InputFiles.h"
11+ #include " InputSection.h"
12+ #include " SymbolTable.h"
13+ #include " Symbols.h"
14+ #include " lld/Common/BPSectionOrdererBase.inc"
15+ #include " llvm/Support/Endian.h"
16+
17+ #define DEBUG_TYPE " bp-section-orderer"
1018
1119using namespace llvm ;
1220using namespace lld ::elf;
1321
14- void BPSectionELF::getSectionHashes (
15- llvm::SmallVectorImpl<uint64_t > &hashes,
16- const llvm::DenseMap<const void *, uint64_t > §ionToIdx) const {
17- constexpr unsigned windowSize = 4 ;
22+ namespace {
23+ struct BPOrdererELF ;
24+ }
25+ template <> struct lld ::BPOrdererTraits<struct BPOrdererELF > {
26+ using Section = elf::InputSectionBase;
27+ using Symbol = elf::Symbol;
28+ };
29+ namespace {
30+ struct BPOrdererELF : lld::BPOrderer<BPOrdererELF> {
31+ static uint64_t getSize (const Section &sec) { return sec.getSize (); }
32+ static bool isCodeSection (const Section &sec) {
33+ return sec.flags & llvm::ELF::SHF_EXECINSTR;
34+ }
35+ static SmallVector<Symbol *, 0 > getSymbols (const Section &sec) {
36+ SmallVector<Symbol *, 0 > symbols;
37+ for (auto *sym : sec.file ->getSymbols ())
38+ if (auto *d = llvm::dyn_cast_or_null<Defined>(sym))
39+ if (d->size > 0 && d->section == &sec)
40+ symbols.emplace_back (d);
41+ return symbols;
42+ }
43+
44+ std::optional<StringRef> static getResolvedLinkageName (llvm::StringRef name) {
45+ return name;
46+ }
47+
48+ static void
49+ getSectionHashes (const Section &sec, llvm::SmallVectorImpl<uint64_t > &hashes,
50+ const llvm::DenseMap<const void *, uint64_t > §ionToIdx) {
51+ constexpr unsigned windowSize = 4 ;
1852
19- // Calculate content hashes: k-mers and the last k-1 bytes.
20- ArrayRef<uint8_t > data = isec-> content ();
21- if (data.size () >= windowSize)
22- for (size_t i = 0 ; i <= data.size () - windowSize; ++i)
23- hashes.push_back (llvm::support::endian::read32le (data.data () + i));
24- for (uint8_t byte : data.take_back (windowSize - 1 ))
25- hashes.push_back (byte);
53+ // Calculate content hashes: k-mers and the last k-1 bytes.
54+ ArrayRef<uint8_t > data = sec. content ();
55+ if (data.size () >= windowSize)
56+ for (size_t i = 0 ; i <= data.size () - windowSize; ++i)
57+ hashes.push_back (llvm::support::endian::read32le (data.data () + i));
58+ for (uint8_t byte : data.take_back (windowSize - 1 ))
59+ hashes.push_back (byte);
2660
27- llvm::sort (hashes);
28- hashes.erase (std::unique (hashes.begin (), hashes.end ()), hashes.end ());
29- }
61+ llvm::sort (hashes);
62+ hashes.erase (std::unique (hashes.begin (), hashes.end ()), hashes.end ());
63+ }
64+
65+ static llvm::StringRef getSymName (const Symbol &sym) { return sym.getName (); }
66+ static uint64_t getSymValue (const Symbol &sym) {
67+ if (auto *d = dyn_cast<Defined>(&sym))
68+ return d->value ;
69+ return 0 ;
70+ }
71+ static uint64_t getSymSize (const Symbol &sym) {
72+ if (auto *d = dyn_cast<Defined>(&sym))
73+ return d->size ;
74+ return 0 ;
75+ }
76+ };
77+ } // namespace
3078
31- llvm::DenseMap<const lld::elf::InputSectionBase *, int >
32- lld::elf::runBalancedPartitioning (Ctx &ctx, llvm::StringRef profilePath,
33- bool forFunctionCompression,
34- bool forDataCompression,
35- bool compressionSortStartupFunctions,
36- bool verbose) {
37- // Collect sections from symbols and wrap as BPSectionELF instances.
38- // Deduplicates sections referenced by multiple symbols.
39- SmallVector<std::unique_ptr<BPSectionBase>> sections;
79+ DenseMap<const InputSectionBase *, int > lld::elf::runBalancedPartitioning (
80+ Ctx &ctx, StringRef profilePath, bool forFunctionCompression,
81+ bool forDataCompression, bool compressionSortStartupFunctions,
82+ bool verbose) {
83+ // Collect candidate sections and associated symbols.
84+ SmallVector<InputSectionBase *> sections;
85+ DenseMap<CachedHashStringRef, DenseSet<unsigned >> rootSymbolToSectionIdxs;
4086 DenseSet<const InputSectionBase *> seenSections;
4187
4288 auto addSection = [&](Symbol &sym) {
4389 if (sym.getSize () == 0 )
4490 return ;
4591 if (auto *d = dyn_cast<Defined>(&sym))
4692 if (auto *sec = dyn_cast_or_null<InputSectionBase>(d->section ))
47- if (seenSections.insert (sec).second )
48- sections.emplace_back (std::make_unique<BPSectionELF>(sec));
93+ if (seenSections.insert (sec).second ) {
94+ size_t idx = sections.size ();
95+ sections.emplace_back (sec);
96+ auto rootName = getRootSymbol (sym.getName ());
97+ rootSymbolToSectionIdxs[CachedHashStringRef (rootName)].insert (idx);
98+ if (auto linkageName = BPOrdererELF::getResolvedLinkageName (rootName))
99+ rootSymbolToSectionIdxs[CachedHashStringRef (*linkageName)].insert (
100+ idx);
101+ }
49102 };
50103
51104 for (Symbol *sym : ctx.symtab ->getSymbols ())
@@ -55,16 +108,8 @@ lld::elf::runBalancedPartitioning(Ctx &ctx, llvm::StringRef profilePath,
55108 for (Symbol *sym : file->getLocalSymbols ())
56109 addSection (*sym);
57110
58- auto reorderedSections = BPSectionBase::reorderSectionsByBalancedPartitioning (
59- profilePath, forFunctionCompression, forDataCompression,
60- compressionSortStartupFunctions, verbose, sections);
61-
62- DenseMap<const InputSectionBase *, int > result;
63- for (const auto [sec, priority] : reorderedSections) {
64- auto *elfSection = cast<BPSectionELF>(sec);
65- result.try_emplace (
66- static_cast <const InputSectionBase *>(elfSection->getSection ()),
67- static_cast <int >(priority));
68- }
69- return result;
111+ return BPOrdererELF::computeOrder (profilePath, forFunctionCompression,
112+ forDataCompression,
113+ compressionSortStartupFunctions, verbose,
114+ sections, rootSymbolToSectionIdxs);
70115}
0 commit comments