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 #include "ICF.h" 10 #include "ConcatOutputSection.h" 11 #include "InputSection.h" 12 #include "Symbols.h" 13 #include "llvm/Support/Parallel.h" 14 15 #include <atomic> 16 17 using namespace llvm; 18 using namespace lld; 19 using namespace lld::macho; 20 21 ICF::ICF(std::vector<ConcatInputSection *> &inputs) { 22 icfInputs.assign(inputs.begin(), inputs.end()); 23 } 24 25 // ICF = Identical Code Folding 26 // 27 // We only fold __TEXT,__text, so this is really "code" folding, and not 28 // "COMDAT" folding. String and scalar constant literals are deduplicated 29 // elsewhere. 30 // 31 // Summary of segments & sections: 32 // 33 // Since folding never occurs across output-section boundaries, 34 // ConcatOutputSection is the natural input for ICF. 35 // 36 // The __TEXT segment is readonly at the MMU. Some sections are already 37 // deduplicated elsewhere (__TEXT,__cstring & __TEXT,__literal*) and some are 38 // synthetic and inherently free of duplicates (__TEXT,__stubs & 39 // __TEXT,__unwind_info). We only run ICF on __TEXT,__text. One might hope ICF 40 // could work on __TEXT,__concat, but doing so induces many test failures. 41 // 42 // The __LINKEDIT segment is readonly at the MMU, yet entirely synthetic, and 43 // thus ineligible for ICF. 44 // 45 // The __DATA_CONST segment is read/write at the MMU, but is logically const to 46 // the application after dyld applies fixups to pointer data. Some sections are 47 // deduplicated elsewhere (__DATA_CONST,__cfstring), and some are synthetic 48 // (__DATA_CONST,__got). There are no ICF opportunities here. 49 // 50 // The __DATA segment is read/write at the MMU, and as application-writeable 51 // data, none of its sections are eligible for ICF. 52 // 53 // Please see the large block comment in lld/ELF/ICF.cpp for an explanation 54 // of the segregation algorithm. 55 // 56 // FIXME(gkm): implement keep-unique attributes 57 // FIXME(gkm): implement address-significance tables for MachO object files 58 59 static unsigned icfPass = 0; 60 static std::atomic<bool> icfRepeat{false}; 61 62 // Compare everything except the relocation referents 63 static bool equalsConstant(const ConcatInputSection *ia, 64 const ConcatInputSection *ib) { 65 if (ia->data.size() != ib->data.size()) 66 return false; 67 if (ia->data != ib->data) 68 return false; 69 if (ia->flags != ib->flags) 70 return false; 71 if (ia->relocs.size() != ib->relocs.size()) 72 return false; 73 auto f = [&](const Reloc &ra, const Reloc &rb) { 74 if (ra.type != rb.type) 75 return false; 76 if (ra.pcrel != rb.pcrel) 77 return false; 78 if (ra.length != rb.length) 79 return false; 80 if (ra.offset != rb.offset) 81 return false; 82 if (ra.addend != rb.addend) 83 return false; 84 if (ra.referent.is<Symbol *>() != rb.referent.is<Symbol *>()) 85 return false; // a nice place to breakpoint 86 return true; 87 }; 88 return std::equal(ia->relocs.begin(), ia->relocs.end(), ib->relocs.begin(), 89 f); 90 } 91 92 // Compare only the relocation referents 93 static bool equalsVariable(const ConcatInputSection *ia, 94 const ConcatInputSection *ib) { 95 assert(ia->relocs.size() == ib->relocs.size()); 96 auto f = [&](const Reloc &ra, const Reloc &rb) { 97 if (ra.referent == rb.referent) 98 return true; 99 if (ra.referent.is<Symbol *>()) { 100 const auto *sa = ra.referent.get<Symbol *>(); 101 const auto *sb = rb.referent.get<Symbol *>(); 102 if (sa->kind() != sb->kind()) 103 return false; 104 if (isa<Defined>(sa)) { 105 const auto *da = dyn_cast<Defined>(sa); 106 const auto *db = dyn_cast<Defined>(sb); 107 if (da->value != db->value) 108 return false; 109 if (da->isAbsolute() != db->isAbsolute()) 110 return false; 111 if (da->isec) { 112 if (da->isec->kind() != db->isec->kind()) 113 return false; 114 if (const auto *isecA = dyn_cast<ConcatInputSection>(da->isec)) { 115 const auto *isecB = cast<ConcatInputSection>(db->isec); 116 if (isecA->icfEqClass[icfPass % 2] != 117 isecB->icfEqClass[icfPass % 2]) 118 return false; 119 } else { 120 // FIXME: implement ICF for other InputSection kinds 121 return false; 122 } 123 } 124 } else if (isa<DylibSymbol>(sa)) { 125 // There is one DylibSymbol per gotIndex and we already checked for 126 // symbol equality, thus we know that these must be different. 127 return false; 128 } else { 129 llvm_unreachable("equalsVariable symbol kind"); 130 } 131 } else { 132 const auto *sa = ra.referent.get<InputSection *>(); 133 const auto *sb = rb.referent.get<InputSection *>(); 134 if (sa->kind() != sb->kind()) 135 return false; 136 if (const auto *isecA = dyn_cast<ConcatInputSection>(sa)) { 137 const auto *isecB = cast<ConcatInputSection>(sb); 138 if (isecA->icfEqClass[icfPass % 2] != isecB->icfEqClass[icfPass % 2]) 139 return false; 140 } else { 141 // FIXME: implement ICF for other InputSection kinds 142 return false; 143 } 144 } 145 return true; 146 }; 147 return std::equal(ia->relocs.begin(), ia->relocs.end(), ib->relocs.begin(), 148 f); 149 } 150 151 // Find the first InputSection after BEGIN whose equivalence class differs 152 size_t ICF::findBoundary(size_t begin, size_t end) { 153 uint64_t beginHash = icfInputs[begin]->icfEqClass[icfPass % 2]; 154 for (size_t i = begin + 1; i < end; ++i) 155 if (beginHash != icfInputs[i]->icfEqClass[icfPass % 2]) 156 return i; 157 return end; 158 } 159 160 // Invoke FUNC on subranges with matching equivalence class 161 void ICF::forEachClassRange(size_t begin, size_t end, 162 std::function<void(size_t, size_t)> func) { 163 while (begin < end) { 164 size_t mid = findBoundary(begin, end); 165 func(begin, mid); 166 begin = mid; 167 } 168 } 169 170 // Split icfInputs into shards, then parallelize invocation of FUNC on subranges 171 // with matching equivalence class 172 void ICF::forEachClass(std::function<void(size_t, size_t)> func) { 173 // Only use threads when the benefits outweigh the overhead. 174 const size_t threadingThreshold = 1024; 175 if (icfInputs.size() < threadingThreshold) { 176 forEachClassRange(0, icfInputs.size(), func); 177 ++icfPass; 178 return; 179 } 180 181 // Shard into non-overlapping intervals, and call FUNC in parallel. The 182 // sharding must be completed before any calls to FUNC are made so that FUNC 183 // can modify the InputSection in its shard without causing data races. 184 const size_t shards = 256; 185 size_t step = icfInputs.size() / shards; 186 size_t boundaries[shards + 1]; 187 boundaries[0] = 0; 188 boundaries[shards] = icfInputs.size(); 189 parallelForEachN(1, shards, [&](size_t i) { 190 boundaries[i] = findBoundary((i - 1) * step, icfInputs.size()); 191 }); 192 parallelForEachN(1, shards + 1, [&](size_t i) { 193 if (boundaries[i - 1] < boundaries[i]) { 194 forEachClassRange(boundaries[i - 1], boundaries[i], func); 195 } 196 }); 197 ++icfPass; 198 } 199 200 void ICF::run() { 201 // Into each origin-section hash, combine all reloc referent section hashes. 202 for (icfPass = 0; icfPass < 2; ++icfPass) { 203 parallelForEach(icfInputs, [&](ConcatInputSection *isec) { 204 uint64_t hash = isec->icfEqClass[icfPass % 2]; 205 for (const Reloc &r : isec->relocs) { 206 if (auto *sym = r.referent.dyn_cast<Symbol *>()) { 207 if (auto *dylibSym = dyn_cast<DylibSymbol>(sym)) 208 hash += dylibSym->stubsHelperIndex; 209 else if (auto *defined = dyn_cast<Defined>(sym)) { 210 hash += defined->value; 211 if (defined->isec) 212 if (auto *isec = cast<ConcatInputSection>(defined->isec)) 213 hash += isec->icfEqClass[icfPass % 2]; 214 // FIXME: implement ICF for other InputSection kinds 215 } else 216 llvm_unreachable("foldIdenticalSections symbol kind"); 217 } 218 } 219 // Set MSB to 1 to avoid collisions with non-hashed classes. 220 isec->icfEqClass[(icfPass + 1) % 2] = hash | (1ull << 63); 221 }); 222 } 223 224 llvm::stable_sort( 225 icfInputs, [](const ConcatInputSection *a, const ConcatInputSection *b) { 226 return a->icfEqClass[0] < b->icfEqClass[0]; 227 }); 228 forEachClass( 229 [&](size_t begin, size_t end) { segregate(begin, end, equalsConstant); }); 230 231 // Split equivalence groups by comparing relocations until convergence 232 do { 233 icfRepeat = false; 234 forEachClass([&](size_t begin, size_t end) { 235 segregate(begin, end, equalsVariable); 236 }); 237 } while (icfRepeat); 238 log("ICF needed " + Twine(icfPass) + " iterations"); 239 240 // Fold sections within equivalence classes 241 forEachClass([&](size_t begin, size_t end) { 242 if (end - begin < 2) 243 return; 244 ConcatInputSection *beginIsec = icfInputs[begin]; 245 for (size_t i = begin + 1; i < end; ++i) 246 beginIsec->foldIdentical(icfInputs[i]); 247 }); 248 } 249 250 // Split an equivalence class into smaller classes. 251 void ICF::segregate( 252 size_t begin, size_t end, 253 std::function<bool(const ConcatInputSection *, const ConcatInputSection *)> 254 equals) { 255 while (begin < end) { 256 // Divide [begin, end) into two. Let mid be the start index of the 257 // second group. 258 auto bound = std::stable_partition(icfInputs.begin() + begin + 1, 259 icfInputs.begin() + end, 260 [&](ConcatInputSection *isec) { 261 return equals(icfInputs[begin], isec); 262 }); 263 size_t mid = bound - icfInputs.begin(); 264 265 // Split [begin, end) into [begin, mid) and [mid, end). We use mid as an 266 // equivalence class ID because every group ends with a unique index. 267 for (size_t i = begin; i < mid; ++i) 268 icfInputs[i]->icfEqClass[(icfPass + 1) % 2] = mid; 269 270 // If we created a group, we need to iterate the main loop again. 271 if (mid != end) 272 icfRepeat = true; 273 274 begin = mid; 275 } 276 } 277