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(); 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(); 96 97 void segregate(InputSection<ELFT> **Begin, InputSection<ELFT> **End, 98 Comparator Eq); 99 100 void forEachGroup(std::vector<InputSection<ELFT> *> &V, Comparator Eq); 101 102 template <class RelTy> 103 static bool relocationEq(ArrayRef<RelTy> RA, ArrayRef<RelTy> RB); 104 105 template <class RelTy> 106 static bool variableEq(const InputSection<ELFT> *A, 107 const InputSection<ELFT> *B, ArrayRef<RelTy> RA, 108 ArrayRef<RelTy> RB); 109 110 static bool equalsConstant(const InputSection<ELFT> *A, 111 const InputSection<ELFT> *B); 112 113 static bool equalsVariable(const InputSection<ELFT> *A, 114 const InputSection<ELFT> *B); 115 }; 116 } 117 } 118 119 // Returns a hash value for S. Note that the information about 120 // relocation targets is not included in the hash value. 121 template <class ELFT> uint64_t ICF<ELFT>::getHash(InputSection<ELFT> *S) { 122 uint64_t Flags = S->getSectionHdr()->sh_flags; 123 uint64_t H = hash_combine(Flags, S->getSize()); 124 for (const Elf_Shdr *Rel : S->RelocSections) 125 H = hash_combine(H, (uint64_t)Rel->sh_size); 126 return H; 127 } 128 129 // Returns true if Sec is subject of ICF. 130 template <class ELFT> bool ICF<ELFT>::isEligible(InputSectionBase<ELFT> *Sec) { 131 if (!Sec || Sec == &InputSection<ELFT>::Discarded || !Sec->Live) 132 return false; 133 auto *S = dyn_cast<InputSection<ELFT>>(Sec); 134 if (!S) 135 return false; 136 137 // .init and .fini contains instructions that must be executed to 138 // initialize and finalize the process. They cannot and should not 139 // be merged. 140 StringRef Name = S->Name; 141 if (Name == ".init" || Name == ".fini") 142 return false; 143 144 const Elf_Shdr &H = *S->getSectionHdr(); 145 return (H.sh_flags & SHF_ALLOC) && (~H.sh_flags & SHF_WRITE); 146 } 147 148 template <class ELFT> 149 std::vector<InputSection<ELFT> *> ICF<ELFT>::getSections() { 150 std::vector<InputSection<ELFT> *> V; 151 for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) 152 for (InputSectionBase<ELFT> *S : F->getSections()) 153 if (isEligible(S)) 154 V.push_back(cast<InputSection<ELFT>>(S)); 155 return V; 156 } 157 158 // All sections between Begin and End must have the same group ID before 159 // you call this function. This function compare sections between Begin 160 // and End using Eq and assign new group IDs for new groups. 161 template <class ELFT> 162 void ICF<ELFT>::segregate(InputSection<ELFT> **Begin, InputSection<ELFT> **End, 163 Comparator Eq) { 164 // This loop rearranges [Begin, End) so that all sections that are 165 // equal in terms of Eq are contiguous. The algorithm is quadratic in 166 // the worst case, but that is not an issue in practice because the 167 // number of distinct sections in [Begin, End) is usually very small. 168 InputSection<ELFT> **I = Begin; 169 for (;;) { 170 InputSection<ELFT> *Head = *I; 171 auto Bound = std::stable_partition( 172 I + 1, End, [&](InputSection<ELFT> *S) { return Eq(Head, S); }); 173 if (Bound == End) 174 return; 175 uint64_t Id = NextId++; 176 for (; I != Bound; ++I) 177 (*I)->GroupId = Id; 178 } 179 } 180 181 template <class ELFT> 182 void ICF<ELFT>::forEachGroup(std::vector<InputSection<ELFT> *> &V, 183 Comparator Eq) { 184 for (InputSection<ELFT> **I = V.data(), **E = I + V.size(); I != E;) { 185 InputSection<ELFT> *Head = *I; 186 auto Bound = std::find_if(I + 1, E, [&](InputSection<ELFT> *S) { 187 return S->GroupId != Head->GroupId; 188 }); 189 segregate(I, Bound, Eq); 190 I = Bound; 191 } 192 } 193 194 // Compare two lists of relocations. 195 template <class ELFT> 196 template <class RelTy> 197 bool ICF<ELFT>::relocationEq(ArrayRef<RelTy> RelsA, ArrayRef<RelTy> RelsB) { 198 const RelTy *IA = RelsA.begin(); 199 const RelTy *EA = RelsA.end(); 200 const RelTy *IB = RelsB.begin(); 201 const RelTy *EB = RelsB.end(); 202 if (EA - IA != EB - IB) 203 return false; 204 for (; IA != EA; ++IA, ++IB) 205 if (IA->r_offset != IB->r_offset || 206 IA->getType(Config->Mips64EL) != IB->getType(Config->Mips64EL) || 207 getAddend<ELFT>(*IA) != getAddend<ELFT>(*IB)) 208 return false; 209 return true; 210 } 211 212 // Compare "non-moving" part of two InputSections, namely everything 213 // except relocation targets. 214 template <class ELFT> 215 bool ICF<ELFT>::equalsConstant(const InputSection<ELFT> *A, 216 const InputSection<ELFT> *B) { 217 if (A->RelocSections.size() != B->RelocSections.size()) 218 return false; 219 220 for (size_t I = 0, E = A->RelocSections.size(); I != E; ++I) { 221 const Elf_Shdr *RA = A->RelocSections[I]; 222 const Elf_Shdr *RB = B->RelocSections[I]; 223 ELFFile<ELFT> &FileA = A->File->getObj(); 224 ELFFile<ELFT> &FileB = B->File->getObj(); 225 if (RA->sh_type == SHT_RELA) { 226 if (!relocationEq(FileA.relas(RA), FileB.relas(RB))) 227 return false; 228 } else { 229 if (!relocationEq(FileA.rels(RA), FileB.rels(RB))) 230 return false; 231 } 232 } 233 234 return A->getSectionHdr()->sh_flags == B->getSectionHdr()->sh_flags && 235 A->getSize() == B->getSize() && A->Data == B->Data; 236 } 237 238 template <class ELFT> 239 template <class RelTy> 240 bool ICF<ELFT>::variableEq(const InputSection<ELFT> *A, 241 const InputSection<ELFT> *B, ArrayRef<RelTy> RelsA, 242 ArrayRef<RelTy> RelsB) { 243 const RelTy *IA = RelsA.begin(); 244 const RelTy *EA = RelsA.end(); 245 const RelTy *IB = RelsB.begin(); 246 for (; IA != EA; ++IA, ++IB) { 247 SymbolBody &SA = A->File->getRelocTargetSym(*IA); 248 SymbolBody &SB = B->File->getRelocTargetSym(*IB); 249 if (&SA == &SB) 250 continue; 251 252 // Or, the symbols should be pointing to the same section 253 // in terms of the group ID. 254 auto *DA = dyn_cast<DefinedRegular<ELFT>>(&SA); 255 auto *DB = dyn_cast<DefinedRegular<ELFT>>(&SB); 256 if (!DA || !DB) 257 return false; 258 if (DA->Value != DB->Value) 259 return false; 260 InputSection<ELFT> *X = dyn_cast<InputSection<ELFT>>(DA->Section); 261 InputSection<ELFT> *Y = dyn_cast<InputSection<ELFT>>(DB->Section); 262 if (X && Y && X->GroupId && X->GroupId == Y->GroupId) 263 continue; 264 return false; 265 } 266 return true; 267 } 268 269 // Compare "moving" part of two InputSections, namely relocation targets. 270 template <class ELFT> 271 bool ICF<ELFT>::equalsVariable(const InputSection<ELFT> *A, 272 const InputSection<ELFT> *B) { 273 for (size_t I = 0, E = A->RelocSections.size(); I != E; ++I) { 274 const Elf_Shdr *RA = A->RelocSections[I]; 275 const Elf_Shdr *RB = B->RelocSections[I]; 276 ELFFile<ELFT> &FileA = A->File->getObj(); 277 ELFFile<ELFT> &FileB = B->File->getObj(); 278 if (RA->sh_type == SHT_RELA) { 279 if (!variableEq(A, B, FileA.relas(RA), FileB.relas(RB))) 280 return false; 281 } else { 282 if (!variableEq(A, B, FileA.rels(RA), FileB.rels(RB))) 283 return false; 284 } 285 } 286 return true; 287 } 288 289 // The main function of ICF. 290 template <class ELFT> void ICF<ELFT>::run() { 291 // Initially, we use hash values as section group IDs. Therefore, 292 // if two sections have the same ID, they are likely (but not 293 // guaranteed) to have the same static contents in terms of ICF. 294 std::vector<InputSection<ELFT> *> V = getSections(); 295 for (InputSection<ELFT> *S : V) 296 // Set MSB on to avoid collisions with serial group IDs 297 S->GroupId = getHash(S) | (uint64_t(1) << 63); 298 299 // From now on, sections in V are ordered so that sections in 300 // the same group are consecutive in the vector. 301 std::stable_sort(V.begin(), V.end(), 302 [](InputSection<ELFT> *A, InputSection<ELFT> *B) { 303 if (A->GroupId != B->GroupId) 304 return A->GroupId < B->GroupId; 305 // Within a group, put the highest alignment 306 // requirement first, so that's the one we'll keep. 307 return B->Alignment < A->Alignment; 308 }); 309 310 // Compare static contents and assign unique IDs for each static content. 311 forEachGroup(V, equalsConstant); 312 313 // Split groups by comparing relocations until we get a convergence. 314 int Cnt = 1; 315 for (;;) { 316 ++Cnt; 317 uint64_t Id = NextId; 318 forEachGroup(V, equalsVariable); 319 if (Id == NextId) 320 break; 321 } 322 log("ICF needed " + Twine(Cnt) + " iterations."); 323 324 // Merge sections in the same group. 325 for (auto I = V.begin(), E = V.end(); I != E;) { 326 InputSection<ELFT> *Head = *I++; 327 auto Bound = std::find_if(I, E, [&](InputSection<ELFT> *S) { 328 return Head->GroupId != S->GroupId; 329 }); 330 if (I == Bound) 331 continue; 332 log("selected " + Head->Name); 333 while (I != Bound) { 334 InputSection<ELFT> *S = *I++; 335 log(" removed " + S->Name); 336 Head->replace(S); 337 } 338 } 339 } 340 341 // ICF entry point function. 342 template <class ELFT> void elf::doIcf() { ICF<ELFT>().run(); } 343 344 template void elf::doIcf<ELF32LE>(); 345 template void elf::doIcf<ELF32BE>(); 346 template void elf::doIcf<ELF64LE>(); 347 template void elf::doIcf<ELF64BE>(); 348