[lld] [lld][ELF] Extend profile guided function ordering to ELF binaries (PR #117514)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 29 22:53:20 PST 2024
================
@@ -0,0 +1,140 @@
+//===- BPSectionOrderer.h ---------------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// This file uses Balanced Partitioning to order sections to improve startup
+/// time and compressed size.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_ELF_BPSECTION_ORDERER_H
+#define LLD_ELF_BPSECTION_ORDERER_H
+
+#include "InputFiles.h"
+#include "InputSection.h"
+#include "Relocations.h"
+#include "Symbols.h"
+#include "lld/Common/SectionOrderer.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/xxhash.h"
+
+namespace lld::elf {
+
+class InputSection;
+
+class ELFSymbol : public BPSymbol {
+ const Symbol *sym;
+
+public:
+ explicit ELFSymbol(const Symbol *s) : sym(s) {}
+
+ llvm::StringRef getName() const override { return sym->getName(); }
+
+ BPSymbol *asDefinedSymbol() override {
+ if (auto *d = llvm::dyn_cast<Defined>(sym))
+ return this;
+ return nullptr;
+ }
+
+ uint64_t getValue() const override {
+ if (auto *d = llvm::dyn_cast<Defined>(sym))
+ return d->value;
+ return 0;
+ }
+
+ uint64_t getSize() const override {
+ if (auto *d = llvm::dyn_cast<Defined>(sym))
+ return d->size;
+ return 0;
+ }
+
+ InputSectionBase *getInputSection() const {
+ if (auto *d = llvm::dyn_cast<Defined>(sym))
+ return llvm::dyn_cast_or_null<InputSectionBase>(d->section);
+ return nullptr;
+ }
+
+ const Symbol *getSymbol() const { return sym; }
+};
+
+class ELFSection : public BPSectionBase {
+ const InputSectionBase *isec;
+ ELFSymbol *symbol;
+ std::vector<BPSymbol *> symbols;
+
+public:
+ explicit ELFSection(const InputSectionBase *sec, ELFSymbol *sym)
+ : isec(sec), symbol(sym), symbols({sym}) {}
+
+ const InputSectionBase *getSection() const { return isec; }
+
+ ELFSymbol *getSymbol() const { return symbol; }
+ llvm::StringRef getName() const override { return isec->name; }
+
+ uint64_t getSize() const override { return isec->getSize(); }
+
+ bool isCodeSection() const override {
+ return isec->flags & llvm::ELF::SHF_EXECINSTR;
+ }
+
+ bool hasValidData() const override {
+ return isec && !isec->content().empty();
+ }
+
+ llvm::ArrayRef<uint8_t> getSectionData() const override {
+ return isec->content();
+ }
+
+ llvm::ArrayRef<BPSymbol *> getSymbols() const override { return symbols; }
+
+ void getSectionHash(llvm::SmallVectorImpl<uint64_t> &hashes,
+ const llvm::DenseMap<const BPSectionBase *, uint64_t>
+ §ionToIdx) const override {
+ constexpr unsigned windowSize = 4;
+
+ // Convert BPSectionBase map to InputSection map
+ llvm::DenseMap<const InputSectionBase *, uint64_t> elfSectionToIdx;
+ for (const auto &[sec, idx] : sectionToIdx) {
+ if (auto *elfSec = llvm::dyn_cast<ELFSection>(sec))
+ elfSectionToIdx[elfSec->getSection()] = idx;
+ }
+
+ // Calculate content hashes
+ for (size_t i = 0; i < isec->content().size(); i++) {
----------------
MaskRay wrote:
https://llvm.org/docs/CodingStandards.html#don-t-evaluate-end-every-time-through-a-loop
I think many places in this patch violate this and should be fixed
https://github.com/llvm/llvm-project/pull/117514
More information about the llvm-commits
mailing list