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() != da->isAbsolute()) 110 return false; 111 if (da->isec) 112 if (da->isec->icfEqClass[icfPass % 2] != 113 db->isec->icfEqClass[icfPass % 2]) 114 return false; 115 } else if (isa<DylibSymbol>(sa)) { 116 // There is one DylibSymbol per gotIndex and we already checked for 117 // symbol equality, thus we know that these must be different. 118 return false; 119 } else { 120 llvm_unreachable("equalsVariable symbol kind"); 121 } 122 } else { 123 const auto *sa = ra.referent.get<InputSection *>(); 124 const auto *sb = rb.referent.get<InputSection *>(); 125 if (sa->icfEqClass[icfPass % 2] != sb->icfEqClass[icfPass % 2]) 126 return false; 127 } 128 return true; 129 }; 130 return std::equal(ia->relocs.begin(), ia->relocs.end(), ib->relocs.begin(), 131 f); 132 } 133 134 // Find the first InputSection after BEGIN whose equivalence class differs 135 size_t ICF::findBoundary(size_t begin, size_t end) { 136 uint64_t beginHash = icfInputs[begin]->icfEqClass[icfPass % 2]; 137 for (size_t i = begin + 1; i < end; ++i) 138 if (beginHash != icfInputs[i]->icfEqClass[icfPass % 2]) 139 return i; 140 return end; 141 } 142 143 // Invoke FUNC on subranges with matching equivalence class 144 void ICF::forEachClassRange(size_t begin, size_t end, 145 std::function<void(size_t, size_t)> func) { 146 while (begin < end) { 147 size_t mid = findBoundary(begin, end); 148 func(begin, mid); 149 begin = mid; 150 } 151 } 152 153 // Split icfInputs into shards, then parallelize invocation of FUNC on subranges 154 // with matching equivalence class 155 void ICF::forEachClass(std::function<void(size_t, size_t)> func) { 156 // Only use threads when the benefits outweigh the overhead. 157 const size_t threadingThreshold = 1024; 158 if (icfInputs.size() < threadingThreshold) { 159 forEachClassRange(0, icfInputs.size(), func); 160 ++icfPass; 161 return; 162 } 163 164 // Shard into non-overlapping intervals, and call FUNC in parallel. The 165 // sharding must be completed before any calls to FUNC are made so that FUNC 166 // can modify the InputSection in its shard without causing data races. 167 const size_t shards = 256; 168 size_t step = icfInputs.size() / shards; 169 size_t boundaries[shards + 1]; 170 boundaries[0] = 0; 171 boundaries[shards] = icfInputs.size(); 172 parallelForEachN(1, shards, [&](size_t i) { 173 boundaries[i] = findBoundary((i - 1) * step, icfInputs.size()); 174 }); 175 parallelForEachN(1, shards + 1, [&](size_t i) { 176 if (boundaries[i - 1] < boundaries[i]) { 177 forEachClassRange(boundaries[i - 1], boundaries[i], func); 178 } 179 }); 180 ++icfPass; 181 } 182 183 void ICF::run() { 184 // Into each origin-section hash, combine all reloc referent section hashes. 185 for (icfPass = 0; icfPass < 2; ++icfPass) { 186 parallelForEach(icfInputs, [&](InputSection *isec) { 187 uint64_t hash = isec->icfEqClass[icfPass % 2]; 188 for (const Reloc &r : isec->relocs) { 189 if (auto *sym = r.referent.dyn_cast<Symbol *>()) { 190 if (auto *dylibSym = dyn_cast<DylibSymbol>(sym)) 191 hash += dylibSym->stubsHelperIndex; 192 else if (auto *defined = dyn_cast<Defined>(sym)) 193 hash += 194 defined->value + 195 (defined->isec ? defined->isec->icfEqClass[icfPass % 2] : 0); 196 else 197 llvm_unreachable("foldIdenticalSections symbol kind"); 198 } 199 } 200 // Set MSB to 1 to avoid collisions with non-hashed classes. 201 isec->icfEqClass[(icfPass + 1) % 2] = hash | (1ull << 63); 202 }); 203 } 204 205 llvm::stable_sort(icfInputs, 206 [](const InputSection *a, const InputSection *b) { 207 return a->icfEqClass[0] < b->icfEqClass[0]; 208 }); 209 forEachClass( 210 [&](size_t begin, size_t end) { segregate(begin, end, equalsConstant); }); 211 212 // Split equivalence groups by comparing relocations until convergence 213 do { 214 icfRepeat = false; 215 forEachClass([&](size_t begin, size_t end) { 216 segregate(begin, end, equalsVariable); 217 }); 218 } while (icfRepeat); 219 log("ICF needed " + Twine(icfPass) + " iterations"); 220 221 // Fold sections within equivalence classes 222 forEachClass([&](size_t begin, size_t end) { 223 if (end - begin < 2) 224 return; 225 ConcatInputSection *beginIsec = icfInputs[begin]; 226 for (size_t i = begin + 1; i < end; ++i) 227 beginIsec->foldIdentical(icfInputs[i]); 228 }); 229 } 230 231 // Split an equivalence class into smaller classes. 232 void ICF::segregate( 233 size_t begin, size_t end, 234 std::function<bool(const ConcatInputSection *, const ConcatInputSection *)> 235 equals) { 236 while (begin < end) { 237 // Divide [begin, end) into two. Let mid be the start index of the 238 // second group. 239 auto bound = std::stable_partition(icfInputs.begin() + begin + 1, 240 icfInputs.begin() + end, 241 [&](ConcatInputSection *isec) { 242 return equals(icfInputs[begin], isec); 243 }); 244 size_t mid = bound - icfInputs.begin(); 245 246 // Split [begin, end) into [begin, mid) and [mid, end). We use mid as an 247 // equivalence class ID because every group ends with a unique index. 248 for (size_t i = begin; i < mid; ++i) 249 icfInputs[i]->icfEqClass[(icfPass + 1) % 2] = mid; 250 251 // If we created a group, we need to iterate the main loop again. 252 if (mid != end) 253 icfRepeat = true; 254 255 begin = mid; 256 } 257 } 258