1 //===- ICF.cpp ------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // ICF is short for Identical Code Folding. That is a size optimization to 10 // identify and merge two or more read-only sections (typically functions) 11 // that happened to have the same contents. It usually reduces output size 12 // by a few percent. 13 // 14 // On Windows, ICF is enabled by default. 15 // 16 // See ELF/ICF.cpp for the details about the algorithm. 17 // 18 //===----------------------------------------------------------------------===// 19 20 #include "ICF.h" 21 #include "Chunks.h" 22 #include "Symbols.h" 23 #include "lld/Common/ErrorHandler.h" 24 #include "lld/Common/Timer.h" 25 #include "llvm/ADT/Hashing.h" 26 #include "llvm/Support/Debug.h" 27 #include "llvm/Support/Parallel.h" 28 #include "llvm/Support/raw_ostream.h" 29 #include "llvm/Support/xxhash.h" 30 #include <algorithm> 31 #include <atomic> 32 #include <vector> 33 34 using namespace llvm; 35 36 namespace lld { 37 namespace coff { 38 39 static Timer icfTimer("ICF", Timer::root()); 40 41 class ICF { 42 public: 43 ICF(ICFLevel icfLevel) : icfLevel(icfLevel){}; 44 void run(ArrayRef<Chunk *> v); 45 46 private: 47 void segregate(size_t begin, size_t end, bool constant); 48 49 bool equalsEHData(const SectionChunk *a, const SectionChunk *b); 50 51 bool equalsConstant(const SectionChunk *a, const SectionChunk *b); 52 bool equalsVariable(const SectionChunk *a, const SectionChunk *b); 53 54 bool isEligible(SectionChunk *c); 55 56 size_t findBoundary(size_t begin, size_t end); 57 58 void forEachClassRange(size_t begin, size_t end, 59 std::function<void(size_t, size_t)> fn); 60 61 void forEachClass(std::function<void(size_t, size_t)> fn); 62 63 std::vector<SectionChunk *> chunks; 64 int cnt = 0; 65 std::atomic<bool> repeat = {false}; 66 ICFLevel icfLevel = ICFLevel::All; 67 }; 68 69 // Returns true if section S is subject of ICF. 70 // 71 // Microsoft's documentation 72 // (https://msdn.microsoft.com/en-us/library/bxwfs976.aspx; visited April 73 // 2017) says that /opt:icf folds both functions and read-only data. 74 // Despite that, the MSVC linker folds only functions. We found 75 // a few instances of programs that are not safe for data merging. 76 // Therefore, we merge only functions just like the MSVC tool. However, we also 77 // merge read-only sections in a couple of cases where the address of the 78 // section is insignificant to the user program and the behaviour matches that 79 // of the Visual C++ linker. 80 bool ICF::isEligible(SectionChunk *c) { 81 // Non-comdat chunks, dead chunks, and writable chunks are not eligible. 82 bool writable = c->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE; 83 if (!c->isCOMDAT() || !c->live || writable) 84 return false; 85 86 // Under regular (not safe) ICF, all code sections are eligible. 87 if ((icfLevel == ICFLevel::All) && 88 c->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE) 89 return true; 90 91 // .pdata and .xdata unwind info sections are eligible. 92 StringRef outSecName = c->getSectionName().split('$').first; 93 if (outSecName == ".pdata" || outSecName == ".xdata") 94 return true; 95 96 // So are vtables. 97 if (c->sym && c->sym->getName().startswith("??_7")) 98 return true; 99 100 // Anything else not in an address-significance table is eligible. 101 return !c->keepUnique; 102 } 103 104 // Split an equivalence class into smaller classes. 105 void ICF::segregate(size_t begin, size_t end, bool constant) { 106 while (begin < end) { 107 // Divide [Begin, End) into two. Let Mid be the start index of the 108 // second group. 109 auto bound = std::stable_partition( 110 chunks.begin() + begin + 1, chunks.begin() + end, [&](SectionChunk *s) { 111 if (constant) 112 return equalsConstant(chunks[begin], s); 113 return equalsVariable(chunks[begin], s); 114 }); 115 size_t mid = bound - chunks.begin(); 116 117 // Split [Begin, End) into [Begin, Mid) and [Mid, End). We use Mid as an 118 // equivalence class ID because every group ends with a unique index. 119 for (size_t i = begin; i < mid; ++i) 120 chunks[i]->eqClass[(cnt + 1) % 2] = mid; 121 122 // If we created a group, we need to iterate the main loop again. 123 if (mid != end) 124 repeat = true; 125 126 begin = mid; 127 } 128 } 129 130 // Returns true if two sections have equivalent associated .pdata/.xdata 131 // sections. 132 bool ICF::equalsEHData(const SectionChunk *a, const SectionChunk *b) { 133 auto findEHData = [](const SectionChunk *s) { 134 const SectionChunk *pdata = nullptr; 135 const SectionChunk *xdata = nullptr; 136 for (const SectionChunk &assoc : s->children()) { 137 StringRef name = assoc.getSectionName(); 138 if (name.startswith(".pdata") && (name.size() == 6 || name[6] == '$')) 139 pdata = &assoc; 140 else if (name.startswith(".xdata") && 141 (name.size() == 6 || name[6] == '$')) 142 xdata = &assoc; 143 } 144 return std::make_pair(pdata, xdata); 145 }; 146 auto aData = findEHData(a); 147 auto bData = findEHData(b); 148 auto considerEqual = [cnt = cnt](const SectionChunk *l, 149 const SectionChunk *r) { 150 return l == r || (l->getContents() == r->getContents() && 151 l->eqClass[cnt % 2] == r->eqClass[cnt % 2]); 152 }; 153 return considerEqual(aData.first, bData.first) && 154 considerEqual(aData.second, bData.second); 155 } 156 157 // Compare "non-moving" part of two sections, namely everything 158 // except relocation targets. 159 bool ICF::equalsConstant(const SectionChunk *a, const SectionChunk *b) { 160 if (a->relocsSize != b->relocsSize) 161 return false; 162 163 // Compare relocations. 164 auto eq = [&](const coff_relocation &r1, const coff_relocation &r2) { 165 if (r1.Type != r2.Type || 166 r1.VirtualAddress != r2.VirtualAddress) { 167 return false; 168 } 169 Symbol *b1 = a->file->getSymbol(r1.SymbolTableIndex); 170 Symbol *b2 = b->file->getSymbol(r2.SymbolTableIndex); 171 if (b1 == b2) 172 return true; 173 if (auto *d1 = dyn_cast<DefinedRegular>(b1)) 174 if (auto *d2 = dyn_cast<DefinedRegular>(b2)) 175 return d1->getValue() == d2->getValue() && 176 d1->getChunk()->eqClass[cnt % 2] == d2->getChunk()->eqClass[cnt % 2]; 177 return false; 178 }; 179 if (!std::equal(a->getRelocs().begin(), a->getRelocs().end(), 180 b->getRelocs().begin(), eq)) 181 return false; 182 183 // Compare section attributes and contents. 184 return a->getOutputCharacteristics() == b->getOutputCharacteristics() && 185 a->getSectionName() == b->getSectionName() && 186 a->header->SizeOfRawData == b->header->SizeOfRawData && 187 a->checksum == b->checksum && a->getContents() == b->getContents() && 188 equalsEHData(a, b); 189 } 190 191 // Compare "moving" part of two sections, namely relocation targets. 192 bool ICF::equalsVariable(const SectionChunk *a, const SectionChunk *b) { 193 // Compare relocations. 194 auto eq = [&](const coff_relocation &r1, const coff_relocation &r2) { 195 Symbol *b1 = a->file->getSymbol(r1.SymbolTableIndex); 196 Symbol *b2 = b->file->getSymbol(r2.SymbolTableIndex); 197 if (b1 == b2) 198 return true; 199 if (auto *d1 = dyn_cast<DefinedRegular>(b1)) 200 if (auto *d2 = dyn_cast<DefinedRegular>(b2)) 201 return d1->getChunk()->eqClass[cnt % 2] == d2->getChunk()->eqClass[cnt % 2]; 202 return false; 203 }; 204 return std::equal(a->getRelocs().begin(), a->getRelocs().end(), 205 b->getRelocs().begin(), eq) && 206 equalsEHData(a, b); 207 } 208 209 // Find the first Chunk after Begin that has a different class from Begin. 210 size_t ICF::findBoundary(size_t begin, size_t end) { 211 for (size_t i = begin + 1; i < end; ++i) 212 if (chunks[begin]->eqClass[cnt % 2] != chunks[i]->eqClass[cnt % 2]) 213 return i; 214 return end; 215 } 216 217 void ICF::forEachClassRange(size_t begin, size_t end, 218 std::function<void(size_t, size_t)> fn) { 219 while (begin < end) { 220 size_t mid = findBoundary(begin, end); 221 fn(begin, mid); 222 begin = mid; 223 } 224 } 225 226 // Call Fn on each class group. 227 void ICF::forEachClass(std::function<void(size_t, size_t)> fn) { 228 // If the number of sections are too small to use threading, 229 // call Fn sequentially. 230 if (chunks.size() < 1024) { 231 forEachClassRange(0, chunks.size(), fn); 232 ++cnt; 233 return; 234 } 235 236 // Shard into non-overlapping intervals, and call Fn in parallel. 237 // The sharding must be completed before any calls to Fn are made 238 // so that Fn can modify the Chunks in its shard without causing data 239 // races. 240 const size_t numShards = 256; 241 size_t step = chunks.size() / numShards; 242 size_t boundaries[numShards + 1]; 243 boundaries[0] = 0; 244 boundaries[numShards] = chunks.size(); 245 parallelForEachN(1, numShards, [&](size_t i) { 246 boundaries[i] = findBoundary((i - 1) * step, chunks.size()); 247 }); 248 parallelForEachN(1, numShards + 1, [&](size_t i) { 249 if (boundaries[i - 1] < boundaries[i]) { 250 forEachClassRange(boundaries[i - 1], boundaries[i], fn); 251 } 252 }); 253 ++cnt; 254 } 255 256 // Merge identical COMDAT sections. 257 // Two sections are considered the same if their section headers, 258 // contents and relocations are all the same. 259 void ICF::run(ArrayRef<Chunk *> vec) { 260 ScopedTimer t(icfTimer); 261 262 // Collect only mergeable sections and group by hash value. 263 uint32_t nextId = 1; 264 for (Chunk *c : vec) { 265 if (auto *sc = dyn_cast<SectionChunk>(c)) { 266 if (isEligible(sc)) 267 chunks.push_back(sc); 268 else 269 sc->eqClass[0] = nextId++; 270 } 271 } 272 273 // Make sure that ICF doesn't merge sections that are being handled by string 274 // tail merging. 275 for (MergeChunk *mc : MergeChunk::instances) 276 if (mc) 277 for (SectionChunk *sc : mc->sections) 278 sc->eqClass[0] = nextId++; 279 280 // Initially, we use hash values to partition sections. 281 parallelForEach(chunks, [&](SectionChunk *sc) { 282 sc->eqClass[0] = xxHash64(sc->getContents()); 283 }); 284 285 // Combine the hashes of the sections referenced by each section into its 286 // hash. 287 for (unsigned cnt = 0; cnt != 2; ++cnt) { 288 parallelForEach(chunks, [&](SectionChunk *sc) { 289 uint32_t hash = sc->eqClass[cnt % 2]; 290 for (Symbol *b : sc->symbols()) 291 if (auto *sym = dyn_cast_or_null<DefinedRegular>(b)) 292 hash += sym->getChunk()->eqClass[cnt % 2]; 293 // Set MSB to 1 to avoid collisions with non-hash classes. 294 sc->eqClass[(cnt + 1) % 2] = hash | (1U << 31); 295 }); 296 } 297 298 // From now on, sections in Chunks are ordered so that sections in 299 // the same group are consecutive in the vector. 300 llvm::stable_sort(chunks, [](const SectionChunk *a, const SectionChunk *b) { 301 return a->eqClass[0] < b->eqClass[0]; 302 }); 303 304 // Compare static contents and assign unique IDs for each static content. 305 forEachClass([&](size_t begin, size_t end) { segregate(begin, end, true); }); 306 307 // Split groups by comparing relocations until convergence is obtained. 308 do { 309 repeat = false; 310 forEachClass( 311 [&](size_t begin, size_t end) { segregate(begin, end, false); }); 312 } while (repeat); 313 314 log("ICF needed " + Twine(cnt) + " iterations"); 315 316 // Merge sections in the same classes. 317 forEachClass([&](size_t begin, size_t end) { 318 if (end - begin == 1) 319 return; 320 321 log("Selected " + chunks[begin]->getDebugName()); 322 for (size_t i = begin + 1; i < end; ++i) { 323 log(" Removed " + chunks[i]->getDebugName()); 324 chunks[begin]->replace(chunks[i]); 325 } 326 }); 327 } 328 329 // Entry point to ICF. 330 void doICF(ArrayRef<Chunk *> chunks, ICFLevel icfLevel) { 331 ICF(icfLevel).run(chunks); 332 } 333 334 } // namespace coff 335 } // namespace lld 336