]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/COFF/ICF.cpp
MFV r326007: less v529.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / COFF / ICF.cpp
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