1*9880d681SAndroid Build Coastguard Worker //===-ThinLTOCodeGenerator.cpp - LLVM Link Time Optimizer -----------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the Thin Link Time Optimization library. This library is
11*9880d681SAndroid Build Coastguard Worker // intended to be used by linker to optimize code at link time.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "llvm/LTO/legacy/ThinLTOCodeGenerator.h"
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker #ifdef HAVE_LLVM_REVISION
18*9880d681SAndroid Build Coastguard Worker #include "LLVMLTORevision.h"
19*9880d681SAndroid Build Coastguard Worker #endif
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ModuleSummaryAnalysis.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/TargetLibraryInfo.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/TargetTransformInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Bitcode/BitcodeWriterPass.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Bitcode/ReaderWriter.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DiagnosticPrinter.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LegacyPassManager.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/IRReader/IRReader.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/LTO/LTO.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Linker/Linker.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/SubtargetFeature.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/IRObjectFile.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ModuleSummaryIndexObjectFile.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CachePruning.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Path.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SHA1.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ThreadPool.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
46*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/IPO.h"
47*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/IPO/FunctionImport.h"
48*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/IPO/Internalize.h"
49*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/IPO/PassManagerBuilder.h"
50*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/ObjCARC.h"
51*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/FunctionImportUtils.h"
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker #include <numeric>
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker using namespace llvm;
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "thinlto"
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker namespace llvm {
60*9880d681SAndroid Build Coastguard Worker // Flags -discard-value-names, defined in LTOCodeGenerator.cpp
61*9880d681SAndroid Build Coastguard Worker extern cl::opt<bool> LTODiscardValueNames;
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker namespace {
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker static cl::opt<int> ThreadCount("threads",
67*9880d681SAndroid Build Coastguard Worker cl::init(std::thread::hardware_concurrency()));
68*9880d681SAndroid Build Coastguard Worker
diagnosticHandler(const DiagnosticInfo & DI)69*9880d681SAndroid Build Coastguard Worker static void diagnosticHandler(const DiagnosticInfo &DI) {
70*9880d681SAndroid Build Coastguard Worker DiagnosticPrinterRawOStream DP(errs());
71*9880d681SAndroid Build Coastguard Worker DI.print(DP);
72*9880d681SAndroid Build Coastguard Worker errs() << '\n';
73*9880d681SAndroid Build Coastguard Worker }
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker // Simple helper to save temporary files for debug.
saveTempBitcode(const Module & TheModule,StringRef TempDir,unsigned count,StringRef Suffix)76*9880d681SAndroid Build Coastguard Worker static void saveTempBitcode(const Module &TheModule, StringRef TempDir,
77*9880d681SAndroid Build Coastguard Worker unsigned count, StringRef Suffix) {
78*9880d681SAndroid Build Coastguard Worker if (TempDir.empty())
79*9880d681SAndroid Build Coastguard Worker return;
80*9880d681SAndroid Build Coastguard Worker // User asked to save temps, let dump the bitcode file after import.
81*9880d681SAndroid Build Coastguard Worker auto SaveTempPath = TempDir + llvm::utostr(count) + Suffix;
82*9880d681SAndroid Build Coastguard Worker std::error_code EC;
83*9880d681SAndroid Build Coastguard Worker raw_fd_ostream OS(SaveTempPath.str(), EC, sys::fs::F_None);
84*9880d681SAndroid Build Coastguard Worker if (EC)
85*9880d681SAndroid Build Coastguard Worker report_fatal_error(Twine("Failed to open ") + SaveTempPath +
86*9880d681SAndroid Build Coastguard Worker " to save optimized bitcode\n");
87*9880d681SAndroid Build Coastguard Worker WriteBitcodeToFile(&TheModule, OS, /* ShouldPreserveUseListOrder */ true);
88*9880d681SAndroid Build Coastguard Worker }
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker static const GlobalValueSummary *
getFirstDefinitionForLinker(const GlobalValueSummaryList & GVSummaryList)91*9880d681SAndroid Build Coastguard Worker getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
92*9880d681SAndroid Build Coastguard Worker // If there is any strong definition anywhere, get it.
93*9880d681SAndroid Build Coastguard Worker auto StrongDefForLinker = llvm::find_if(
94*9880d681SAndroid Build Coastguard Worker GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
95*9880d681SAndroid Build Coastguard Worker auto Linkage = Summary->linkage();
96*9880d681SAndroid Build Coastguard Worker return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
97*9880d681SAndroid Build Coastguard Worker !GlobalValue::isWeakForLinker(Linkage);
98*9880d681SAndroid Build Coastguard Worker });
99*9880d681SAndroid Build Coastguard Worker if (StrongDefForLinker != GVSummaryList.end())
100*9880d681SAndroid Build Coastguard Worker return StrongDefForLinker->get();
101*9880d681SAndroid Build Coastguard Worker // Get the first *linker visible* definition for this global in the summary
102*9880d681SAndroid Build Coastguard Worker // list.
103*9880d681SAndroid Build Coastguard Worker auto FirstDefForLinker = llvm::find_if(
104*9880d681SAndroid Build Coastguard Worker GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
105*9880d681SAndroid Build Coastguard Worker auto Linkage = Summary->linkage();
106*9880d681SAndroid Build Coastguard Worker return !GlobalValue::isAvailableExternallyLinkage(Linkage);
107*9880d681SAndroid Build Coastguard Worker });
108*9880d681SAndroid Build Coastguard Worker // Extern templates can be emitted as available_externally.
109*9880d681SAndroid Build Coastguard Worker if (FirstDefForLinker == GVSummaryList.end())
110*9880d681SAndroid Build Coastguard Worker return nullptr;
111*9880d681SAndroid Build Coastguard Worker return FirstDefForLinker->get();
112*9880d681SAndroid Build Coastguard Worker }
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker // Populate map of GUID to the prevailing copy for any multiply defined
115*9880d681SAndroid Build Coastguard Worker // symbols. Currently assume first copy is prevailing, or any strong
116*9880d681SAndroid Build Coastguard Worker // definition. Can be refined with Linker information in the future.
computePrevailingCopies(const ModuleSummaryIndex & Index,DenseMap<GlobalValue::GUID,const GlobalValueSummary * > & PrevailingCopy)117*9880d681SAndroid Build Coastguard Worker static void computePrevailingCopies(
118*9880d681SAndroid Build Coastguard Worker const ModuleSummaryIndex &Index,
119*9880d681SAndroid Build Coastguard Worker DenseMap<GlobalValue::GUID, const GlobalValueSummary *> &PrevailingCopy) {
120*9880d681SAndroid Build Coastguard Worker auto HasMultipleCopies = [&](const GlobalValueSummaryList &GVSummaryList) {
121*9880d681SAndroid Build Coastguard Worker return GVSummaryList.size() > 1;
122*9880d681SAndroid Build Coastguard Worker };
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker for (auto &I : Index) {
125*9880d681SAndroid Build Coastguard Worker if (HasMultipleCopies(I.second))
126*9880d681SAndroid Build Coastguard Worker PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second);
127*9880d681SAndroid Build Coastguard Worker }
128*9880d681SAndroid Build Coastguard Worker }
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker static StringMap<MemoryBufferRef>
generateModuleMap(const std::vector<MemoryBufferRef> & Modules)131*9880d681SAndroid Build Coastguard Worker generateModuleMap(const std::vector<MemoryBufferRef> &Modules) {
132*9880d681SAndroid Build Coastguard Worker StringMap<MemoryBufferRef> ModuleMap;
133*9880d681SAndroid Build Coastguard Worker for (auto &ModuleBuffer : Modules) {
134*9880d681SAndroid Build Coastguard Worker assert(ModuleMap.find(ModuleBuffer.getBufferIdentifier()) ==
135*9880d681SAndroid Build Coastguard Worker ModuleMap.end() &&
136*9880d681SAndroid Build Coastguard Worker "Expect unique Buffer Identifier");
137*9880d681SAndroid Build Coastguard Worker ModuleMap[ModuleBuffer.getBufferIdentifier()] = ModuleBuffer;
138*9880d681SAndroid Build Coastguard Worker }
139*9880d681SAndroid Build Coastguard Worker return ModuleMap;
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker
promoteModule(Module & TheModule,const ModuleSummaryIndex & Index)142*9880d681SAndroid Build Coastguard Worker static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index) {
143*9880d681SAndroid Build Coastguard Worker if (renameModuleForThinLTO(TheModule, Index))
144*9880d681SAndroid Build Coastguard Worker report_fatal_error("renameModuleForThinLTO failed");
145*9880d681SAndroid Build Coastguard Worker }
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker static void
crossImportIntoModule(Module & TheModule,const ModuleSummaryIndex & Index,StringMap<MemoryBufferRef> & ModuleMap,const FunctionImporter::ImportMapTy & ImportList)148*9880d681SAndroid Build Coastguard Worker crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index,
149*9880d681SAndroid Build Coastguard Worker StringMap<MemoryBufferRef> &ModuleMap,
150*9880d681SAndroid Build Coastguard Worker const FunctionImporter::ImportMapTy &ImportList) {
151*9880d681SAndroid Build Coastguard Worker ModuleLoader Loader(TheModule.getContext(), ModuleMap);
152*9880d681SAndroid Build Coastguard Worker FunctionImporter Importer(Index, Loader);
153*9880d681SAndroid Build Coastguard Worker Importer.importFunctions(TheModule, ImportList);
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker
optimizeModule(Module & TheModule,TargetMachine & TM)156*9880d681SAndroid Build Coastguard Worker static void optimizeModule(Module &TheModule, TargetMachine &TM) {
157*9880d681SAndroid Build Coastguard Worker // Populate the PassManager
158*9880d681SAndroid Build Coastguard Worker PassManagerBuilder PMB;
159*9880d681SAndroid Build Coastguard Worker PMB.LibraryInfo = new TargetLibraryInfoImpl(TM.getTargetTriple());
160*9880d681SAndroid Build Coastguard Worker PMB.Inliner = createFunctionInliningPass();
161*9880d681SAndroid Build Coastguard Worker // FIXME: should get it from the bitcode?
162*9880d681SAndroid Build Coastguard Worker PMB.OptLevel = 3;
163*9880d681SAndroid Build Coastguard Worker PMB.LoopVectorize = true;
164*9880d681SAndroid Build Coastguard Worker PMB.SLPVectorize = true;
165*9880d681SAndroid Build Coastguard Worker PMB.VerifyInput = true;
166*9880d681SAndroid Build Coastguard Worker PMB.VerifyOutput = false;
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker legacy::PassManager PM;
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard Worker // Add the TTI (required to inform the vectorizer about register size for
171*9880d681SAndroid Build Coastguard Worker // instance)
172*9880d681SAndroid Build Coastguard Worker PM.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));
173*9880d681SAndroid Build Coastguard Worker
174*9880d681SAndroid Build Coastguard Worker // Add optimizations
175*9880d681SAndroid Build Coastguard Worker PMB.populateThinLTOPassManager(PM);
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker PM.run(TheModule);
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker // Convert the PreservedSymbols map from "Name" based to "GUID" based.
181*9880d681SAndroid Build Coastguard Worker static DenseSet<GlobalValue::GUID>
computeGUIDPreservedSymbols(const StringSet<> & PreservedSymbols,const Triple & TheTriple)182*9880d681SAndroid Build Coastguard Worker computeGUIDPreservedSymbols(const StringSet<> &PreservedSymbols,
183*9880d681SAndroid Build Coastguard Worker const Triple &TheTriple) {
184*9880d681SAndroid Build Coastguard Worker DenseSet<GlobalValue::GUID> GUIDPreservedSymbols(PreservedSymbols.size());
185*9880d681SAndroid Build Coastguard Worker for (auto &Entry : PreservedSymbols) {
186*9880d681SAndroid Build Coastguard Worker StringRef Name = Entry.first();
187*9880d681SAndroid Build Coastguard Worker if (TheTriple.isOSBinFormatMachO() && Name.size() > 0 && Name[0] == '_')
188*9880d681SAndroid Build Coastguard Worker Name = Name.drop_front();
189*9880d681SAndroid Build Coastguard Worker GUIDPreservedSymbols.insert(GlobalValue::getGUID(Name));
190*9880d681SAndroid Build Coastguard Worker }
191*9880d681SAndroid Build Coastguard Worker return GUIDPreservedSymbols;
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker
codegenModule(Module & TheModule,TargetMachine & TM)194*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
195*9880d681SAndroid Build Coastguard Worker TargetMachine &TM) {
196*9880d681SAndroid Build Coastguard Worker SmallVector<char, 128> OutputBuffer;
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker // CodeGen
199*9880d681SAndroid Build Coastguard Worker {
200*9880d681SAndroid Build Coastguard Worker raw_svector_ostream OS(OutputBuffer);
201*9880d681SAndroid Build Coastguard Worker legacy::PassManager PM;
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker // If the bitcode files contain ARC code and were compiled with optimization,
204*9880d681SAndroid Build Coastguard Worker // the ObjCARCContractPass must be run, so do it unconditionally here.
205*9880d681SAndroid Build Coastguard Worker PM.add(createObjCARCContractPass());
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker // Setup the codegen now.
208*9880d681SAndroid Build Coastguard Worker if (TM.addPassesToEmitFile(PM, OS, TargetMachine::CGFT_ObjectFile,
209*9880d681SAndroid Build Coastguard Worker /* DisableVerify */ true))
210*9880d681SAndroid Build Coastguard Worker report_fatal_error("Failed to setup codegen");
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker // Run codegen now. resulting binary is in OutputBuffer.
213*9880d681SAndroid Build Coastguard Worker PM.run(TheModule);
214*9880d681SAndroid Build Coastguard Worker }
215*9880d681SAndroid Build Coastguard Worker return make_unique<ObjectMemoryBuffer>(std::move(OutputBuffer));
216*9880d681SAndroid Build Coastguard Worker }
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker /// Manage caching for a single Module.
219*9880d681SAndroid Build Coastguard Worker class ModuleCacheEntry {
220*9880d681SAndroid Build Coastguard Worker SmallString<128> EntryPath;
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker public:
223*9880d681SAndroid Build Coastguard Worker // Create a cache entry. This compute a unique hash for the Module considering
224*9880d681SAndroid Build Coastguard Worker // the current list of export/import, and offer an interface to query to
225*9880d681SAndroid Build Coastguard Worker // access the content in the cache.
ModuleCacheEntry(StringRef CachePath,const ModuleSummaryIndex & Index,StringRef ModuleID,const FunctionImporter::ImportMapTy & ImportList,const FunctionImporter::ExportSetTy & ExportList,const std::map<GlobalValue::GUID,GlobalValue::LinkageTypes> & ResolvedODR,const GVSummaryMapTy & DefinedFunctions,const DenseSet<GlobalValue::GUID> & PreservedSymbols)226*9880d681SAndroid Build Coastguard Worker ModuleCacheEntry(
227*9880d681SAndroid Build Coastguard Worker StringRef CachePath, const ModuleSummaryIndex &Index, StringRef ModuleID,
228*9880d681SAndroid Build Coastguard Worker const FunctionImporter::ImportMapTy &ImportList,
229*9880d681SAndroid Build Coastguard Worker const FunctionImporter::ExportSetTy &ExportList,
230*9880d681SAndroid Build Coastguard Worker const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
231*9880d681SAndroid Build Coastguard Worker const GVSummaryMapTy &DefinedFunctions,
232*9880d681SAndroid Build Coastguard Worker const DenseSet<GlobalValue::GUID> &PreservedSymbols) {
233*9880d681SAndroid Build Coastguard Worker if (CachePath.empty())
234*9880d681SAndroid Build Coastguard Worker return;
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker // Compute the unique hash for this entry
237*9880d681SAndroid Build Coastguard Worker // This is based on the current compiler version, the module itself, the
238*9880d681SAndroid Build Coastguard Worker // export list, the hash for every single module in the import list, the
239*9880d681SAndroid Build Coastguard Worker // list of ResolvedODR for the module, and the list of preserved symbols.
240*9880d681SAndroid Build Coastguard Worker
241*9880d681SAndroid Build Coastguard Worker SHA1 Hasher;
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Worker // Start with the compiler revision
244*9880d681SAndroid Build Coastguard Worker Hasher.update(LLVM_VERSION_STRING);
245*9880d681SAndroid Build Coastguard Worker #ifdef HAVE_LLVM_REVISION
246*9880d681SAndroid Build Coastguard Worker Hasher.update(LLVM_REVISION);
247*9880d681SAndroid Build Coastguard Worker #endif
248*9880d681SAndroid Build Coastguard Worker
249*9880d681SAndroid Build Coastguard Worker // Include the hash for the current module
250*9880d681SAndroid Build Coastguard Worker auto ModHash = Index.getModuleHash(ModuleID);
251*9880d681SAndroid Build Coastguard Worker Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));
252*9880d681SAndroid Build Coastguard Worker for (auto F : ExportList)
253*9880d681SAndroid Build Coastguard Worker // The export list can impact the internalization, be conservative here
254*9880d681SAndroid Build Coastguard Worker Hasher.update(ArrayRef<uint8_t>((uint8_t *)&F, sizeof(F)));
255*9880d681SAndroid Build Coastguard Worker
256*9880d681SAndroid Build Coastguard Worker // Include the hash for every module we import functions from
257*9880d681SAndroid Build Coastguard Worker for (auto &Entry : ImportList) {
258*9880d681SAndroid Build Coastguard Worker auto ModHash = Index.getModuleHash(Entry.first());
259*9880d681SAndroid Build Coastguard Worker Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));
260*9880d681SAndroid Build Coastguard Worker }
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker // Include the hash for the resolved ODR.
263*9880d681SAndroid Build Coastguard Worker for (auto &Entry : ResolvedODR) {
264*9880d681SAndroid Build Coastguard Worker Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.first,
265*9880d681SAndroid Build Coastguard Worker sizeof(GlobalValue::GUID)));
266*9880d681SAndroid Build Coastguard Worker Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.second,
267*9880d681SAndroid Build Coastguard Worker sizeof(GlobalValue::LinkageTypes)));
268*9880d681SAndroid Build Coastguard Worker }
269*9880d681SAndroid Build Coastguard Worker
270*9880d681SAndroid Build Coastguard Worker // Include the hash for the preserved symbols.
271*9880d681SAndroid Build Coastguard Worker for (auto &Entry : PreservedSymbols) {
272*9880d681SAndroid Build Coastguard Worker if (DefinedFunctions.count(Entry))
273*9880d681SAndroid Build Coastguard Worker Hasher.update(
274*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t>((const uint8_t *)&Entry, sizeof(GlobalValue::GUID)));
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker
277*9880d681SAndroid Build Coastguard Worker sys::path::append(EntryPath, CachePath, toHex(Hasher.result()));
278*9880d681SAndroid Build Coastguard Worker }
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker // Access the path to this entry in the cache.
getEntryPath()281*9880d681SAndroid Build Coastguard Worker StringRef getEntryPath() { return EntryPath; }
282*9880d681SAndroid Build Coastguard Worker
283*9880d681SAndroid Build Coastguard Worker // Try loading the buffer for this cache entry.
tryLoadingBuffer()284*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<MemoryBuffer>> tryLoadingBuffer() {
285*9880d681SAndroid Build Coastguard Worker if (EntryPath.empty())
286*9880d681SAndroid Build Coastguard Worker return std::error_code();
287*9880d681SAndroid Build Coastguard Worker return MemoryBuffer::getFile(EntryPath);
288*9880d681SAndroid Build Coastguard Worker }
289*9880d681SAndroid Build Coastguard Worker
290*9880d681SAndroid Build Coastguard Worker // Cache the Produced object file
291*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MemoryBuffer>
write(std::unique_ptr<MemoryBuffer> OutputBuffer)292*9880d681SAndroid Build Coastguard Worker write(std::unique_ptr<MemoryBuffer> OutputBuffer) {
293*9880d681SAndroid Build Coastguard Worker if (EntryPath.empty())
294*9880d681SAndroid Build Coastguard Worker return OutputBuffer;
295*9880d681SAndroid Build Coastguard Worker
296*9880d681SAndroid Build Coastguard Worker // Write to a temporary to avoid race condition
297*9880d681SAndroid Build Coastguard Worker SmallString<128> TempFilename;
298*9880d681SAndroid Build Coastguard Worker int TempFD;
299*9880d681SAndroid Build Coastguard Worker std::error_code EC =
300*9880d681SAndroid Build Coastguard Worker sys::fs::createTemporaryFile("Thin", "tmp.o", TempFD, TempFilename);
301*9880d681SAndroid Build Coastguard Worker if (EC) {
302*9880d681SAndroid Build Coastguard Worker errs() << "Error: " << EC.message() << "\n";
303*9880d681SAndroid Build Coastguard Worker report_fatal_error("ThinLTO: Can't get a temporary file");
304*9880d681SAndroid Build Coastguard Worker }
305*9880d681SAndroid Build Coastguard Worker {
306*9880d681SAndroid Build Coastguard Worker raw_fd_ostream OS(TempFD, /* ShouldClose */ true);
307*9880d681SAndroid Build Coastguard Worker OS << OutputBuffer->getBuffer();
308*9880d681SAndroid Build Coastguard Worker }
309*9880d681SAndroid Build Coastguard Worker // Rename to final destination (hopefully race condition won't matter here)
310*9880d681SAndroid Build Coastguard Worker EC = sys::fs::rename(TempFilename, EntryPath);
311*9880d681SAndroid Build Coastguard Worker if (EC) {
312*9880d681SAndroid Build Coastguard Worker sys::fs::remove(TempFilename);
313*9880d681SAndroid Build Coastguard Worker raw_fd_ostream OS(EntryPath, EC, sys::fs::F_None);
314*9880d681SAndroid Build Coastguard Worker if (EC)
315*9880d681SAndroid Build Coastguard Worker report_fatal_error(Twine("Failed to open ") + EntryPath +
316*9880d681SAndroid Build Coastguard Worker " to save cached entry\n");
317*9880d681SAndroid Build Coastguard Worker OS << OutputBuffer->getBuffer();
318*9880d681SAndroid Build Coastguard Worker }
319*9880d681SAndroid Build Coastguard Worker auto ReloadedBufferOrErr = MemoryBuffer::getFile(EntryPath);
320*9880d681SAndroid Build Coastguard Worker if (auto EC = ReloadedBufferOrErr.getError()) {
321*9880d681SAndroid Build Coastguard Worker // FIXME diagnose
322*9880d681SAndroid Build Coastguard Worker errs() << "error: can't reload cached file '" << EntryPath
323*9880d681SAndroid Build Coastguard Worker << "': " << EC.message() << "\n";
324*9880d681SAndroid Build Coastguard Worker return OutputBuffer;
325*9880d681SAndroid Build Coastguard Worker }
326*9880d681SAndroid Build Coastguard Worker return std::move(*ReloadedBufferOrErr);
327*9880d681SAndroid Build Coastguard Worker }
328*9880d681SAndroid Build Coastguard Worker };
329*9880d681SAndroid Build Coastguard Worker
330*9880d681SAndroid Build Coastguard Worker static std::unique_ptr<MemoryBuffer>
ProcessThinLTOModule(Module & TheModule,ModuleSummaryIndex & Index,StringMap<MemoryBufferRef> & ModuleMap,TargetMachine & TM,const FunctionImporter::ImportMapTy & ImportList,const FunctionImporter::ExportSetTy & ExportList,const DenseSet<GlobalValue::GUID> & GUIDPreservedSymbols,const GVSummaryMapTy & DefinedGlobals,const ThinLTOCodeGenerator::CachingOptions & CacheOptions,bool DisableCodeGen,StringRef SaveTempsDir,unsigned count)331*9880d681SAndroid Build Coastguard Worker ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index,
332*9880d681SAndroid Build Coastguard Worker StringMap<MemoryBufferRef> &ModuleMap, TargetMachine &TM,
333*9880d681SAndroid Build Coastguard Worker const FunctionImporter::ImportMapTy &ImportList,
334*9880d681SAndroid Build Coastguard Worker const FunctionImporter::ExportSetTy &ExportList,
335*9880d681SAndroid Build Coastguard Worker const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
336*9880d681SAndroid Build Coastguard Worker const GVSummaryMapTy &DefinedGlobals,
337*9880d681SAndroid Build Coastguard Worker const ThinLTOCodeGenerator::CachingOptions &CacheOptions,
338*9880d681SAndroid Build Coastguard Worker bool DisableCodeGen, StringRef SaveTempsDir,
339*9880d681SAndroid Build Coastguard Worker unsigned count) {
340*9880d681SAndroid Build Coastguard Worker
341*9880d681SAndroid Build Coastguard Worker // "Benchmark"-like optimization: single-source case
342*9880d681SAndroid Build Coastguard Worker bool SingleModule = (ModuleMap.size() == 1);
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker if (!SingleModule) {
345*9880d681SAndroid Build Coastguard Worker promoteModule(TheModule, Index);
346*9880d681SAndroid Build Coastguard Worker
347*9880d681SAndroid Build Coastguard Worker // Apply summary-based LinkOnce/Weak resolution decisions.
348*9880d681SAndroid Build Coastguard Worker thinLTOResolveWeakForLinkerModule(TheModule, DefinedGlobals);
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker // Save temps: after promotion.
351*9880d681SAndroid Build Coastguard Worker saveTempBitcode(TheModule, SaveTempsDir, count, ".1.promoted.bc");
352*9880d681SAndroid Build Coastguard Worker }
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Worker // Be friendly and don't nuke totally the module when the client didn't
355*9880d681SAndroid Build Coastguard Worker // supply anything to preserve.
356*9880d681SAndroid Build Coastguard Worker if (!ExportList.empty() || !GUIDPreservedSymbols.empty()) {
357*9880d681SAndroid Build Coastguard Worker // Apply summary-based internalization decisions.
358*9880d681SAndroid Build Coastguard Worker thinLTOInternalizeModule(TheModule, DefinedGlobals);
359*9880d681SAndroid Build Coastguard Worker }
360*9880d681SAndroid Build Coastguard Worker
361*9880d681SAndroid Build Coastguard Worker // Save internalized bitcode
362*9880d681SAndroid Build Coastguard Worker saveTempBitcode(TheModule, SaveTempsDir, count, ".2.internalized.bc");
363*9880d681SAndroid Build Coastguard Worker
364*9880d681SAndroid Build Coastguard Worker if (!SingleModule) {
365*9880d681SAndroid Build Coastguard Worker crossImportIntoModule(TheModule, Index, ModuleMap, ImportList);
366*9880d681SAndroid Build Coastguard Worker
367*9880d681SAndroid Build Coastguard Worker // Save temps: after cross-module import.
368*9880d681SAndroid Build Coastguard Worker saveTempBitcode(TheModule, SaveTempsDir, count, ".3.imported.bc");
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker
371*9880d681SAndroid Build Coastguard Worker optimizeModule(TheModule, TM);
372*9880d681SAndroid Build Coastguard Worker
373*9880d681SAndroid Build Coastguard Worker saveTempBitcode(TheModule, SaveTempsDir, count, ".4.opt.bc");
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker if (DisableCodeGen) {
376*9880d681SAndroid Build Coastguard Worker // Configured to stop before CodeGen, serialize the bitcode and return.
377*9880d681SAndroid Build Coastguard Worker SmallVector<char, 128> OutputBuffer;
378*9880d681SAndroid Build Coastguard Worker {
379*9880d681SAndroid Build Coastguard Worker raw_svector_ostream OS(OutputBuffer);
380*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndexBuilder IndexBuilder(&TheModule);
381*9880d681SAndroid Build Coastguard Worker WriteBitcodeToFile(&TheModule, OS, true, &IndexBuilder.getIndex());
382*9880d681SAndroid Build Coastguard Worker }
383*9880d681SAndroid Build Coastguard Worker return make_unique<ObjectMemoryBuffer>(std::move(OutputBuffer));
384*9880d681SAndroid Build Coastguard Worker }
385*9880d681SAndroid Build Coastguard Worker
386*9880d681SAndroid Build Coastguard Worker return codegenModule(TheModule, TM);
387*9880d681SAndroid Build Coastguard Worker }
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Worker /// Resolve LinkOnce/Weak symbols. Record resolutions in the \p ResolvedODR map
390*9880d681SAndroid Build Coastguard Worker /// for caching, and in the \p Index for application during the ThinLTO
391*9880d681SAndroid Build Coastguard Worker /// backends. This is needed for correctness for exported symbols (ensure
392*9880d681SAndroid Build Coastguard Worker /// at least one copy kept) and a compile-time optimization (to drop duplicate
393*9880d681SAndroid Build Coastguard Worker /// copies when possible).
resolveWeakForLinkerInIndex(ModuleSummaryIndex & Index,StringMap<std::map<GlobalValue::GUID,GlobalValue::LinkageTypes>> & ResolvedODR)394*9880d681SAndroid Build Coastguard Worker static void resolveWeakForLinkerInIndex(
395*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndex &Index,
396*9880d681SAndroid Build Coastguard Worker StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>>
397*9880d681SAndroid Build Coastguard Worker &ResolvedODR) {
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Worker DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
400*9880d681SAndroid Build Coastguard Worker computePrevailingCopies(Index, PrevailingCopy);
401*9880d681SAndroid Build Coastguard Worker
402*9880d681SAndroid Build Coastguard Worker auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
403*9880d681SAndroid Build Coastguard Worker const auto &Prevailing = PrevailingCopy.find(GUID);
404*9880d681SAndroid Build Coastguard Worker // Not in map means that there was only one copy, which must be prevailing.
405*9880d681SAndroid Build Coastguard Worker if (Prevailing == PrevailingCopy.end())
406*9880d681SAndroid Build Coastguard Worker return true;
407*9880d681SAndroid Build Coastguard Worker return Prevailing->second == S;
408*9880d681SAndroid Build Coastguard Worker };
409*9880d681SAndroid Build Coastguard Worker
410*9880d681SAndroid Build Coastguard Worker auto recordNewLinkage = [&](StringRef ModuleIdentifier,
411*9880d681SAndroid Build Coastguard Worker GlobalValue::GUID GUID,
412*9880d681SAndroid Build Coastguard Worker GlobalValue::LinkageTypes NewLinkage) {
413*9880d681SAndroid Build Coastguard Worker ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
414*9880d681SAndroid Build Coastguard Worker };
415*9880d681SAndroid Build Coastguard Worker
416*9880d681SAndroid Build Coastguard Worker thinLTOResolveWeakForLinkerInIndex(Index, isPrevailing, recordNewLinkage);
417*9880d681SAndroid Build Coastguard Worker }
418*9880d681SAndroid Build Coastguard Worker
419*9880d681SAndroid Build Coastguard Worker // Initialize the TargetMachine builder for a given Triple
initTMBuilder(TargetMachineBuilder & TMBuilder,const Triple & TheTriple)420*9880d681SAndroid Build Coastguard Worker static void initTMBuilder(TargetMachineBuilder &TMBuilder,
421*9880d681SAndroid Build Coastguard Worker const Triple &TheTriple) {
422*9880d681SAndroid Build Coastguard Worker // Set a default CPU for Darwin triples (copied from LTOCodeGenerator).
423*9880d681SAndroid Build Coastguard Worker // FIXME this looks pretty terrible...
424*9880d681SAndroid Build Coastguard Worker if (TMBuilder.MCpu.empty() && TheTriple.isOSDarwin()) {
425*9880d681SAndroid Build Coastguard Worker if (TheTriple.getArch() == llvm::Triple::x86_64)
426*9880d681SAndroid Build Coastguard Worker TMBuilder.MCpu = "core2";
427*9880d681SAndroid Build Coastguard Worker else if (TheTriple.getArch() == llvm::Triple::x86)
428*9880d681SAndroid Build Coastguard Worker TMBuilder.MCpu = "yonah";
429*9880d681SAndroid Build Coastguard Worker else if (TheTriple.getArch() == llvm::Triple::aarch64)
430*9880d681SAndroid Build Coastguard Worker TMBuilder.MCpu = "cyclone";
431*9880d681SAndroid Build Coastguard Worker }
432*9880d681SAndroid Build Coastguard Worker TMBuilder.TheTriple = std::move(TheTriple);
433*9880d681SAndroid Build Coastguard Worker }
434*9880d681SAndroid Build Coastguard Worker
435*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
436*9880d681SAndroid Build Coastguard Worker
addModule(StringRef Identifier,StringRef Data)437*9880d681SAndroid Build Coastguard Worker void ThinLTOCodeGenerator::addModule(StringRef Identifier, StringRef Data) {
438*9880d681SAndroid Build Coastguard Worker MemoryBufferRef Buffer(Data, Identifier);
439*9880d681SAndroid Build Coastguard Worker if (Modules.empty()) {
440*9880d681SAndroid Build Coastguard Worker // First module added, so initialize the triple and some options
441*9880d681SAndroid Build Coastguard Worker LLVMContext Context;
442*9880d681SAndroid Build Coastguard Worker Triple TheTriple(getBitcodeTargetTriple(Buffer, Context));
443*9880d681SAndroid Build Coastguard Worker initTMBuilder(TMBuilder, Triple(TheTriple));
444*9880d681SAndroid Build Coastguard Worker }
445*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
446*9880d681SAndroid Build Coastguard Worker else {
447*9880d681SAndroid Build Coastguard Worker LLVMContext Context;
448*9880d681SAndroid Build Coastguard Worker assert(TMBuilder.TheTriple.str() ==
449*9880d681SAndroid Build Coastguard Worker getBitcodeTargetTriple(Buffer, Context) &&
450*9880d681SAndroid Build Coastguard Worker "ThinLTO modules with different triple not supported");
451*9880d681SAndroid Build Coastguard Worker }
452*9880d681SAndroid Build Coastguard Worker #endif
453*9880d681SAndroid Build Coastguard Worker Modules.push_back(Buffer);
454*9880d681SAndroid Build Coastguard Worker }
455*9880d681SAndroid Build Coastguard Worker
preserveSymbol(StringRef Name)456*9880d681SAndroid Build Coastguard Worker void ThinLTOCodeGenerator::preserveSymbol(StringRef Name) {
457*9880d681SAndroid Build Coastguard Worker PreservedSymbols.insert(Name);
458*9880d681SAndroid Build Coastguard Worker }
459*9880d681SAndroid Build Coastguard Worker
crossReferenceSymbol(StringRef Name)460*9880d681SAndroid Build Coastguard Worker void ThinLTOCodeGenerator::crossReferenceSymbol(StringRef Name) {
461*9880d681SAndroid Build Coastguard Worker // FIXME: At the moment, we don't take advantage of this extra information,
462*9880d681SAndroid Build Coastguard Worker // we're conservatively considering cross-references as preserved.
463*9880d681SAndroid Build Coastguard Worker // CrossReferencedSymbols.insert(Name);
464*9880d681SAndroid Build Coastguard Worker PreservedSymbols.insert(Name);
465*9880d681SAndroid Build Coastguard Worker }
466*9880d681SAndroid Build Coastguard Worker
467*9880d681SAndroid Build Coastguard Worker // TargetMachine factory
create() const468*9880d681SAndroid Build Coastguard Worker std::unique_ptr<TargetMachine> TargetMachineBuilder::create() const {
469*9880d681SAndroid Build Coastguard Worker std::string ErrMsg;
470*9880d681SAndroid Build Coastguard Worker const Target *TheTarget =
471*9880d681SAndroid Build Coastguard Worker TargetRegistry::lookupTarget(TheTriple.str(), ErrMsg);
472*9880d681SAndroid Build Coastguard Worker if (!TheTarget) {
473*9880d681SAndroid Build Coastguard Worker report_fatal_error("Can't load target for this Triple: " + ErrMsg);
474*9880d681SAndroid Build Coastguard Worker }
475*9880d681SAndroid Build Coastguard Worker
476*9880d681SAndroid Build Coastguard Worker // Use MAttr as the default set of features.
477*9880d681SAndroid Build Coastguard Worker SubtargetFeatures Features(MAttr);
478*9880d681SAndroid Build Coastguard Worker Features.getDefaultSubtargetFeatures(TheTriple);
479*9880d681SAndroid Build Coastguard Worker std::string FeatureStr = Features.getString();
480*9880d681SAndroid Build Coastguard Worker return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
481*9880d681SAndroid Build Coastguard Worker TheTriple.str(), MCpu, FeatureStr, Options, RelocModel,
482*9880d681SAndroid Build Coastguard Worker CodeModel::Default, CGOptLevel));
483*9880d681SAndroid Build Coastguard Worker }
484*9880d681SAndroid Build Coastguard Worker
485*9880d681SAndroid Build Coastguard Worker /**
486*9880d681SAndroid Build Coastguard Worker * Produce the combined summary index from all the bitcode files:
487*9880d681SAndroid Build Coastguard Worker * "thin-link".
488*9880d681SAndroid Build Coastguard Worker */
linkCombinedIndex()489*9880d681SAndroid Build Coastguard Worker std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
490*9880d681SAndroid Build Coastguard Worker std::unique_ptr<ModuleSummaryIndex> CombinedIndex;
491*9880d681SAndroid Build Coastguard Worker uint64_t NextModuleId = 0;
492*9880d681SAndroid Build Coastguard Worker for (auto &ModuleBuffer : Modules) {
493*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
494*9880d681SAndroid Build Coastguard Worker object::ModuleSummaryIndexObjectFile::create(ModuleBuffer,
495*9880d681SAndroid Build Coastguard Worker diagnosticHandler);
496*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = ObjOrErr.getError()) {
497*9880d681SAndroid Build Coastguard Worker // FIXME diagnose
498*9880d681SAndroid Build Coastguard Worker errs() << "error: can't create ModuleSummaryIndexObjectFile for buffer: "
499*9880d681SAndroid Build Coastguard Worker << EC.message() << "\n";
500*9880d681SAndroid Build Coastguard Worker return nullptr;
501*9880d681SAndroid Build Coastguard Worker }
502*9880d681SAndroid Build Coastguard Worker auto Index = (*ObjOrErr)->takeIndex();
503*9880d681SAndroid Build Coastguard Worker if (CombinedIndex) {
504*9880d681SAndroid Build Coastguard Worker CombinedIndex->mergeFrom(std::move(Index), ++NextModuleId);
505*9880d681SAndroid Build Coastguard Worker } else {
506*9880d681SAndroid Build Coastguard Worker CombinedIndex = std::move(Index);
507*9880d681SAndroid Build Coastguard Worker }
508*9880d681SAndroid Build Coastguard Worker }
509*9880d681SAndroid Build Coastguard Worker return CombinedIndex;
510*9880d681SAndroid Build Coastguard Worker }
511*9880d681SAndroid Build Coastguard Worker
512*9880d681SAndroid Build Coastguard Worker /**
513*9880d681SAndroid Build Coastguard Worker * Perform promotion and renaming of exported internal functions.
514*9880d681SAndroid Build Coastguard Worker * Index is updated to reflect linkage changes from weak resolution.
515*9880d681SAndroid Build Coastguard Worker */
promote(Module & TheModule,ModuleSummaryIndex & Index)516*9880d681SAndroid Build Coastguard Worker void ThinLTOCodeGenerator::promote(Module &TheModule,
517*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndex &Index) {
518*9880d681SAndroid Build Coastguard Worker auto ModuleCount = Index.modulePaths().size();
519*9880d681SAndroid Build Coastguard Worker auto ModuleIdentifier = TheModule.getModuleIdentifier();
520*9880d681SAndroid Build Coastguard Worker // Collect for each module the list of function it defines (GUID -> Summary).
521*9880d681SAndroid Build Coastguard Worker StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
522*9880d681SAndroid Build Coastguard Worker Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
523*9880d681SAndroid Build Coastguard Worker
524*9880d681SAndroid Build Coastguard Worker // Generate import/export list
525*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
526*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
527*9880d681SAndroid Build Coastguard Worker ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
528*9880d681SAndroid Build Coastguard Worker ExportLists);
529*9880d681SAndroid Build Coastguard Worker
530*9880d681SAndroid Build Coastguard Worker // Resolve LinkOnce/Weak symbols.
531*9880d681SAndroid Build Coastguard Worker StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
532*9880d681SAndroid Build Coastguard Worker resolveWeakForLinkerInIndex(Index, ResolvedODR);
533*9880d681SAndroid Build Coastguard Worker
534*9880d681SAndroid Build Coastguard Worker thinLTOResolveWeakForLinkerModule(
535*9880d681SAndroid Build Coastguard Worker TheModule, ModuleToDefinedGVSummaries[ModuleIdentifier]);
536*9880d681SAndroid Build Coastguard Worker
537*9880d681SAndroid Build Coastguard Worker promoteModule(TheModule, Index);
538*9880d681SAndroid Build Coastguard Worker }
539*9880d681SAndroid Build Coastguard Worker
540*9880d681SAndroid Build Coastguard Worker /**
541*9880d681SAndroid Build Coastguard Worker * Perform cross-module importing for the module identified by ModuleIdentifier.
542*9880d681SAndroid Build Coastguard Worker */
crossModuleImport(Module & TheModule,ModuleSummaryIndex & Index)543*9880d681SAndroid Build Coastguard Worker void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
544*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndex &Index) {
545*9880d681SAndroid Build Coastguard Worker auto ModuleMap = generateModuleMap(Modules);
546*9880d681SAndroid Build Coastguard Worker auto ModuleCount = Index.modulePaths().size();
547*9880d681SAndroid Build Coastguard Worker
548*9880d681SAndroid Build Coastguard Worker // Collect for each module the list of function it defines (GUID -> Summary).
549*9880d681SAndroid Build Coastguard Worker StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
550*9880d681SAndroid Build Coastguard Worker Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
551*9880d681SAndroid Build Coastguard Worker
552*9880d681SAndroid Build Coastguard Worker // Generate import/export list
553*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
554*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
555*9880d681SAndroid Build Coastguard Worker ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
556*9880d681SAndroid Build Coastguard Worker ExportLists);
557*9880d681SAndroid Build Coastguard Worker auto &ImportList = ImportLists[TheModule.getModuleIdentifier()];
558*9880d681SAndroid Build Coastguard Worker
559*9880d681SAndroid Build Coastguard Worker crossImportIntoModule(TheModule, Index, ModuleMap, ImportList);
560*9880d681SAndroid Build Coastguard Worker }
561*9880d681SAndroid Build Coastguard Worker
562*9880d681SAndroid Build Coastguard Worker /**
563*9880d681SAndroid Build Coastguard Worker * Compute the list of summaries needed for importing into module.
564*9880d681SAndroid Build Coastguard Worker */
gatherImportedSummariesForModule(StringRef ModulePath,ModuleSummaryIndex & Index,std::map<std::string,GVSummaryMapTy> & ModuleToSummariesForIndex)565*9880d681SAndroid Build Coastguard Worker void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
566*9880d681SAndroid Build Coastguard Worker StringRef ModulePath, ModuleSummaryIndex &Index,
567*9880d681SAndroid Build Coastguard Worker std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
568*9880d681SAndroid Build Coastguard Worker auto ModuleCount = Index.modulePaths().size();
569*9880d681SAndroid Build Coastguard Worker
570*9880d681SAndroid Build Coastguard Worker // Collect for each module the list of function it defines (GUID -> Summary).
571*9880d681SAndroid Build Coastguard Worker StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
572*9880d681SAndroid Build Coastguard Worker Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
573*9880d681SAndroid Build Coastguard Worker
574*9880d681SAndroid Build Coastguard Worker // Generate import/export list
575*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
576*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
577*9880d681SAndroid Build Coastguard Worker ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
578*9880d681SAndroid Build Coastguard Worker ExportLists);
579*9880d681SAndroid Build Coastguard Worker
580*9880d681SAndroid Build Coastguard Worker llvm::gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,
581*9880d681SAndroid Build Coastguard Worker ImportLists,
582*9880d681SAndroid Build Coastguard Worker ModuleToSummariesForIndex);
583*9880d681SAndroid Build Coastguard Worker }
584*9880d681SAndroid Build Coastguard Worker
585*9880d681SAndroid Build Coastguard Worker /**
586*9880d681SAndroid Build Coastguard Worker * Emit the list of files needed for importing into module.
587*9880d681SAndroid Build Coastguard Worker */
emitImports(StringRef ModulePath,StringRef OutputName,ModuleSummaryIndex & Index)588*9880d681SAndroid Build Coastguard Worker void ThinLTOCodeGenerator::emitImports(StringRef ModulePath,
589*9880d681SAndroid Build Coastguard Worker StringRef OutputName,
590*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndex &Index) {
591*9880d681SAndroid Build Coastguard Worker auto ModuleCount = Index.modulePaths().size();
592*9880d681SAndroid Build Coastguard Worker
593*9880d681SAndroid Build Coastguard Worker // Collect for each module the list of function it defines (GUID -> Summary).
594*9880d681SAndroid Build Coastguard Worker StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
595*9880d681SAndroid Build Coastguard Worker Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
596*9880d681SAndroid Build Coastguard Worker
597*9880d681SAndroid Build Coastguard Worker // Generate import/export list
598*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
599*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
600*9880d681SAndroid Build Coastguard Worker ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
601*9880d681SAndroid Build Coastguard Worker ExportLists);
602*9880d681SAndroid Build Coastguard Worker
603*9880d681SAndroid Build Coastguard Worker std::error_code EC;
604*9880d681SAndroid Build Coastguard Worker if ((EC = EmitImportsFiles(ModulePath, OutputName, ImportLists)))
605*9880d681SAndroid Build Coastguard Worker report_fatal_error(Twine("Failed to open ") + OutputName +
606*9880d681SAndroid Build Coastguard Worker " to save imports lists\n");
607*9880d681SAndroid Build Coastguard Worker }
608*9880d681SAndroid Build Coastguard Worker
609*9880d681SAndroid Build Coastguard Worker /**
610*9880d681SAndroid Build Coastguard Worker * Perform internalization. Index is updated to reflect linkage changes.
611*9880d681SAndroid Build Coastguard Worker */
internalize(Module & TheModule,ModuleSummaryIndex & Index)612*9880d681SAndroid Build Coastguard Worker void ThinLTOCodeGenerator::internalize(Module &TheModule,
613*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndex &Index) {
614*9880d681SAndroid Build Coastguard Worker initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
615*9880d681SAndroid Build Coastguard Worker auto ModuleCount = Index.modulePaths().size();
616*9880d681SAndroid Build Coastguard Worker auto ModuleIdentifier = TheModule.getModuleIdentifier();
617*9880d681SAndroid Build Coastguard Worker
618*9880d681SAndroid Build Coastguard Worker // Convert the preserved symbols set from string to GUID
619*9880d681SAndroid Build Coastguard Worker auto GUIDPreservedSymbols =
620*9880d681SAndroid Build Coastguard Worker computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
621*9880d681SAndroid Build Coastguard Worker
622*9880d681SAndroid Build Coastguard Worker // Collect for each module the list of function it defines (GUID -> Summary).
623*9880d681SAndroid Build Coastguard Worker StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
624*9880d681SAndroid Build Coastguard Worker Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
625*9880d681SAndroid Build Coastguard Worker
626*9880d681SAndroid Build Coastguard Worker // Generate import/export list
627*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
628*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
629*9880d681SAndroid Build Coastguard Worker ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
630*9880d681SAndroid Build Coastguard Worker ExportLists);
631*9880d681SAndroid Build Coastguard Worker auto &ExportList = ExportLists[ModuleIdentifier];
632*9880d681SAndroid Build Coastguard Worker
633*9880d681SAndroid Build Coastguard Worker // Be friendly and don't nuke totally the module when the client didn't
634*9880d681SAndroid Build Coastguard Worker // supply anything to preserve.
635*9880d681SAndroid Build Coastguard Worker if (ExportList.empty() && GUIDPreservedSymbols.empty())
636*9880d681SAndroid Build Coastguard Worker return;
637*9880d681SAndroid Build Coastguard Worker
638*9880d681SAndroid Build Coastguard Worker // Internalization
639*9880d681SAndroid Build Coastguard Worker auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
640*9880d681SAndroid Build Coastguard Worker const auto &ExportList = ExportLists.find(ModuleIdentifier);
641*9880d681SAndroid Build Coastguard Worker return (ExportList != ExportLists.end() &&
642*9880d681SAndroid Build Coastguard Worker ExportList->second.count(GUID)) ||
643*9880d681SAndroid Build Coastguard Worker GUIDPreservedSymbols.count(GUID);
644*9880d681SAndroid Build Coastguard Worker };
645*9880d681SAndroid Build Coastguard Worker thinLTOInternalizeAndPromoteInIndex(Index, isExported);
646*9880d681SAndroid Build Coastguard Worker thinLTOInternalizeModule(TheModule,
647*9880d681SAndroid Build Coastguard Worker ModuleToDefinedGVSummaries[ModuleIdentifier]);
648*9880d681SAndroid Build Coastguard Worker }
649*9880d681SAndroid Build Coastguard Worker
650*9880d681SAndroid Build Coastguard Worker /**
651*9880d681SAndroid Build Coastguard Worker * Perform post-importing ThinLTO optimizations.
652*9880d681SAndroid Build Coastguard Worker */
optimize(Module & TheModule)653*9880d681SAndroid Build Coastguard Worker void ThinLTOCodeGenerator::optimize(Module &TheModule) {
654*9880d681SAndroid Build Coastguard Worker initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
655*9880d681SAndroid Build Coastguard Worker
656*9880d681SAndroid Build Coastguard Worker // Optimize now
657*9880d681SAndroid Build Coastguard Worker optimizeModule(TheModule, *TMBuilder.create());
658*9880d681SAndroid Build Coastguard Worker }
659*9880d681SAndroid Build Coastguard Worker
660*9880d681SAndroid Build Coastguard Worker /**
661*9880d681SAndroid Build Coastguard Worker * Perform ThinLTO CodeGen.
662*9880d681SAndroid Build Coastguard Worker */
codegen(Module & TheModule)663*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MemoryBuffer> ThinLTOCodeGenerator::codegen(Module &TheModule) {
664*9880d681SAndroid Build Coastguard Worker initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
665*9880d681SAndroid Build Coastguard Worker return codegenModule(TheModule, *TMBuilder.create());
666*9880d681SAndroid Build Coastguard Worker }
667*9880d681SAndroid Build Coastguard Worker
668*9880d681SAndroid Build Coastguard Worker // Main entry point for the ThinLTO processing
run()669*9880d681SAndroid Build Coastguard Worker void ThinLTOCodeGenerator::run() {
670*9880d681SAndroid Build Coastguard Worker if (CodeGenOnly) {
671*9880d681SAndroid Build Coastguard Worker // Perform only parallel codegen and return.
672*9880d681SAndroid Build Coastguard Worker ThreadPool Pool;
673*9880d681SAndroid Build Coastguard Worker assert(ProducedBinaries.empty() && "The generator should not be reused");
674*9880d681SAndroid Build Coastguard Worker ProducedBinaries.resize(Modules.size());
675*9880d681SAndroid Build Coastguard Worker int count = 0;
676*9880d681SAndroid Build Coastguard Worker for (auto &ModuleBuffer : Modules) {
677*9880d681SAndroid Build Coastguard Worker Pool.async([&](int count) {
678*9880d681SAndroid Build Coastguard Worker LLVMContext Context;
679*9880d681SAndroid Build Coastguard Worker Context.setDiscardValueNames(LTODiscardValueNames);
680*9880d681SAndroid Build Coastguard Worker
681*9880d681SAndroid Build Coastguard Worker // Parse module now
682*9880d681SAndroid Build Coastguard Worker auto TheModule = loadModuleFromBuffer(ModuleBuffer, Context, false);
683*9880d681SAndroid Build Coastguard Worker
684*9880d681SAndroid Build Coastguard Worker // CodeGen
685*9880d681SAndroid Build Coastguard Worker ProducedBinaries[count] = codegen(*TheModule);
686*9880d681SAndroid Build Coastguard Worker }, count++);
687*9880d681SAndroid Build Coastguard Worker }
688*9880d681SAndroid Build Coastguard Worker
689*9880d681SAndroid Build Coastguard Worker return;
690*9880d681SAndroid Build Coastguard Worker }
691*9880d681SAndroid Build Coastguard Worker
692*9880d681SAndroid Build Coastguard Worker // Sequential linking phase
693*9880d681SAndroid Build Coastguard Worker auto Index = linkCombinedIndex();
694*9880d681SAndroid Build Coastguard Worker
695*9880d681SAndroid Build Coastguard Worker // Save temps: index.
696*9880d681SAndroid Build Coastguard Worker if (!SaveTempsDir.empty()) {
697*9880d681SAndroid Build Coastguard Worker auto SaveTempPath = SaveTempsDir + "index.bc";
698*9880d681SAndroid Build Coastguard Worker std::error_code EC;
699*9880d681SAndroid Build Coastguard Worker raw_fd_ostream OS(SaveTempPath, EC, sys::fs::F_None);
700*9880d681SAndroid Build Coastguard Worker if (EC)
701*9880d681SAndroid Build Coastguard Worker report_fatal_error(Twine("Failed to open ") + SaveTempPath +
702*9880d681SAndroid Build Coastguard Worker " to save optimized bitcode\n");
703*9880d681SAndroid Build Coastguard Worker WriteIndexToFile(*Index, OS);
704*9880d681SAndroid Build Coastguard Worker }
705*9880d681SAndroid Build Coastguard Worker
706*9880d681SAndroid Build Coastguard Worker // Prepare the resulting object vector
707*9880d681SAndroid Build Coastguard Worker assert(ProducedBinaries.empty() && "The generator should not be reused");
708*9880d681SAndroid Build Coastguard Worker ProducedBinaries.resize(Modules.size());
709*9880d681SAndroid Build Coastguard Worker
710*9880d681SAndroid Build Coastguard Worker // Prepare the module map.
711*9880d681SAndroid Build Coastguard Worker auto ModuleMap = generateModuleMap(Modules);
712*9880d681SAndroid Build Coastguard Worker auto ModuleCount = Modules.size();
713*9880d681SAndroid Build Coastguard Worker
714*9880d681SAndroid Build Coastguard Worker // Collect for each module the list of function it defines (GUID -> Summary).
715*9880d681SAndroid Build Coastguard Worker StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
716*9880d681SAndroid Build Coastguard Worker Index->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
717*9880d681SAndroid Build Coastguard Worker
718*9880d681SAndroid Build Coastguard Worker // Collect the import/export lists for all modules from the call-graph in the
719*9880d681SAndroid Build Coastguard Worker // combined index.
720*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
721*9880d681SAndroid Build Coastguard Worker StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
722*9880d681SAndroid Build Coastguard Worker ComputeCrossModuleImport(*Index, ModuleToDefinedGVSummaries, ImportLists,
723*9880d681SAndroid Build Coastguard Worker ExportLists);
724*9880d681SAndroid Build Coastguard Worker
725*9880d681SAndroid Build Coastguard Worker // Convert the preserved symbols set from string to GUID, this is needed for
726*9880d681SAndroid Build Coastguard Worker // computing the caching hash and the internalization.
727*9880d681SAndroid Build Coastguard Worker auto GUIDPreservedSymbols =
728*9880d681SAndroid Build Coastguard Worker computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
729*9880d681SAndroid Build Coastguard Worker
730*9880d681SAndroid Build Coastguard Worker // We use a std::map here to be able to have a defined ordering when
731*9880d681SAndroid Build Coastguard Worker // producing a hash for the cache entry.
732*9880d681SAndroid Build Coastguard Worker // FIXME: we should be able to compute the caching hash for the entry based
733*9880d681SAndroid Build Coastguard Worker // on the index, and nuke this map.
734*9880d681SAndroid Build Coastguard Worker StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
735*9880d681SAndroid Build Coastguard Worker
736*9880d681SAndroid Build Coastguard Worker // Resolve LinkOnce/Weak symbols, this has to be computed early because it
737*9880d681SAndroid Build Coastguard Worker // impacts the caching.
738*9880d681SAndroid Build Coastguard Worker resolveWeakForLinkerInIndex(*Index, ResolvedODR);
739*9880d681SAndroid Build Coastguard Worker
740*9880d681SAndroid Build Coastguard Worker auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
741*9880d681SAndroid Build Coastguard Worker const auto &ExportList = ExportLists.find(ModuleIdentifier);
742*9880d681SAndroid Build Coastguard Worker return (ExportList != ExportLists.end() &&
743*9880d681SAndroid Build Coastguard Worker ExportList->second.count(GUID)) ||
744*9880d681SAndroid Build Coastguard Worker GUIDPreservedSymbols.count(GUID);
745*9880d681SAndroid Build Coastguard Worker };
746*9880d681SAndroid Build Coastguard Worker
747*9880d681SAndroid Build Coastguard Worker // Use global summary-based analysis to identify symbols that can be
748*9880d681SAndroid Build Coastguard Worker // internalized (because they aren't exported or preserved as per callback).
749*9880d681SAndroid Build Coastguard Worker // Changes are made in the index, consumed in the ThinLTO backends.
750*9880d681SAndroid Build Coastguard Worker thinLTOInternalizeAndPromoteInIndex(*Index, isExported);
751*9880d681SAndroid Build Coastguard Worker
752*9880d681SAndroid Build Coastguard Worker // Make sure that every module has an entry in the ExportLists and
753*9880d681SAndroid Build Coastguard Worker // ResolvedODR maps to enable threaded access to these maps below.
754*9880d681SAndroid Build Coastguard Worker for (auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
755*9880d681SAndroid Build Coastguard Worker ExportLists[DefinedGVSummaries.first()];
756*9880d681SAndroid Build Coastguard Worker ResolvedODR[DefinedGVSummaries.first()];
757*9880d681SAndroid Build Coastguard Worker }
758*9880d681SAndroid Build Coastguard Worker
759*9880d681SAndroid Build Coastguard Worker // Compute the ordering we will process the inputs: the rough heuristic here
760*9880d681SAndroid Build Coastguard Worker // is to sort them per size so that the largest module get schedule as soon as
761*9880d681SAndroid Build Coastguard Worker // possible. This is purely a compile-time optimization.
762*9880d681SAndroid Build Coastguard Worker std::vector<int> ModulesOrdering;
763*9880d681SAndroid Build Coastguard Worker ModulesOrdering.resize(Modules.size());
764*9880d681SAndroid Build Coastguard Worker std::iota(ModulesOrdering.begin(), ModulesOrdering.end(), 0);
765*9880d681SAndroid Build Coastguard Worker std::sort(ModulesOrdering.begin(), ModulesOrdering.end(),
766*9880d681SAndroid Build Coastguard Worker [&](int LeftIndex, int RightIndex) {
767*9880d681SAndroid Build Coastguard Worker auto LSize = Modules[LeftIndex].getBufferSize();
768*9880d681SAndroid Build Coastguard Worker auto RSize = Modules[RightIndex].getBufferSize();
769*9880d681SAndroid Build Coastguard Worker return LSize > RSize;
770*9880d681SAndroid Build Coastguard Worker });
771*9880d681SAndroid Build Coastguard Worker
772*9880d681SAndroid Build Coastguard Worker // Parallel optimizer + codegen
773*9880d681SAndroid Build Coastguard Worker {
774*9880d681SAndroid Build Coastguard Worker ThreadPool Pool(ThreadCount);
775*9880d681SAndroid Build Coastguard Worker for (auto IndexCount : ModulesOrdering) {
776*9880d681SAndroid Build Coastguard Worker auto &ModuleBuffer = Modules[IndexCount];
777*9880d681SAndroid Build Coastguard Worker Pool.async([&](int count) {
778*9880d681SAndroid Build Coastguard Worker auto ModuleIdentifier = ModuleBuffer.getBufferIdentifier();
779*9880d681SAndroid Build Coastguard Worker auto &ExportList = ExportLists[ModuleIdentifier];
780*9880d681SAndroid Build Coastguard Worker
781*9880d681SAndroid Build Coastguard Worker auto &DefinedFunctions = ModuleToDefinedGVSummaries[ModuleIdentifier];
782*9880d681SAndroid Build Coastguard Worker
783*9880d681SAndroid Build Coastguard Worker // The module may be cached, this helps handling it.
784*9880d681SAndroid Build Coastguard Worker ModuleCacheEntry CacheEntry(CacheOptions.Path, *Index, ModuleIdentifier,
785*9880d681SAndroid Build Coastguard Worker ImportLists[ModuleIdentifier], ExportList,
786*9880d681SAndroid Build Coastguard Worker ResolvedODR[ModuleIdentifier],
787*9880d681SAndroid Build Coastguard Worker DefinedFunctions, GUIDPreservedSymbols);
788*9880d681SAndroid Build Coastguard Worker
789*9880d681SAndroid Build Coastguard Worker {
790*9880d681SAndroid Build Coastguard Worker auto ErrOrBuffer = CacheEntry.tryLoadingBuffer();
791*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Cache " << (ErrOrBuffer ? "hit" : "miss") << " '"
792*9880d681SAndroid Build Coastguard Worker << CacheEntry.getEntryPath() << "' for buffer " << count
793*9880d681SAndroid Build Coastguard Worker << " " << ModuleIdentifier << "\n");
794*9880d681SAndroid Build Coastguard Worker
795*9880d681SAndroid Build Coastguard Worker if (ErrOrBuffer) {
796*9880d681SAndroid Build Coastguard Worker // Cache Hit!
797*9880d681SAndroid Build Coastguard Worker ProducedBinaries[count] = std::move(ErrOrBuffer.get());
798*9880d681SAndroid Build Coastguard Worker return;
799*9880d681SAndroid Build Coastguard Worker }
800*9880d681SAndroid Build Coastguard Worker }
801*9880d681SAndroid Build Coastguard Worker
802*9880d681SAndroid Build Coastguard Worker LLVMContext Context;
803*9880d681SAndroid Build Coastguard Worker Context.setDiscardValueNames(LTODiscardValueNames);
804*9880d681SAndroid Build Coastguard Worker Context.enableDebugTypeODRUniquing();
805*9880d681SAndroid Build Coastguard Worker
806*9880d681SAndroid Build Coastguard Worker // Parse module now
807*9880d681SAndroid Build Coastguard Worker auto TheModule = loadModuleFromBuffer(ModuleBuffer, Context, false);
808*9880d681SAndroid Build Coastguard Worker
809*9880d681SAndroid Build Coastguard Worker // Save temps: original file.
810*9880d681SAndroid Build Coastguard Worker saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc");
811*9880d681SAndroid Build Coastguard Worker
812*9880d681SAndroid Build Coastguard Worker auto &ImportList = ImportLists[ModuleIdentifier];
813*9880d681SAndroid Build Coastguard Worker // Run the main process now, and generates a binary
814*9880d681SAndroid Build Coastguard Worker auto OutputBuffer = ProcessThinLTOModule(
815*9880d681SAndroid Build Coastguard Worker *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList,
816*9880d681SAndroid Build Coastguard Worker ExportList, GUIDPreservedSymbols,
817*9880d681SAndroid Build Coastguard Worker ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions,
818*9880d681SAndroid Build Coastguard Worker DisableCodeGen, SaveTempsDir, count);
819*9880d681SAndroid Build Coastguard Worker
820*9880d681SAndroid Build Coastguard Worker OutputBuffer = CacheEntry.write(std::move(OutputBuffer));
821*9880d681SAndroid Build Coastguard Worker ProducedBinaries[count] = std::move(OutputBuffer);
822*9880d681SAndroid Build Coastguard Worker }, IndexCount);
823*9880d681SAndroid Build Coastguard Worker }
824*9880d681SAndroid Build Coastguard Worker }
825*9880d681SAndroid Build Coastguard Worker
826*9880d681SAndroid Build Coastguard Worker CachePruning(CacheOptions.Path)
827*9880d681SAndroid Build Coastguard Worker .setPruningInterval(CacheOptions.PruningInterval)
828*9880d681SAndroid Build Coastguard Worker .setEntryExpiration(CacheOptions.Expiration)
829*9880d681SAndroid Build Coastguard Worker .setMaxSize(CacheOptions.MaxPercentageOfAvailableSpace)
830*9880d681SAndroid Build Coastguard Worker .prune();
831*9880d681SAndroid Build Coastguard Worker
832*9880d681SAndroid Build Coastguard Worker // If statistics were requested, print them out now.
833*9880d681SAndroid Build Coastguard Worker if (llvm::AreStatisticsEnabled())
834*9880d681SAndroid Build Coastguard Worker llvm::PrintStatistics();
835*9880d681SAndroid Build Coastguard Worker }
836