//===- ICF.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
//
//===----------------------------------------------------------------------===//
//
// ICF is short for Identical Code Folding. This is a size optimization to
// identify and merge two or more read-only sections (typically functions)
// that happened to have the same contents. It usually reduces output size
// by a few percent.
//
// In ICF, two sections are considered identical if they have the same
// section flags, section data, and relocations. Relocations are tricky,
// because two relocations are considered the same if they have the same
// relocation types, values, and if they point to the same sections *in
// terms of ICF*.
//
// Here is an example. If foo and bar defined below are compiled to the
// same machine instructions, ICF can and should merge the two, although
// their relocations point to each other.
//
//   void foo() { bar(); }
//   void bar() { foo(); }
//
// If you merge the two, their relocations point to the same section and
// thus you know they are mergeable, but how do you know they are
// mergeable in the first place? This is not an easy problem to solve.
//
// What we are doing in LLD is to partition sections into equivalence
// classes. Sections in the same equivalence class when the algorithm
// terminates are considered identical. Here are details:
//
// 1. First, we partition sections using their hash values as keys. Hash
//    values contain section types, section contents and numbers of
//    relocations. During this step, relocation targets are not taken into
//    account. We just put sections that apparently differ into different
//    equivalence classes.
//
// 2. Next, for each equivalence class, we visit sections to compare
//    relocation targets. Relocation targets are considered equivalent if
//    their targets are in the same equivalence class. Sections with
//    different relocation targets are put into different equivalence
//    clases.
//
// 3. If we split an equivalence class in step 2, two relocations
//    previously target the same equivalence class may now target
//    different equivalence classes. Therefore, we repeat step 2 until a
//    convergence is obtained.
//
// 4. For each equivalence class C, pick an arbitrary section in C, and
//    merge all the other sections in C with it.
//
// For small programs, this algorithm needs 3-5 iterations. For large
// programs such as Chromium, it takes more than 20 iterations.
//
// This algorithm was mentioned as an "optimistic algorithm" in [1],
// though gold implements a different algorithm than this.
//
// We parallelize each step so that multiple threads can work on different
// equivalence classes concurrently. That gave us a large performance
// boost when applying ICF on large programs. For example, MSVC link.exe
// or GNU gold takes 10-20 seconds to apply ICF on Chromium, whose output
// size is about 1.5 GB, but LLD can finish it in less than 2 seconds on a
// 2.8 GHz 40 core machine. Even without threading, LLD's ICF is still
// faster than MSVC or gold though.
//
// [1] Safe ICF: Pointer Safe and Unwinding aware Identical Code Folding
// in the Gold Linker
// http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36912.pdf
//
//===----------------------------------------------------------------------===//

#include "ICF.h"
#include "Config.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Writer.h"
#include "lld/Common/Threads.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/xxhash.h"
#include <algorithm>
#include <atomic>

using namespace lld;
using namespace lld::elf;
using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;

namespace {
template <class ELFT> class ICF {
public:
  void run();

private:
  void segregate(size_t Begin, size_t End, bool Constant);

  template <class RelTy>
  bool constantEq(const InputSection *A, ArrayRef<RelTy> RelsA,
                  const InputSection *B, ArrayRef<RelTy> RelsB);

  template <class RelTy>
  bool variableEq(const InputSection *A, ArrayRef<RelTy> RelsA,
                  const InputSection *B, ArrayRef<RelTy> RelsB);

  bool equalsConstant(const InputSection *A, const InputSection *B);
  bool equalsVariable(const InputSection *A, const InputSection *B);

  size_t findBoundary(size_t Begin, size_t End);

  void forEachClassRange(size_t Begin, size_t End,
                         llvm::function_ref<void(size_t, size_t)> Fn);

  void forEachClass(llvm::function_ref<void(size_t, size_t)> Fn);

  std::vector<InputSection *> Sections;

  // We repeat the main loop while `Repeat` is true.
  std::atomic<bool> Repeat;

  // The main loop counter.
  int Cnt = 0;

  // We have two locations for equivalence classes. On the first iteration
  // of the main loop, Class[0] has a valid value, and Class[1] contains
  // garbage. We read equivalence classes from slot 0 and write to slot 1.
  // So, Class[0] represents the current class, and Class[1] represents
  // the next class. On each iteration, we switch their roles and use them
  // alternately.
  //
  // Why are we doing this? Recall that other threads may be working on
  // other equivalence classes in parallel. They may read sections that we
  // are updating. We cannot update equivalence classes in place because
  // it breaks the invariance that all possibly-identical sections must be
  // in the same equivalence class at any moment. In other words, the for
  // loop to update equivalence classes is not atomic, and that is
  // observable from other threads. By writing new classes to other
  // places, we can keep the invariance.
  //
  // Below, `Current` has the index of the current class, and `Next` has
  // the index of the next class. If threading is enabled, they are either
  // (0, 1) or (1, 0).
  //
  // Note on single-thread: if that's the case, they are always (0, 0)
  // because we can safely read the next class without worrying about race
  // conditions. Using the same location makes this algorithm converge
  // faster because it uses results of the same iteration earlier.
  int Current = 0;
  int Next = 0;
};
}

