[llvm-branch-commits] [lld] ELF: Add branch-to-branch optimization. (PR #138366)
Peter Collingbourne via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu May 22 21:31:50 PDT 2025
================
@@ -0,0 +1,92 @@
+//===- TargetImpl.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_ELF_ARCH_TARGETIMPL_H
+#define LLD_ELF_ARCH_TARGETIMPL_H
+
+#include "InputFiles.h"
+#include "InputSection.h"
+#include "Relocations.h"
+#include "Symbols.h"
+#include "llvm/BinaryFormat/ELF.h"
+
+namespace lld {
+namespace elf {
+
+// getControlTransferAddend: If this relocation is used for control transfer
+// instructions (e.g. branch, branch-link or call) or code references (e.g.
+// virtual function pointers) and indicates an address-insignificant reference,
+// return the effective addend for the relocation, otherwise return
+// std::nullopt. The effective addend for a relocation is the addend that is
+// used to determine its branch destination.
+//
+// getBranchInfo: If a control transfer relocation referring to is+offset
+// directly transfers control to a relocated branch instruction in the specified
+// section, return the relocation for the branch target as well as its effective
+// addend (see above). Otherwise return {nullptr, 0}.
+//
+// mergeControlTransferRelocations: Given r1, a relocation for which
+// getControlTransferAddend() returned a value, and r2, a relocation returned by
+// getBranchInfo(), modify r1 so that it branches directly to the target of r2.
+template <typename GetBranchInfo, typename GetControlTransferAddend,
+ typename MergeControlTransferRelocations>
+inline void applyBranchToBranchOptImpl(
+ Ctx &ctx, GetBranchInfo getBranchInfo,
+ GetControlTransferAddend getControlTransferAddend,
+ MergeControlTransferRelocations mergeControlTransferRelocations) {
+ // Needs to run serially because it writes to the relocations array as well as
+ // reading relocations of other sections.
+ for (ELFFileBase *f : ctx.objectFiles) {
+ auto getRelocBranchInfo =
+ [&getBranchInfo](Relocation &r,
+ uint64_t addend) -> std::pair<Relocation *, uint64_t> {
+ auto *target = dyn_cast_or_null<Defined>(r.sym);
+ // We don't allow preemptible symbols or ifuncs (may go somewhere else),
+ // absolute symbols (runtime behavior unknown), non-executable memory
+ // (ditto) or non-regular sections (no section data).
+ if (!target || target->isPreemptible || target->isGnuIFunc() ||
----------------
pcc wrote:
Shouldn't SHT_REL just work already because we read the implicit addend when producing the Relocation object?
I wanted to add a test case for this but it looks like llvm-mc doesn't have an option to write SHT_REL and instead SHT_REL is tested with yaml2obj hacks, e.g. `lld/test/ELF/aarch64-reloc-implicit-addend.test`. I think that test is already providing enough coverage of the SHT_REL path (otherwise we would need duplicate and difficult to maintain tests of every feature that processes Relocations).
https://github.com/llvm/llvm-project/pull/138366
More information about the llvm-branch-commits
mailing list