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 // ICF is short for Identical Code Folding. That is a size optimization to 11 // identify and merge two or more read-only sections (typically functions) 12 // that happened to have the same contents. It usually reduces output size 13 // by a few percent. 14 // 15 // On Windows, ICF is enabled by default. 16 // 17 // See ELF/ICF.cpp for the details about the algortihm. 18 // 19 //===----------------------------------------------------------------------===// 20 21 #include "Chunks.h" 22 #include "Error.h" 23 #include "Symbols.h" 24 #include "llvm/ADT/Hashing.h" 25 #include "llvm/Support/Debug.h" 26 #include "llvm/Support/Parallel.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include <algorithm> 29 #include <atomic> 30 #include <vector> 31 32 using namespace llvm; 33 34 namespace lld { 35 namespace coff { 36 37 class ICF { 38 public: 39 void run(const std::vector<Chunk *> &V); 40 41 private: 42 void segregate(size_t Begin, size_t End, bool Constant); 43 44 bool equalsConstant(const SectionChunk *A, const SectionChunk *B); 45 bool equalsVariable(const SectionChunk *A, const SectionChunk *B); 46 47 uint32_t getHash(SectionChunk *C); 48 bool isEligible(SectionChunk *C); 49 50 size_t findBoundary(size_t Begin, size_t End); 51 52 void forEachClassRange(size_t Begin, size_t End, 53 std::function<void(size_t, size_t)> Fn); 54 55 void forEachClass(std::function<void(size_t, size_t)> Fn); 56 57 std::vector<SectionChunk *> Chunks; 58 int Cnt = 0; 59 std::atomic<bool> Repeat = {false}; 60 }; 61 62 // Returns a hash value for S. 63 uint32_t ICF::getHash(SectionChunk *C) { 64 return hash_combine(C->getPermissions(), 65 hash_value(C->SectionName), 66 C->NumRelocs, 67 C->getAlign(), 68 uint32_t(C->Header->SizeOfRawData), 69 C->Checksum); 70 } 71 72 // Returns true if section S is subject of ICF. 73 // 74 // Microsoft's documentation 75 // (https://msdn.microsoft.com/en-us/library/bxwfs976.aspx; visited April 76 // 2017) says that /opt:icf folds both functions and read-only data. 77 // Despite that, the MSVC linker folds only functions. We found 78 // a few instances of programs that are not safe for data merging. 79 // Therefore, we merge only functions just like the MSVC tool. 80 bool ICF::isEligible(SectionChunk *C) { 81 bool Global = C->Sym && C->Sym->isExternal(); 82 bool Executable = C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE; 83 bool Writable = C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_WRITE; 84 return C->isCOMDAT() && C->isLive() && Global && Executable && !Writable; 85 } 86 87 // Split an equivalence class into smaller classes. 88 void ICF::segregate(size_t Begin, size_t End, bool Constant) { 89 while (Begin < End) { 90 // Divide [Begin, End) into two. Let Mid be the start index of the 91 // second group. 92 auto Bound = std::stable_partition( 93 Chunks.begin() + Begin + 1, Chunks.begin() + End, [&](SectionChunk *S) { 94 if (Constant) 95 return equalsConstant(Chunks[Begin], S); 96 return equalsVariable(Chunks[Begin], S); 97 }); 98 size_t Mid = Bound - Chunks.begin(); 99 100 // Split [Begin, End) into [Begin, Mid) and [Mid, End). We use Mid as an 101 // equivalence class ID because every group ends with a unique index. 102 for (size_t I = Begin; I < Mid; ++I) 103 Chunks[I]->Class[(Cnt + 1) % 2] = Mid; 104 105 // If we created a group, we need to iterate the main loop again. 106 if (Mid != End) 107 Repeat = true; 108 109 Begin = Mid; 110 } 111 } 112 113 // Compare "non-moving" part of two sections, namely everything 114 // except relocation targets. 115 bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) { 116 if (A->NumRelocs != B->NumRelocs) 117 return false; 118 119 // Compare relocations. 120 auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) { 121 if (R1.Type != R2.Type || 122 R1.VirtualAddress != R2.VirtualAddress) { 123 return false; 124 } 125 SymbolBody *B1 = A->File->getSymbolBody(R1.SymbolTableIndex); 126 SymbolBody *B2 = B->File->getSymbolBody(R2.SymbolTableIndex); 127 if (B1 == B2) 128 return true; 129 if (auto *D1 = dyn_cast<DefinedRegular>(B1)) 130 if (auto *D2 = dyn_cast<DefinedRegular>(B2)) 131 return D1->getValue() == D2->getValue() && 132 D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2]; 133 return false; 134 }; 135 if (!std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq)) 136 return false; 137 138 // Compare section attributes and contents. 139 return A->getPermissions() == B->getPermissions() && 140 A->SectionName == B->SectionName && 141 A->getAlign() == B->getAlign() && 142 A->Header->SizeOfRawData == B->Header->SizeOfRawData && 143 A->Checksum == B->Checksum && 144 A->getContents() == B->getContents(); 145 } 146 147 // Compare "moving" part of two sections, namely relocation targets. 148 bool ICF::equalsVariable(const SectionChunk *A, const SectionChunk *B) { 149 // Compare relocations. 150 auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) { 151 SymbolBody *B1 = A->File->getSymbolBody(R1.SymbolTableIndex); 152 SymbolBody *B2 = B->File->getSymbolBody(R2.SymbolTableIndex); 153 if (B1 == B2) 154 return true; 155 if (auto *D1 = dyn_cast<DefinedRegular>(B1)) 156 if (auto *D2 = dyn_cast<DefinedRegular>(B2)) 157 return D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2]; 158 return false; 159 }; 160 return std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq); 161 } 162 163 size_t ICF::findBoundary(size_t Begin, size_t End) { 164 for (size_t I = Begin + 1; I < End; ++I) 165 if (Chunks[Begin]->Class[Cnt % 2] != Chunks[I]->Class[Cnt % 2]) 166 return I; 167 return End; 168 } 169 170 void ICF::forEachClassRange(size_t Begin, size_t End, 171 std::function<void(size_t, size_t)> Fn) { 172 if (Begin > 0) 173 Begin = findBoundary(Begin - 1, End); 174 175 while (Begin < End) { 176 size_t Mid = findBoundary(Begin, Chunks.size()); 177 Fn(Begin, Mid); 178 Begin = Mid; 179 } 180 } 181 182 // Call Fn on each class group. 183 void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) { 184 // If the number of sections are too small to use threading, 185 // call Fn sequentially. 186 if (Chunks.size() < 1024) { 187 forEachClassRange(0, Chunks.size(), Fn); 188 ++Cnt; 189 return; 190 } 191 192 // Split sections into 256 shards and call Fn in parallel. 193 size_t NumShards = 256; 194 size_t Step = Chunks.size() / NumShards; 195 for_each_n(parallel::par, size_t(0), NumShards, [&](size_t I) { 196 size_t End = (I == NumShards - 1) ? Chunks.size() : (I + 1) * Step; 197 forEachClassRange(I * Step, End, Fn); 198 }); 199 ++Cnt; 200 } 201 202 // Merge identical COMDAT sections. 203 // Two sections are considered the same if their section headers, 204 // contents and relocations are all the same. 205 void ICF::run(const std::vector<Chunk *> &Vec) { 206 // Collect only mergeable sections and group by hash value. 207 uint32_t NextId = 1; 208 for (Chunk *C : Vec) { 209 if (auto *SC = dyn_cast<SectionChunk>(C)) { 210 if (isEligible(SC)) 211 Chunks.push_back(SC); 212 else 213 SC->Class[0] = NextId++; 214 } 215 } 216 217 // Initially, we use hash values to partition sections. 218 for (SectionChunk *SC : Chunks) 219 // Set MSB to 1 to avoid collisions with non-hash classs. 220 SC->Class[0] = getHash(SC) | (1 << 31); 221 222 // From now on, sections in Chunks are ordered so that sections in 223 // the same group are consecutive in the vector. 224 std::stable_sort(Chunks.begin(), Chunks.end(), 225 [](SectionChunk *A, SectionChunk *B) { 226 return A->Class[0] < B->Class[0]; 227 }); 228 229 // Compare static contents and assign unique IDs for each static content. 230 forEachClass([&](size_t Begin, size_t End) { segregate(Begin, End, true); }); 231 232 // Split groups by comparing relocations until convergence is obtained. 233 do { 234 Repeat = false; 235 forEachClass( 236 [&](size_t Begin, size_t End) { segregate(Begin, End, false); }); 237 } while (Repeat); 238 239 log("ICF needed " + Twine(Cnt) + " iterations"); 240 241 // Merge sections in the same classs. 242 forEachClass([&](size_t Begin, size_t End) { 243 if (End - Begin == 1) 244 return; 245 246 log("Selected " + Chunks[Begin]->getDebugName()); 247 for (size_t I = Begin + 1; I < End; ++I) { 248 log(" Removed " + Chunks[I]->getDebugName()); 249 Chunks[Begin]->replace(Chunks[I]); 250 } 251 }); 252 } 253 254 // Entry point to ICF. 255 void doICF(const std::vector<Chunk *> &Chunks) { ICF().run(Chunks); } 256 257 } // namespace coff 258 } // namespace lld 259