// Returns true if section S is subject of ICF.
static bool isEligible(InputSection *S) {
  if (!S->isLive() || S->KeepUnique || !(S->Flags & SHF_ALLOC))
    return false;

  // Don't merge writable sections. .data.rel.ro sections are marked as writable
  // but are semantically read-only.
  if ((S->Flags & SHF_WRITE) && S->Name != ".data.rel.ro" &&
      !S->Name.startswith(".data.rel.ro."))
    return false;

  // SHF_LINK_ORDER sections are ICF'd as a unit with their dependent sections,
  // so we don't consider them for ICF individually.
  if (S->Flags & SHF_LINK_ORDER)
    return false;

  // Don't merge synthetic sections as their Data member is not valid and empty.
  // The Data member needs to be valid for ICF as it is used by ICF to determine
  // the equality of section contents.
  if (isa<SyntheticSection>(S))
    return false;

  // .init and .fini contains instructions that must be executed to initialize
  // and finalize the process. They cannot and should not be merged.
  if (S->Name == ".init" || S->Name == ".fini")
    return false;

  // A user program may enumerate sections named with a C identifier using
  // __start_* and __stop_* symbols. We cannot ICF any such sections because
  // that could change program semantics.
  if (isValidCIdentifier(S->Name))
    return false;

  return true;
}

// Split an equivalence class into smaller classes.
template <class ELFT>
void ICF<ELFT>::segregate(size_t Begin, size_t End, bool Constant) {
  // This loop rearranges sections in [Begin, End) so that all sections
  // that are equal in terms of equals{Constant,Variable} are contiguous
  // in [Begin, End).
  //
  // The algorithm is quadratic in the worst case, but that is not an
  // issue in practice because the number of the distinct sections in
  // each range is usually very small.

  while (Begin < End) {
    // Divide [Begin, End) into two. Let Mid be the start index of the
    // second group.
    auto Bound =
        std::stable_partition(Sections.begin() + Begin + 1,
                              Sections.begin() + End, [&](InputSection *S) {
                                if (Constant)
                                  return equalsConstant(Sections[Begin], S);
                                return equalsVariable(Sections[Begin], S);
                              });
    size_t Mid = Bound - Sections.begin();

    // Now we split [Begin, End) into [Begin, Mid) and [Mid, End) by
    // updating the sections in [Begin, Mid). We use Mid as an equivalence
    // class ID because every group ends with a unique index.
    for (size_t I = Begin; I < Mid; ++I)
      Sections[I]->Class[Next] = Mid;

    // If we created a group, we need to iterate the main loop again.
    if (Mid != End)
      Repeat = true;

    Begin = Mid;
  }
}

// Compare two lists of relocations.
template <class ELFT>
template <class RelTy>
bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA,
                           const InputSection *SecB, ArrayRef<RelTy> RB) {
  for (size_t I = 0; I < RA.size(); ++I) {
    if (RA[I].r_offset != RB[I].r_offset ||
        RA[I].getType(Config->IsMips64EL) != RB[I].getType(Config->IsMips64EL))
      return false;

    uint64_t AddA = getAddend<ELFT>(RA[I]);
    uint64_t AddB = getAddend<ELFT>(RB[I]);

    Symbol &SA = SecA->template getFile<ELFT>()->getRelocTargetSym(RA[I]);
    Symbol &SB = SecB->template getFile<ELFT>()->getRelocTargetSym(RB[I]);
    if (&SA == &SB) {
      if (AddA == AddB)
        continue;
      return false;
    }

    auto *DA = dyn_cast<Defined>(&SA);
    auto *DB = dyn_cast<Defined>(&SB);

    // Placeholder symbols generated by linker scripts look the same now but
    // may have different values later.
    if (!DA || !DB || DA->ScriptDefined || DB->ScriptDefined)
      return false;

    // Relocations referring to absolute symbols are constant-equal if their
    // values are equal.
    if (!DA->Section && !DB->Section && DA->Value + AddA == DB->Value + AddB)
      continue;
    if (!DA->Section || !DB->Section)
      return false;

    if (DA->Section->kind() != DB->Section->kind())
      return false;

    // Relocations referring to InputSections are constant-equal if their
    // section offsets are equal.
    if (isa<InputSection>(DA->Section)) {
      if (DA->Value + AddA == DB->Value + AddB)
        continue;
      return false;
    }

    // Relocations referring to MergeInputSections are constant-equal if their
    // offsets in the output section are equal.
    auto *X = dyn_cast<MergeInputSection>(DA->Section);
    if (!X)
      return false;
    auto *Y = cast<MergeInputSection>(DB->Section);
    if (X->getParent() != Y->getParent())
      return false;

    uint64_t OffsetA =
        SA.isSection() ? X->getOffset(AddA) : X->getOffset(DA->Value) + AddA;
    uint64_t OffsetB =
        SB.isSection() ? Y->getOffset(AddB) : Y->getOffset(DB->Value) + AddB;
    if (OffsetA != OffsetB)
      return false;
  }

  return true;
}

