//===- 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. That 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. // // On Windows, ICF is enabled by default. // // See ELF/ICF.cpp for the details about the algorithm. // //===----------------------------------------------------------------------===// #include "ICF.h" #include "COFFLinkerContext.h" #include "Chunks.h" #include "Symbols.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Timer.h" #include "llvm/ADT/Hashing.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Parallel.h" #include "llvm/Support/TimeProfiler.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/xxhash.h" #include <algorithm> #include <atomic> #include <vector> usingnamespacellvm; namespace lld::coff { class ICF { … }; // Returns true if section S is subject of ICF. // // Microsoft's documentation // (https://msdn.microsoft.com/en-us/library/bxwfs976.aspx; visited April // 2017) says that /opt:icf folds both functions and read-only data. // Despite that, the MSVC linker folds only functions. We found // a few instances of programs that are not safe for data merging. // Therefore, we merge only functions just like the MSVC tool. However, we also // merge read-only sections in a couple of cases where the address of the // section is insignificant to the user program and the behaviour matches that // of the Visual C++ linker. bool ICF::isEligible(SectionChunk *c) { … } // Split an equivalence class into smaller classes. void ICF::segregate(size_t begin, size_t end, bool constant) { … } // Returns true if two sections' associative children are equal. bool ICF::assocEquals(const SectionChunk *a, const SectionChunk *b) { … } // Compare "non-moving" part of two sections, namely everything // except relocation targets. bool ICF::equalsConstant(const SectionChunk *a, const SectionChunk *b) { … } // Compare "moving" part of two sections, namely relocation targets. bool ICF::equalsVariable(const SectionChunk *a, const SectionChunk *b) { … } // Find the first Chunk after Begin that has a different class from Begin. size_t ICF::findBoundary(size_t begin, size_t end) { … } void ICF::forEachClassRange(size_t begin, size_t end, std::function<void(size_t, size_t)> fn) { … } // Call Fn on each class group. void ICF::forEachClass(std::function<void(size_t, size_t)> fn) { … } // Merge identical COMDAT sections. // Two sections are considered the same if their section headers, // contents and relocations are all the same. void ICF::run() { … } // Entry point to ICF. void doICF(COFFLinkerContext &ctx) { … } } // namespace lld::coff