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 // Implements ICF (Identical COMDAT Folding) 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "Chunks.h" 15 #include <tuple> 16 #include <unordered_set> 17 #include <vector> 18 19 namespace lld { 20 namespace coff { 21 namespace { 22 23 struct Hasher { 24 size_t operator()(const SectionChunk *C) const { return C->getHash(); } 25 }; 26 27 struct Equals { 28 bool operator()(const SectionChunk *A, const SectionChunk *B) const { 29 return A->equals(B); 30 } 31 }; 32 33 } // anonymous namespace 34 35 // Merge identical COMDAT sections. 36 // Two sections are considered as identical when their section headers, 37 // contents and relocations are all the same. 38 void doICF(const std::vector<Chunk *> &Chunks) { 39 std::unordered_set<SectionChunk *, Hasher, Equals> Set; 40 bool Redo; 41 do { 42 Set.clear(); 43 Redo = false; 44 for (Chunk *C : Chunks) { 45 auto *SC = dyn_cast<SectionChunk>(C); 46 if (!SC || !SC->isCOMDAT() || !SC->isLive()) 47 continue; 48 auto P = Set.insert(SC); 49 bool Inserted = P.second; 50 if (Inserted) 51 continue; 52 SectionChunk *Existing = *P.first; 53 SC->replaceWith(Existing); 54 // By merging sections, two relocations that originally pointed to 55 // different locations can now point to the same location. 56 // So, repeat the process until a convegence is obtained. 57 Redo = true; 58 } 59 } while (Redo); 60 } 61 62 } // namespace coff 63 } // namespace lld 64