// Compare "non-moving" part of two InputSections, namely everything
// except relocation targets.
template <class ELFT>
bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) {
  if (A->NumRelocations != B->NumRelocations || A->Flags != B->Flags ||
      A->getSize() != B->getSize() || A->data() != B->data())
    return false;

  // If two sections have different output sections, we cannot merge them.
  // FIXME: This doesn't do the right thing in the case where there is a linker
  // script. We probably need to move output section assignment before ICF to
  // get the correct behaviour here.
  if (getOutputSectionName(A) != getOutputSectionName(B))
    return false;

  if (A->AreRelocsRela)
    return constantEq(A, A->template relas<ELFT>(), B,
                      B->template relas<ELFT>());
  return constantEq(A, A->template rels<ELFT>(), B, B->template rels<ELFT>());
}

// Compare two lists of relocations. Returns true if all pairs of
// relocations point to the same section in terms of ICF.
template <class ELFT>
template <class RelTy>
bool ICF<ELFT>::variableEq(const InputSection *SecA, ArrayRef<RelTy> RA,
                           const InputSection *SecB, ArrayRef<RelTy> RB) {
  assert(RA.size() == RB.size());

  for (size_t I = 0; I < RA.size(); ++I) {
    // The two sections must be identical.
    Symbol &SA = SecA->template getFile<ELFT>()->getRelocTargetSym(RA[I]);
    Symbol &SB = SecB->template getFile<ELFT>()->getRelocTargetSym(RB[I]);
    if (&SA == &SB)
      continue;

    auto *DA = cast<Defined>(&SA);
    auto *DB = cast<Defined>(&SB);

    // We already dealt with absolute and non-InputSection symbols in
    // constantEq, and for InputSections we have already checked everything
    // except the equivalence class.
    if (!DA->Section)
      continue;
    auto *X = dyn_cast<InputSection>(DA->Section);
    if (!X)
      continue;
    auto *Y = cast<InputSection>(DB->Section);

    // Ineligible sections are in the special equivalence class 0.
    // They can never be the same in terms of the equivalence class.
    if (X->Class[Current] == 0)
      return false;
    if (X->Class[Current] != Y->Class[Current])
      return false;
  };

  return true;
}

// Compare "moving" part of two InputSections, namely relocation targets.
template <class ELFT>
bool ICF<ELFT>::equalsVariable(const InputSection *A, const InputSection *B) {
  if (A->AreRelocsRela)
    return variableEq(A, A->template relas<ELFT>(), B,
                      B->template relas<ELFT>());
  return variableEq(A, A->template rels<ELFT>(), B, B->template rels<ELFT>());
}

template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t Begin, size_t End) {
  uint32_t Class = Sections[Begin]->Class[Current];
  for (size_t I = Begin + 1; I < End; ++I)
    if (Class != Sections[I]->Class[Current])
      return I;
  return End;
}

// Sections in the same equivalence class are contiguous in Sections
// vector. Therefore, Sections vector can be considered as contiguous
// groups of sections, grouped by the class.
//
// This function calls Fn on every group within [Begin, End).
template <class ELFT>
void ICF<ELFT>::forEachClassRange(size_t Begin, size_t End,
                                  llvm::function_ref<void(size_t, size_t)> Fn) {
  while (Begin < End) {
    size_t Mid = findBoundary(Begin, End);
    Fn(Begin, Mid);
    Begin = Mid;
  }
}

