diff options
author | mingmingl <mingmingl@google.com> | 2025-02-04 11:11:14 -0800 |
---|---|---|
committer | mingmingl <mingmingl@google.com> | 2025-02-04 11:11:14 -0800 |
commit | e91747a92d27ecf799427bf563f9f64f7c4d2447 (patch) | |
tree | 7aa5a8a9170deec293e152bdf2be804399dcd612 /lld/ELF/BPSectionOrderer.cpp | |
parent | 3a8d9337d816aef41c3ca1484be8b933a71a3c46 (diff) | |
parent | 53d6e59b594639417cdbfcfa2d18cea64acb4009 (diff) | |
download | llvm-users/mingmingl-llvm/spr/sdpglobalvariable.zip llvm-users/mingmingl-llvm/spr/sdpglobalvariable.tar.gz llvm-users/mingmingl-llvm/spr/sdpglobalvariable.tar.bz2 |
Merge branch 'main' into users/mingmingl-llvm/spr/sdpglobalvariableusers/mingmingl-llvm/spr/sdpglobalvariable
Diffstat (limited to 'lld/ELF/BPSectionOrderer.cpp')
-rw-r--r-- | lld/ELF/BPSectionOrderer.cpp | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/lld/ELF/BPSectionOrderer.cpp b/lld/ELF/BPSectionOrderer.cpp new file mode 100644 index 0000000..01f77b3 --- /dev/null +++ b/lld/ELF/BPSectionOrderer.cpp @@ -0,0 +1,95 @@ +//===- BPSectionOrderer.cpp -----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "BPSectionOrderer.h" +#include "InputFiles.h" +#include "InputSection.h" +#include "SymbolTable.h" +#include "Symbols.h" +#include "lld/Common/BPSectionOrdererBase.inc" +#include "llvm/Support/Endian.h" + +using namespace llvm; +using namespace lld::elf; + +namespace { +struct BPOrdererELF; +} +template <> struct lld::BPOrdererTraits<struct BPOrdererELF> { + using Section = elf::InputSectionBase; + using Defined = elf::Defined; +}; +namespace { +struct BPOrdererELF : lld::BPOrderer<BPOrdererELF> { + DenseMap<const InputSectionBase *, Defined *> secToSym; + + static uint64_t getSize(const Section &sec) { return sec.getSize(); } + static bool isCodeSection(const Section &sec) { + return sec.flags & ELF::SHF_EXECINSTR; + } + ArrayRef<Defined *> getSymbols(const Section &sec) { + auto it = secToSym.find(&sec); + if (it == secToSym.end()) + return {}; + return ArrayRef(it->second); + } + + static void + getSectionHashes(const Section &sec, SmallVectorImpl<uint64_t> &hashes, + const DenseMap<const void *, uint64_t> §ionToIdx) { + constexpr unsigned windowSize = 4; + + // Calculate content hashes: k-mers and the last k-1 bytes. + ArrayRef<uint8_t> data = sec.content(); + if (data.size() >= windowSize) + for (size_t i = 0; i <= data.size() - windowSize; ++i) + hashes.push_back(support::endian::read32le(data.data() + i)); + for (uint8_t byte : data.take_back(windowSize - 1)) + hashes.push_back(byte); + + llvm::sort(hashes); + hashes.erase(std::unique(hashes.begin(), hashes.end()), hashes.end()); + } + + static StringRef getSymName(const Defined &sym) { return sym.getName(); } + static uint64_t getSymValue(const Defined &sym) { return sym.value; } + static uint64_t getSymSize(const Defined &sym) { return sym.size; } +}; +} // namespace + +DenseMap<const InputSectionBase *, int> elf::runBalancedPartitioning( + Ctx &ctx, StringRef profilePath, bool forFunctionCompression, + bool forDataCompression, bool compressionSortStartupFunctions, + bool verbose) { + // Collect candidate sections and associated symbols. + SmallVector<InputSectionBase *> sections; + DenseMap<CachedHashStringRef, std::set<unsigned>> rootSymbolToSectionIdxs; + BPOrdererELF orderer; + + auto addSection = [&](Symbol &sym) { + auto *d = dyn_cast<Defined>(&sym); + if (!d) + return; + auto *sec = dyn_cast_or_null<InputSectionBase>(d->section); + if (!sec || sec->size == 0 || !orderer.secToSym.try_emplace(sec, d).second) + return; + rootSymbolToSectionIdxs[CachedHashStringRef(getRootSymbol(sym.getName()))] + .insert(sections.size()); + sections.emplace_back(sec); + }; + + for (Symbol *sym : ctx.symtab->getSymbols()) + addSection(*sym); + for (ELFFileBase *file : ctx.objectFiles) + for (Symbol *sym : file->getLocalSymbols()) + addSection(*sym); + return orderer.computeOrder(profilePath, forFunctionCompression, + forDataCompression, + compressionSortStartupFunctions, verbose, + sections, rootSymbolToSectionIdxs); +} |