xref: /llvm-project-15.0.7/lld/ELF/ICF.cpp (revision fcef3e46)
1 //===- ICF.cpp ------------------------------------------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Identical Code Folding is a feature to merge sections not by name (which
11 // is regular comdat handling) but by contents. If two non-writable sections
12 // have the same data, relocations, attributes, etc., then the two
13 // are considered identical and merged by the linker. This optimization
14 // makes outputs smaller.
15 //
16 // ICF is theoretically a problem of reducing graphs by merging as many
17 // identical subgraphs as possible if we consider sections as vertices and
18 // relocations as edges. It may sound simple, but it is a bit more
19 // complicated than you might think. The order of processing sections
20 // matters because merging two sections can make other sections, whose
21 // relocations now point to the same section, mergeable. Graphs may contain
22 // cycles. We need a sophisticated algorithm to do this properly and
23 // efficiently.
24 //
25 // What we do in this file is this. We split sections into groups. Sections
26 // in the same group are considered identical.
27 //
28 // We begin by optimistically putting all sections into a single equivalence
29 // class. Then we apply a series of checks that split this initial
30 // equivalence class into more and more refined equivalence classes based on
31 // the properties by which a section can be distinguished.
32 //
33 // We begin by checking that the section contents and flags are the
34 // same. This only needs to be done once since these properties don't depend
35 // on the current equivalence class assignment.
36 //
37 // Then we split the equivalence classes based on checking that their
38 // relocations are the same, where relocation targets are compared by their
39 // equivalence class, not the concrete section. This may need to be done
40 // multiple times because as the equivalence classes are refined, two
41 // sections that had a relocation target in the same equivalence class may
42 // now target different equivalence classes, and hence these two sections
43 // must be put in different equivalence classes (whereas in the previous
44 // iteration they were not since the relocation target was the same.)
45 //
46 // Our algorithm is smart enough to merge the following mutually-recursive
47 // functions.
48 //
49 //   void foo() { bar(); }
50 //   void bar() { foo(); }
51 //
52 // This algorithm is so-called "optimistic" algorithm described in
53 // http://research.google.com/pubs/pub36912.html. (Note that what GNU
54 // gold implemented is different from the optimistic algorithm.)
55 //
56 //===----------------------------------------------------------------------===//
57 
58 #include "ICF.h"
59 #include "Config.h"
60 #include "OutputSections.h"
61 #include "SymbolTable.h"
62 
63 #include "llvm/ADT/Hashing.h"
64 #include "llvm/Object/ELF.h"
65 #include "llvm/Support/ELF.h"
66 #include "llvm/Support/raw_ostream.h"
67 
68 using namespace lld;
69 using namespace lld::elf;
70 using namespace llvm;
71 using namespace llvm::ELF;
72 using namespace llvm::object;
73 
74 namespace lld {
75 namespace elf {
76 template <class ELFT> class ICF {
77   typedef typename ELFT::Shdr Elf_Shdr;
78   typedef typename ELFT::Sym Elf_Sym;
79   typedef typename ELFT::uint uintX_t;
80   typedef Elf_Rel_Impl<ELFT, false> Elf_Rel;
81 
82   using Comparator = std::function<bool(const InputSection<ELFT> *,
83                                         const InputSection<ELFT> *)>;
84 
85 public:
86   void run(SymbolTable<ELFT> *Symtab);
87 
88 private:
89   uint64_t NextId = 1;
90 
91   static void setLive(SymbolTable<ELFT> *S);
92   static uint64_t relSize(InputSection<ELFT> *S);
93   static uint64_t getHash(InputSection<ELFT> *S);
94   static bool isEligible(InputSectionBase<ELFT> *Sec);
95   static std::vector<InputSection<ELFT> *> getSections(SymbolTable<ELFT> *S);
96   static SymbolBody &getSymbol(const InputSection<ELFT> *Sec,
97                                const Elf_Rel *Rel);
98 
99   void segregate(InputSection<ELFT> **Begin, InputSection<ELFT> **End,
100                  Comparator Eq);
101 
102   void forEachGroup(std::vector<InputSection<ELFT> *> &V, Comparator Eq);
103 
104   template <class RelTy>
105   static bool relocationEq(iterator_range<const RelTy *> RA,
106                            iterator_range<const RelTy *> RB);
107 
108   template <class RelTy>
109   static bool variableEq(const InputSection<ELFT> *A,
110                          const InputSection<ELFT> *B,
111                          iterator_range<const RelTy *> RA,
112                          iterator_range<const RelTy *> RB);
113 
114   static bool equalsConstant(const InputSection<ELFT> *A,
115                              const InputSection<ELFT> *B);
116 
117   static bool equalsVariable(const InputSection<ELFT> *A,
118                              const InputSection<ELFT> *B);
119 };
120 }
121 }
122 
123 // Returns a hash value for S. Note that the information about
124 // relocation targets is not included in the hash value.
125 template <class ELFT> uint64_t ICF<ELFT>::getHash(InputSection<ELFT> *S) {
126   uint64_t Flags = S->getSectionHdr()->sh_flags;
127   uint64_t H = hash_combine(Flags, S->getSize());
128   for (const Elf_Shdr *Rel : S->RelocSections)
129     H = hash_combine(H, (uint64_t)Rel->sh_size);
130   return H;
131 }
132 
133 // Returns true if Sec is subject of ICF.
134 template <class ELFT> bool ICF<ELFT>::isEligible(InputSectionBase<ELFT> *Sec) {
135   if (!Sec || Sec == InputSection<ELFT>::Discarded || !Sec->Live)
136     return false;
137   auto *S = dyn_cast<InputSection<ELFT>>(Sec);
138   if (!S)
139     return false;
140 
141   // .init and .fini contains instructions that must be executed to
142   // initialize and finalize the process. They cannot and should not
143   // be merged.
144   StringRef Name = S->getSectionName();
145   if (Name == ".init" || Name == ".fini")
146     return false;
147 
148   const Elf_Shdr &H = *S->getSectionHdr();
149   return (H.sh_flags & SHF_ALLOC) && (~H.sh_flags & SHF_WRITE);
150 }
151 
152 template <class ELFT>
153 std::vector<InputSection<ELFT> *>
154 ICF<ELFT>::getSections(SymbolTable<ELFT> *Symtab) {
155   std::vector<InputSection<ELFT> *> V;
156   for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab->getObjectFiles())
157     for (InputSectionBase<ELFT> *S : F->getSections())
158       if (isEligible(S))
159         V.push_back(cast<InputSection<ELFT>>(S));
160   return V;
161 }
162 
163 template <class ELFT>
164 SymbolBody &ICF<ELFT>::getSymbol(const InputSection<ELFT> *Sec,
165                                  const Elf_Rel *Rel) {
166   uint32_t SymIdx = Rel->getSymbol(Config->Mips64EL);
167   return Sec->File->getSymbolBody(SymIdx).repl();
168 }
169 
170 // All sections between Begin and End must have the same group ID before
171 // you call this function. This function compare sections between Begin
172 // and End using Eq and assign new group IDs for new groups.
173 template <class ELFT>
174 void ICF<ELFT>::segregate(InputSection<ELFT> **Begin, InputSection<ELFT> **End,
175                           Comparator Eq) {
176   // This loop rearranges [Begin, End) so that all sections that are
177   // equal in terms of Eq are contiguous. The algorithm is quadratic in
178   // the worst case, but that is not an issue in practice because the
179   // number of distinct sections in [Begin, End) is usually very small.
180   InputSection<ELFT> **I = Begin;
181   for (;;) {
182     InputSection<ELFT> *Head = *I;
183     auto Bound = std::stable_partition(
184         I + 1, End, [&](InputSection<ELFT> *S) { return Eq(Head, S); });
185     if (Bound == End)
186       return;
187     uint64_t Id = NextId++;
188     for (; I != Bound; ++I)
189       (*I)->GroupId = Id;
190   }
191 }
192 
193 template <class ELFT>
194 void ICF<ELFT>::forEachGroup(std::vector<InputSection<ELFT> *> &V,
195                              Comparator Eq) {
196   for (InputSection<ELFT> **I = V.data(), **E = I + V.size(); I != E;) {
197     InputSection<ELFT> *Head = *I;
198     auto Bound = std::find_if(I + 1, E, [&](InputSection<ELFT> *S) {
199       return S->GroupId != Head->GroupId;
200     });
201     segregate(I, Bound, Eq);
202     I = Bound;
203   }
204 }
205 
206 // Compare two lists of relocations.
207 template <class ELFT>
208 template <class RelTy>
209 bool ICF<ELFT>::relocationEq(iterator_range<const RelTy *> RelsA,
210                              iterator_range<const RelTy *> RelsB) {
211   const RelTy *IA = RelsA.begin();
212   const RelTy *EA = RelsA.end();
213   const RelTy *IB = RelsB.begin();
214   const RelTy *EB = RelsB.end();
215   if (EA - IA != EB - IB)
216     return false;
217   for (; IA != EA; ++IA, ++IB)
218     if (IA->r_offset != IB->r_offset ||
219         IA->getType(Config->Mips64EL) != IB->getType(Config->Mips64EL) ||
220         getAddend<ELFT>(*IA) != getAddend<ELFT>(*IB))
221       return false;
222   return true;
223 }
224 
225 // Compare "non-moving" part of two InputSections, namely everything
226 // except relocation targets.
227 template <class ELFT>
228 bool ICF<ELFT>::equalsConstant(const InputSection<ELFT> *A,
229                                const InputSection<ELFT> *B) {
230   if (A->RelocSections.size() != B->RelocSections.size())
231     return false;
232 
233   for (size_t I = 0, E = A->RelocSections.size(); I != E; ++I) {
234     const Elf_Shdr *RA = A->RelocSections[I];
235     const Elf_Shdr *RB = B->RelocSections[I];
236     ELFFile<ELFT> &FileA = A->File->getObj();
237     ELFFile<ELFT> &FileB = B->File->getObj();
238     if (RA->sh_type == SHT_RELA) {
239       if (!relocationEq(FileA.relas(RA), FileB.relas(RB)))
240         return false;
241     } else {
242       if (!relocationEq(FileA.rels(RA), FileB.rels(RB)))
243         return false;
244     }
245   }
246 
247   return A->getSectionHdr()->sh_flags == B->getSectionHdr()->sh_flags &&
248          A->getSize() == B->getSize() &&
249          A->getSectionData() == B->getSectionData();
250 }
251 
252 template <class ELFT>
253 template <class RelTy>
254 bool ICF<ELFT>::variableEq(const InputSection<ELFT> *A,
255                            const InputSection<ELFT> *B,
256                            iterator_range<const RelTy *> RelsA,
257                            iterator_range<const RelTy *> RelsB) {
258   const RelTy *IA = RelsA.begin();
259   const RelTy *EA = RelsA.end();
260   const RelTy *IB = RelsB.begin();
261   for (; IA != EA; ++IA, ++IB) {
262     SymbolBody &SA = getSymbol(A, (const Elf_Rel *)IA);
263     SymbolBody &SB = getSymbol(B, (const Elf_Rel *)IB);
264     if (&SA == &SB)
265       continue;
266 
267     // Or, the symbols should be pointing to the same section
268     // in terms of the group ID.
269     auto *DA = dyn_cast<DefinedRegular<ELFT>>(&SA);
270     auto *DB = dyn_cast<DefinedRegular<ELFT>>(&SB);
271     if (!DA || !DB)
272       return false;
273     if (DA->Sym.st_value != DB->Sym.st_value)
274       return false;
275     InputSection<ELFT> *X = dyn_cast<InputSection<ELFT>>(DA->Section);
276     InputSection<ELFT> *Y = dyn_cast<InputSection<ELFT>>(DB->Section);
277     if (X && Y && X->GroupId && X->GroupId == Y->GroupId)
278       continue;
279     return false;
280   }
281   return true;
282 }
283 
284 // Compare "moving" part of two InputSections, namely relocation targets.
285 template <class ELFT>
286 bool ICF<ELFT>::equalsVariable(const InputSection<ELFT> *A,
287                                const InputSection<ELFT> *B) {
288   for (size_t I = 0, E = A->RelocSections.size(); I != E; ++I) {
289     const Elf_Shdr *RA = A->RelocSections[I];
290     const Elf_Shdr *RB = B->RelocSections[I];
291     ELFFile<ELFT> &FileA = A->File->getObj();
292     ELFFile<ELFT> &FileB = B->File->getObj();
293     if (RA->sh_type == SHT_RELA) {
294       if (!variableEq(A, B, FileA.relas(RA), FileB.relas(RB)))
295         return false;
296     } else {
297       if (!variableEq(A, B, FileA.rels(RA), FileB.rels(RB)))
298         return false;
299     }
300   }
301   return true;
302 }
303 
304 // The main function of ICF.
305 template <class ELFT> void ICF<ELFT>::run(SymbolTable<ELFT> *Symtab) {
306   // Initially, we use hash values as section group IDs. Therefore,
307   // if two sections have the same ID, they are likely (but not
308   // guaranteed) to have the same static contents in terms of ICF.
309   std::vector<InputSection<ELFT> *> V = getSections(Symtab);
310   for (InputSection<ELFT> *S : V)
311     // Set MSB on to avoid collisions with serial group IDs
312     S->GroupId = getHash(S) | (uint64_t(1) << 63);
313 
314   // From now on, sections in V are ordered so that sections in
315   // the same group are consecutive in the vector.
316   std::stable_sort(V.begin(), V.end(),
317                    [](InputSection<ELFT> *A, InputSection<ELFT> *B) {
318                      return A->GroupId < B->GroupId;
319                    });
320 
321   // Compare static contents and assign unique IDs for each static content.
322   forEachGroup(V, equalsConstant);
323 
324   // Split groups by comparing relocations until we get a convergence.
325   int Cnt = 1;
326   for (;;) {
327     ++Cnt;
328     uint64_t Id = NextId;
329     forEachGroup(V, equalsVariable);
330     if (Id == NextId)
331       break;
332   }
333   log("ICF needed " + Twine(Cnt) + " iterations.");
334 
335   // Merge sections in the same group.
336   for (auto I = V.begin(), E = V.end(); I != E;) {
337     InputSection<ELFT> *Head = *I++;
338     auto Bound = std::find_if(I, E, [&](InputSection<ELFT> *S) {
339       return Head->GroupId != S->GroupId;
340     });
341     if (I == Bound)
342       continue;
343     log("selected " + Head->getSectionName());
344     while (I != Bound) {
345       InputSection<ELFT> *S = *I++;
346       log("  removed " + S->getSectionName());
347       Head->replace(S);
348     }
349   }
350 }
351 
352 // ICF entry point function.
353 template <class ELFT> void elf::doIcf(SymbolTable<ELFT> *Symtab) {
354   ICF<ELFT>().run(Symtab);
355 }
356 
357 template void elf::doIcf(SymbolTable<ELF32LE> *);
358 template void elf::doIcf(SymbolTable<ELF32BE> *);
359 template void elf::doIcf(SymbolTable<ELF64LE> *);
360 template void elf::doIcf(SymbolTable<ELF64BE> *);
361