// Call Fn on each equivalence class.
template <class ELFT>
void ICF<ELFT>::forEachClass(llvm::function_ref<void(size_t, size_t)> Fn) {
  // If threading is disabled or the number of sections are
  // too small to use threading, call Fn sequentially.
  if (!ThreadsEnabled || Sections.size() < 1024) {
    forEachClassRange(0, Sections.size(), Fn);
    ++Cnt;
    return;
  }

  Current = Cnt % 2;
  Next = (Cnt + 1) % 2;

  // Shard into non-overlapping intervals, and call Fn in parallel.
  // The sharding must be completed before any calls to Fn are made
  // so that Fn can modify the Chunks in its shard without causing data
  // races.
  const size_t NumShards = 256;
  size_t Step = Sections.size() / NumShards;
  size_t Boundaries[NumShards + 1];
  Boundaries[0] = 0;
  Boundaries[NumShards] = Sections.size();

  parallelForEachN(1, NumShards, [&](size_t I) {
    Boundaries[I] = findBoundary((I - 1) * Step, Sections.size());
  });

  parallelForEachN(1, NumShards + 1, [&](size_t I) {
    if (Boundaries[I - 1] < Boundaries[I])
      forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn);
  });
  ++Cnt;
}

// Combine the hashes of the sections referenced by the given section into its
// hash.
template <class ELFT, class RelTy>
static void combineRelocHashes(unsigned Cnt, InputSection *IS,
                               ArrayRef<RelTy> Rels) {
  uint32_t Hash = IS->Class[Cnt % 2];
  for (RelTy Rel : Rels) {
    Symbol &S = IS->template getFile<ELFT>()->getRelocTargetSym(Rel);
    if (auto *D = dyn_cast<Defined>(&S))
      if (auto *RelSec = dyn_cast_or_null<InputSection>(D->Section))
        Hash += RelSec->Class[Cnt % 2];
  }
  // Set MSB to 1 to avoid collisions with non-hash IDs.
  IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
}

static void print(const Twine &S) {
  if (Config->PrintIcfSections)
    message(S);
}

// The main function of ICF.
template <class ELFT> void ICF<ELFT>::run() {
  // Collect sections to merge.
  for (InputSectionBase *Sec : InputSections)
    if (auto *S = dyn_cast<InputSection>(Sec))
      if (isEligible(S))
        Sections.push_back(S);

  // Initially, we use hash values to partition sections.
  parallelForEach(Sections, [&](InputSection *S) {
    S->Class[0] = xxHash64(S->data());
  });

  for (unsigned Cnt = 0; Cnt != 2; ++Cnt) {
    parallelForEach(Sections, [&](InputSection *S) {
      if (S->AreRelocsRela)
        combineRelocHashes<ELFT>(Cnt, S, S->template relas<ELFT>());
      else
        combineRelocHashes<ELFT>(Cnt, S, S->template rels<ELFT>());
    });
  }

  // From now on, sections in Sections vector are ordered so that sections
  // in the same equivalence class are consecutive in the vector.
  llvm::stable_sort(Sections, [](const InputSection *A, const InputSection *B) {
    return A->Class[0] < B->Class[0];
  });

  // Compare static contents and assign unique IDs for each static content.
  forEachClass([&](size_t Begin, size_t End) { segregate(Begin, End, true); });

  // Split groups by comparing relocations until convergence is obtained.
  do {
    Repeat = false;
    forEachClass(
        [&](size_t Begin, size_t End) { segregate(Begin, End, false); });
  } while (Repeat);

  log("ICF needed " + Twine(Cnt) + " iterations");

  // Merge sections by the equivalence class.
  forEachClassRange(0, Sections.size(), [&](size_t Begin, size_t End) {
    if (End - Begin == 1)
      return;
    print("selected section " + toString(Sections[Begin]));
    for (size_t I = Begin + 1; I < End; ++I) {
      print("  removing identical section " + toString(Sections[I]));
      Sections[Begin]->replace(Sections[I]);

      // At this point we know sections merged are fully identical and hence
      // we want to remove duplicate implicit dependencies such as link order
      // and relocation sections.
      for (InputSection *IS : Sections[I]->DependentSections)
        IS->markDead();
    }
  });
}

// ICF entry point function.
template <class ELFT> void elf::doIcf() { ICF<ELFT>().run(); }

template void elf::doIcf<ELF32LE>();
template void elf::doIcf<ELF32BE>();
template void elf::doIcf<ELF64LE>();
template void elf::doIcf<ELF64BE>();
