1f785676fSDimitry Andric //===-LTOCodeGenerator.cpp - LLVM Link Time Optimizer ---------------------===//
2f785676fSDimitry Andric //
3f785676fSDimitry Andric //                     The LLVM Compiler Infrastructure
4f785676fSDimitry Andric //
5f785676fSDimitry Andric // This file is distributed under the University of Illinois Open Source
6f785676fSDimitry Andric // License. See LICENSE.TXT for details.
7f785676fSDimitry Andric //
8f785676fSDimitry Andric //===----------------------------------------------------------------------===//
9f785676fSDimitry Andric //
10f785676fSDimitry Andric // This file implements the Link Time Optimization library. This library is
11f785676fSDimitry Andric // intended to be used by linker to optimize code at link time.
12f785676fSDimitry Andric //
13f785676fSDimitry Andric //===----------------------------------------------------------------------===//
14f785676fSDimitry Andric 
15f785676fSDimitry Andric #include "llvm/LTO/LTOCodeGenerator.h"
16f785676fSDimitry Andric #include "llvm/ADT/StringExtras.h"
17f785676fSDimitry Andric #include "llvm/Analysis/Passes.h"
18f785676fSDimitry Andric #include "llvm/Bitcode/ReaderWriter.h"
19f785676fSDimitry Andric #include "llvm/CodeGen/RuntimeLibcalls.h"
20f785676fSDimitry Andric #include "llvm/Config/config.h"
21f785676fSDimitry Andric #include "llvm/IR/Constants.h"
22f785676fSDimitry Andric #include "llvm/IR/DataLayout.h"
23f785676fSDimitry Andric #include "llvm/IR/DerivedTypes.h"
2491bc56edSDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
2591bc56edSDimitry Andric #include "llvm/IR/DiagnosticPrinter.h"
26f785676fSDimitry Andric #include "llvm/IR/LLVMContext.h"
2791bc56edSDimitry Andric #include "llvm/IR/Mangler.h"
28f785676fSDimitry Andric #include "llvm/IR/Module.h"
2991bc56edSDimitry Andric #include "llvm/IR/Verifier.h"
30f785676fSDimitry Andric #include "llvm/InitializePasses.h"
3191bc56edSDimitry Andric #include "llvm/LTO/LTOModule.h"
3291bc56edSDimitry Andric #include "llvm/Linker/Linker.h"
33f785676fSDimitry Andric #include "llvm/MC/MCAsmInfo.h"
34f785676fSDimitry Andric #include "llvm/MC/MCContext.h"
35f785676fSDimitry Andric #include "llvm/MC/SubtargetFeature.h"
36f785676fSDimitry Andric #include "llvm/PassManager.h"
37f785676fSDimitry Andric #include "llvm/Support/CommandLine.h"
38f785676fSDimitry Andric #include "llvm/Support/FileSystem.h"
39f785676fSDimitry Andric #include "llvm/Support/FormattedStream.h"
40f785676fSDimitry Andric #include "llvm/Support/Host.h"
41f785676fSDimitry Andric #include "llvm/Support/MemoryBuffer.h"
42f785676fSDimitry Andric #include "llvm/Support/Signals.h"
43f785676fSDimitry Andric #include "llvm/Support/TargetRegistry.h"
44f785676fSDimitry Andric #include "llvm/Support/TargetSelect.h"
45f785676fSDimitry Andric #include "llvm/Support/ToolOutputFile.h"
4691bc56edSDimitry Andric #include "llvm/Support/raw_ostream.h"
47f785676fSDimitry Andric #include "llvm/Target/TargetLibraryInfo.h"
48f785676fSDimitry Andric #include "llvm/Target/TargetLowering.h"
49f785676fSDimitry Andric #include "llvm/Target/TargetOptions.h"
50f785676fSDimitry Andric #include "llvm/Target/TargetRegisterInfo.h"
51f785676fSDimitry Andric #include "llvm/Transforms/IPO.h"
52f785676fSDimitry Andric #include "llvm/Transforms/IPO/PassManagerBuilder.h"
53f785676fSDimitry Andric #include "llvm/Transforms/ObjCARC.h"
5491bc56edSDimitry Andric #include <system_error>
55f785676fSDimitry Andric using namespace llvm;
56f785676fSDimitry Andric 
57f785676fSDimitry Andric const char* LTOCodeGenerator::getVersionString() {
58f785676fSDimitry Andric #ifdef LLVM_VERSION_INFO
59f785676fSDimitry Andric   return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
60f785676fSDimitry Andric #else
61f785676fSDimitry Andric   return PACKAGE_NAME " version " PACKAGE_VERSION;
62f785676fSDimitry Andric #endif
63f785676fSDimitry Andric }
64f785676fSDimitry Andric 
65f785676fSDimitry Andric LTOCodeGenerator::LTOCodeGenerator()
6691bc56edSDimitry Andric     : Context(getGlobalContext()), IRLinker(new Module("ld-temp.o", Context)),
6791bc56edSDimitry Andric       TargetMach(nullptr), EmitDwarfDebugInfo(false),
6891bc56edSDimitry Andric       ScopeRestrictionsDone(false), CodeModel(LTO_CODEGEN_PIC_MODEL_DEFAULT),
6991bc56edSDimitry Andric       NativeObjectFile(nullptr), DiagHandler(nullptr), DiagContext(nullptr) {
70f785676fSDimitry Andric   initializeLTOPasses();
71f785676fSDimitry Andric }
72f785676fSDimitry Andric 
73f785676fSDimitry Andric LTOCodeGenerator::~LTOCodeGenerator() {
74f785676fSDimitry Andric   delete TargetMach;
75f785676fSDimitry Andric   delete NativeObjectFile;
7691bc56edSDimitry Andric   TargetMach = nullptr;
7791bc56edSDimitry Andric   NativeObjectFile = nullptr;
78f785676fSDimitry Andric 
7991bc56edSDimitry Andric   IRLinker.deleteModule();
80f785676fSDimitry Andric 
81f785676fSDimitry Andric   for (std::vector<char *>::iterator I = CodegenOptions.begin(),
82f785676fSDimitry Andric                                      E = CodegenOptions.end();
83f785676fSDimitry Andric        I != E; ++I)
84f785676fSDimitry Andric     free(*I);
85f785676fSDimitry Andric }
86f785676fSDimitry Andric 
87f785676fSDimitry Andric // Initialize LTO passes. Please keep this funciton in sync with
88f785676fSDimitry Andric // PassManagerBuilder::populateLTOPassManager(), and make sure all LTO
89f785676fSDimitry Andric // passes are initialized.
90f785676fSDimitry Andric void LTOCodeGenerator::initializeLTOPasses() {
91f785676fSDimitry Andric   PassRegistry &R = *PassRegistry::getPassRegistry();
92f785676fSDimitry Andric 
93f785676fSDimitry Andric   initializeInternalizePassPass(R);
94f785676fSDimitry Andric   initializeIPSCCPPass(R);
95f785676fSDimitry Andric   initializeGlobalOptPass(R);
96f785676fSDimitry Andric   initializeConstantMergePass(R);
97f785676fSDimitry Andric   initializeDAHPass(R);
98f785676fSDimitry Andric   initializeInstCombinerPass(R);
99f785676fSDimitry Andric   initializeSimpleInlinerPass(R);
100f785676fSDimitry Andric   initializePruneEHPass(R);
101f785676fSDimitry Andric   initializeGlobalDCEPass(R);
102f785676fSDimitry Andric   initializeArgPromotionPass(R);
103f785676fSDimitry Andric   initializeJumpThreadingPass(R);
104f785676fSDimitry Andric   initializeSROAPass(R);
105f785676fSDimitry Andric   initializeSROA_DTPass(R);
106f785676fSDimitry Andric   initializeSROA_SSAUpPass(R);
107f785676fSDimitry Andric   initializeFunctionAttrsPass(R);
108f785676fSDimitry Andric   initializeGlobalsModRefPass(R);
109f785676fSDimitry Andric   initializeLICMPass(R);
11091bc56edSDimitry Andric   initializeMergedLoadStoreMotionPass(R);
111f785676fSDimitry Andric   initializeGVNPass(R);
112f785676fSDimitry Andric   initializeMemCpyOptPass(R);
113f785676fSDimitry Andric   initializeDCEPass(R);
114f785676fSDimitry Andric   initializeCFGSimplifyPassPass(R);
115f785676fSDimitry Andric }
116f785676fSDimitry Andric 
117f785676fSDimitry Andric bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) {
11891bc56edSDimitry Andric   bool ret = IRLinker.linkInModule(&mod->getModule(), &errMsg);
119f785676fSDimitry Andric 
120f785676fSDimitry Andric   const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs();
121f785676fSDimitry Andric   for (int i = 0, e = undefs.size(); i != e; ++i)
122f785676fSDimitry Andric     AsmUndefinedRefs[undefs[i]] = 1;
123f785676fSDimitry Andric 
124f785676fSDimitry Andric   return !ret;
125f785676fSDimitry Andric }
126f785676fSDimitry Andric 
127f785676fSDimitry Andric void LTOCodeGenerator::setTargetOptions(TargetOptions options) {
12891bc56edSDimitry Andric   Options = options;
129f785676fSDimitry Andric }
130f785676fSDimitry Andric 
131f785676fSDimitry Andric void LTOCodeGenerator::setDebugInfo(lto_debug_model debug) {
132f785676fSDimitry Andric   switch (debug) {
133f785676fSDimitry Andric   case LTO_DEBUG_MODEL_NONE:
134f785676fSDimitry Andric     EmitDwarfDebugInfo = false;
135f785676fSDimitry Andric     return;
136f785676fSDimitry Andric 
137f785676fSDimitry Andric   case LTO_DEBUG_MODEL_DWARF:
138f785676fSDimitry Andric     EmitDwarfDebugInfo = true;
139f785676fSDimitry Andric     return;
140f785676fSDimitry Andric   }
141f785676fSDimitry Andric   llvm_unreachable("Unknown debug format!");
142f785676fSDimitry Andric }
143f785676fSDimitry Andric 
144f785676fSDimitry Andric void LTOCodeGenerator::setCodePICModel(lto_codegen_model model) {
145f785676fSDimitry Andric   switch (model) {
146f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_STATIC:
147f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
148f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
14991bc56edSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DEFAULT:
150f785676fSDimitry Andric     CodeModel = model;
151f785676fSDimitry Andric     return;
152f785676fSDimitry Andric   }
153f785676fSDimitry Andric   llvm_unreachable("Unknown PIC model!");
154f785676fSDimitry Andric }
155f785676fSDimitry Andric 
156f785676fSDimitry Andric bool LTOCodeGenerator::writeMergedModules(const char *path,
157f785676fSDimitry Andric                                           std::string &errMsg) {
158f785676fSDimitry Andric   if (!determineTarget(errMsg))
159f785676fSDimitry Andric     return false;
160f785676fSDimitry Andric 
161f785676fSDimitry Andric   // mark which symbols can not be internalized
162f785676fSDimitry Andric   applyScopeRestrictions();
163f785676fSDimitry Andric 
164f785676fSDimitry Andric   // create output file
165f785676fSDimitry Andric   std::string ErrInfo;
16691bc56edSDimitry Andric   tool_output_file Out(path, ErrInfo, sys::fs::F_None);
167f785676fSDimitry Andric   if (!ErrInfo.empty()) {
168f785676fSDimitry Andric     errMsg = "could not open bitcode file for writing: ";
169f785676fSDimitry Andric     errMsg += path;
170f785676fSDimitry Andric     return false;
171f785676fSDimitry Andric   }
172f785676fSDimitry Andric 
173f785676fSDimitry Andric   // write bitcode to it
17491bc56edSDimitry Andric   WriteBitcodeToFile(IRLinker.getModule(), Out.os());
175f785676fSDimitry Andric   Out.os().close();
176f785676fSDimitry Andric 
177f785676fSDimitry Andric   if (Out.os().has_error()) {
178f785676fSDimitry Andric     errMsg = "could not write bitcode file: ";
179f785676fSDimitry Andric     errMsg += path;
180f785676fSDimitry Andric     Out.os().clear_error();
181f785676fSDimitry Andric     return false;
182f785676fSDimitry Andric   }
183f785676fSDimitry Andric 
184f785676fSDimitry Andric   Out.keep();
185f785676fSDimitry Andric   return true;
186f785676fSDimitry Andric }
187f785676fSDimitry Andric 
188f785676fSDimitry Andric bool LTOCodeGenerator::compile_to_file(const char** name,
189f785676fSDimitry Andric                                        bool disableOpt,
190f785676fSDimitry Andric                                        bool disableInline,
191f785676fSDimitry Andric                                        bool disableGVNLoadPRE,
192f785676fSDimitry Andric                                        std::string& errMsg) {
193f785676fSDimitry Andric   // make unique temp .o file to put generated object file
194f785676fSDimitry Andric   SmallString<128> Filename;
195f785676fSDimitry Andric   int FD;
19691bc56edSDimitry Andric   std::error_code EC =
19791bc56edSDimitry Andric       sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename);
198f785676fSDimitry Andric   if (EC) {
199f785676fSDimitry Andric     errMsg = EC.message();
200f785676fSDimitry Andric     return false;
201f785676fSDimitry Andric   }
202f785676fSDimitry Andric 
203f785676fSDimitry Andric   // generate object file
204f785676fSDimitry Andric   tool_output_file objFile(Filename.c_str(), FD);
205f785676fSDimitry Andric 
206f785676fSDimitry Andric   bool genResult = generateObjectFile(objFile.os(), disableOpt, disableInline,
207f785676fSDimitry Andric                                       disableGVNLoadPRE, errMsg);
208f785676fSDimitry Andric   objFile.os().close();
209f785676fSDimitry Andric   if (objFile.os().has_error()) {
210f785676fSDimitry Andric     objFile.os().clear_error();
211f785676fSDimitry Andric     sys::fs::remove(Twine(Filename));
212f785676fSDimitry Andric     return false;
213f785676fSDimitry Andric   }
214f785676fSDimitry Andric 
215f785676fSDimitry Andric   objFile.keep();
216f785676fSDimitry Andric   if (!genResult) {
217f785676fSDimitry Andric     sys::fs::remove(Twine(Filename));
218f785676fSDimitry Andric     return false;
219f785676fSDimitry Andric   }
220f785676fSDimitry Andric 
221f785676fSDimitry Andric   NativeObjectPath = Filename.c_str();
222f785676fSDimitry Andric   *name = NativeObjectPath.c_str();
223f785676fSDimitry Andric   return true;
224f785676fSDimitry Andric }
225f785676fSDimitry Andric 
226f785676fSDimitry Andric const void* LTOCodeGenerator::compile(size_t* length,
227f785676fSDimitry Andric                                       bool disableOpt,
228f785676fSDimitry Andric                                       bool disableInline,
229f785676fSDimitry Andric                                       bool disableGVNLoadPRE,
230f785676fSDimitry Andric                                       std::string& errMsg) {
231f785676fSDimitry Andric   const char *name;
232f785676fSDimitry Andric   if (!compile_to_file(&name, disableOpt, disableInline, disableGVNLoadPRE,
233f785676fSDimitry Andric                        errMsg))
23491bc56edSDimitry Andric     return nullptr;
235f785676fSDimitry Andric 
236f785676fSDimitry Andric   // remove old buffer if compile() called twice
237f785676fSDimitry Andric   delete NativeObjectFile;
238f785676fSDimitry Andric 
239f785676fSDimitry Andric   // read .o file into memory buffer
24091bc56edSDimitry Andric   ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
24191bc56edSDimitry Andric       MemoryBuffer::getFile(name, -1, false);
24291bc56edSDimitry Andric   if (std::error_code EC = BufferOrErr.getError()) {
24391bc56edSDimitry Andric     errMsg = EC.message();
244f785676fSDimitry Andric     sys::fs::remove(NativeObjectPath);
24591bc56edSDimitry Andric     return nullptr;
246f785676fSDimitry Andric   }
24791bc56edSDimitry Andric   NativeObjectFile = BufferOrErr.get().release();
248f785676fSDimitry Andric 
249f785676fSDimitry Andric   // remove temp files
250f785676fSDimitry Andric   sys::fs::remove(NativeObjectPath);
251f785676fSDimitry Andric 
252f785676fSDimitry Andric   // return buffer, unless error
25391bc56edSDimitry Andric   if (!NativeObjectFile)
25491bc56edSDimitry Andric     return nullptr;
255f785676fSDimitry Andric   *length = NativeObjectFile->getBufferSize();
256f785676fSDimitry Andric   return NativeObjectFile->getBufferStart();
257f785676fSDimitry Andric }
258f785676fSDimitry Andric 
259f785676fSDimitry Andric bool LTOCodeGenerator::determineTarget(std::string &errMsg) {
26091bc56edSDimitry Andric   if (TargetMach)
261f785676fSDimitry Andric     return true;
262f785676fSDimitry Andric 
26391bc56edSDimitry Andric   std::string TripleStr = IRLinker.getModule()->getTargetTriple();
264f785676fSDimitry Andric   if (TripleStr.empty())
265f785676fSDimitry Andric     TripleStr = sys::getDefaultTargetTriple();
266f785676fSDimitry Andric   llvm::Triple Triple(TripleStr);
267f785676fSDimitry Andric 
268f785676fSDimitry Andric   // create target machine from info for merged modules
269f785676fSDimitry Andric   const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg);
27091bc56edSDimitry Andric   if (!march)
271f785676fSDimitry Andric     return false;
272f785676fSDimitry Andric 
273f785676fSDimitry Andric   // The relocation model is actually a static member of TargetMachine and
274f785676fSDimitry Andric   // needs to be set before the TargetMachine is instantiated.
275f785676fSDimitry Andric   Reloc::Model RelocModel = Reloc::Default;
276f785676fSDimitry Andric   switch (CodeModel) {
277f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_STATIC:
278f785676fSDimitry Andric     RelocModel = Reloc::Static;
279f785676fSDimitry Andric     break;
280f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
281f785676fSDimitry Andric     RelocModel = Reloc::PIC_;
282f785676fSDimitry Andric     break;
283f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
284f785676fSDimitry Andric     RelocModel = Reloc::DynamicNoPIC;
285f785676fSDimitry Andric     break;
28691bc56edSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DEFAULT:
28791bc56edSDimitry Andric     // RelocModel is already the default, so leave it that way.
28891bc56edSDimitry Andric     break;
289f785676fSDimitry Andric   }
290f785676fSDimitry Andric 
29191bc56edSDimitry Andric   // Construct LTOModule, hand over ownership of module and target. Use MAttr as
29291bc56edSDimitry Andric   // the default set of features.
29391bc56edSDimitry Andric   SubtargetFeatures Features(MAttr);
294f785676fSDimitry Andric   Features.getDefaultSubtargetFeatures(Triple);
295f785676fSDimitry Andric   std::string FeatureStr = Features.getString();
296f785676fSDimitry Andric   // Set a default CPU for Darwin triples.
297f785676fSDimitry Andric   if (MCpu.empty() && Triple.isOSDarwin()) {
298f785676fSDimitry Andric     if (Triple.getArch() == llvm::Triple::x86_64)
299f785676fSDimitry Andric       MCpu = "core2";
300f785676fSDimitry Andric     else if (Triple.getArch() == llvm::Triple::x86)
301f785676fSDimitry Andric       MCpu = "yonah";
30291bc56edSDimitry Andric     else if (Triple.getArch() == llvm::Triple::arm64 ||
30391bc56edSDimitry Andric              Triple.getArch() == llvm::Triple::aarch64)
30491bc56edSDimitry Andric       MCpu = "cyclone";
305f785676fSDimitry Andric   }
306f785676fSDimitry Andric 
307f785676fSDimitry Andric   TargetMach = march->createTargetMachine(TripleStr, MCpu, FeatureStr, Options,
308f785676fSDimitry Andric                                           RelocModel, CodeModel::Default,
309f785676fSDimitry Andric                                           CodeGenOpt::Aggressive);
310f785676fSDimitry Andric   return true;
311f785676fSDimitry Andric }
312f785676fSDimitry Andric 
313f785676fSDimitry Andric void LTOCodeGenerator::
314f785676fSDimitry Andric applyRestriction(GlobalValue &GV,
315f785676fSDimitry Andric                  const ArrayRef<StringRef> &Libcalls,
316f785676fSDimitry Andric                  std::vector<const char*> &MustPreserveList,
317f785676fSDimitry Andric                  SmallPtrSet<GlobalValue*, 8> &AsmUsed,
318f785676fSDimitry Andric                  Mangler &Mangler) {
31991bc56edSDimitry Andric   // There are no restrictions to apply to declarations.
320f785676fSDimitry Andric   if (GV.isDeclaration())
321f785676fSDimitry Andric     return;
32291bc56edSDimitry Andric 
32391bc56edSDimitry Andric   // There is nothing more restrictive than private linkage.
32491bc56edSDimitry Andric   if (GV.hasPrivateLinkage())
32591bc56edSDimitry Andric     return;
32691bc56edSDimitry Andric 
32791bc56edSDimitry Andric   SmallString<64> Buffer;
32891bc56edSDimitry Andric   TargetMach->getNameWithPrefix(Buffer, &GV, Mangler);
32991bc56edSDimitry Andric 
330f785676fSDimitry Andric   if (MustPreserveSymbols.count(Buffer))
331f785676fSDimitry Andric     MustPreserveList.push_back(GV.getName().data());
332f785676fSDimitry Andric   if (AsmUndefinedRefs.count(Buffer))
333f785676fSDimitry Andric     AsmUsed.insert(&GV);
334f785676fSDimitry Andric 
335f785676fSDimitry Andric   // Conservatively append user-supplied runtime library functions to
336f785676fSDimitry Andric   // llvm.compiler.used.  These could be internalized and deleted by
337f785676fSDimitry Andric   // optimizations like -globalopt, causing problems when later optimizations
338f785676fSDimitry Andric   // add new library calls (e.g., llvm.memset => memset and printf => puts).
339f785676fSDimitry Andric   // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
340f785676fSDimitry Andric   if (isa<Function>(GV) &&
341f785676fSDimitry Andric       std::binary_search(Libcalls.begin(), Libcalls.end(), GV.getName()))
342f785676fSDimitry Andric     AsmUsed.insert(&GV);
343f785676fSDimitry Andric }
344f785676fSDimitry Andric 
345f785676fSDimitry Andric static void findUsedValues(GlobalVariable *LLVMUsed,
346f785676fSDimitry Andric                            SmallPtrSet<GlobalValue*, 8> &UsedValues) {
34791bc56edSDimitry Andric   if (!LLVMUsed) return;
348f785676fSDimitry Andric 
349f785676fSDimitry Andric   ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
350f785676fSDimitry Andric   for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
351f785676fSDimitry Andric     if (GlobalValue *GV =
352f785676fSDimitry Andric         dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
353f785676fSDimitry Andric       UsedValues.insert(GV);
354f785676fSDimitry Andric }
355f785676fSDimitry Andric 
356f785676fSDimitry Andric static void accumulateAndSortLibcalls(std::vector<StringRef> &Libcalls,
357f785676fSDimitry Andric                                       const TargetLibraryInfo& TLI,
358f785676fSDimitry Andric                                       const TargetLowering *Lowering)
359f785676fSDimitry Andric {
360f785676fSDimitry Andric   // TargetLibraryInfo has info on C runtime library calls on the current
361f785676fSDimitry Andric   // target.
362f785676fSDimitry Andric   for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
363f785676fSDimitry Andric        I != E; ++I) {
364f785676fSDimitry Andric     LibFunc::Func F = static_cast<LibFunc::Func>(I);
365f785676fSDimitry Andric     if (TLI.has(F))
366f785676fSDimitry Andric       Libcalls.push_back(TLI.getName(F));
367f785676fSDimitry Andric   }
368f785676fSDimitry Andric 
369f785676fSDimitry Andric   // TargetLowering has info on library calls that CodeGen expects to be
370f785676fSDimitry Andric   // available, both from the C runtime and compiler-rt.
371f785676fSDimitry Andric   if (Lowering)
372f785676fSDimitry Andric     for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
373f785676fSDimitry Andric          I != E; ++I)
374f785676fSDimitry Andric       if (const char *Name
375f785676fSDimitry Andric           = Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
376f785676fSDimitry Andric         Libcalls.push_back(Name);
377f785676fSDimitry Andric 
378f785676fSDimitry Andric   array_pod_sort(Libcalls.begin(), Libcalls.end());
379f785676fSDimitry Andric   Libcalls.erase(std::unique(Libcalls.begin(), Libcalls.end()),
380f785676fSDimitry Andric                  Libcalls.end());
381f785676fSDimitry Andric }
382f785676fSDimitry Andric 
383f785676fSDimitry Andric void LTOCodeGenerator::applyScopeRestrictions() {
384f785676fSDimitry Andric   if (ScopeRestrictionsDone)
385f785676fSDimitry Andric     return;
38691bc56edSDimitry Andric   Module *mergedModule = IRLinker.getModule();
387f785676fSDimitry Andric 
388f785676fSDimitry Andric   // Start off with a verification pass.
389f785676fSDimitry Andric   PassManager passes;
390f785676fSDimitry Andric   passes.add(createVerifierPass());
39191bc56edSDimitry Andric   passes.add(createDebugInfoVerifierPass());
392f785676fSDimitry Andric 
393f785676fSDimitry Andric   // mark which symbols can not be internalized
39491bc56edSDimitry Andric   Mangler Mangler(TargetMach->getDataLayout());
395f785676fSDimitry Andric   std::vector<const char*> MustPreserveList;
396f785676fSDimitry Andric   SmallPtrSet<GlobalValue*, 8> AsmUsed;
397f785676fSDimitry Andric   std::vector<StringRef> Libcalls;
398f785676fSDimitry Andric   TargetLibraryInfo TLI(Triple(TargetMach->getTargetTriple()));
399f785676fSDimitry Andric   accumulateAndSortLibcalls(Libcalls, TLI, TargetMach->getTargetLowering());
400f785676fSDimitry Andric 
401f785676fSDimitry Andric   for (Module::iterator f = mergedModule->begin(),
402f785676fSDimitry Andric          e = mergedModule->end(); f != e; ++f)
403f785676fSDimitry Andric     applyRestriction(*f, Libcalls, MustPreserveList, AsmUsed, Mangler);
404f785676fSDimitry Andric   for (Module::global_iterator v = mergedModule->global_begin(),
405f785676fSDimitry Andric          e = mergedModule->global_end(); v !=  e; ++v)
406f785676fSDimitry Andric     applyRestriction(*v, Libcalls, MustPreserveList, AsmUsed, Mangler);
407f785676fSDimitry Andric   for (Module::alias_iterator a = mergedModule->alias_begin(),
408f785676fSDimitry Andric          e = mergedModule->alias_end(); a != e; ++a)
409f785676fSDimitry Andric     applyRestriction(*a, Libcalls, MustPreserveList, AsmUsed, Mangler);
410f785676fSDimitry Andric 
411f785676fSDimitry Andric   GlobalVariable *LLVMCompilerUsed =
412f785676fSDimitry Andric     mergedModule->getGlobalVariable("llvm.compiler.used");
413f785676fSDimitry Andric   findUsedValues(LLVMCompilerUsed, AsmUsed);
414f785676fSDimitry Andric   if (LLVMCompilerUsed)
415f785676fSDimitry Andric     LLVMCompilerUsed->eraseFromParent();
416f785676fSDimitry Andric 
417f785676fSDimitry Andric   if (!AsmUsed.empty()) {
418f785676fSDimitry Andric     llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(Context);
419f785676fSDimitry Andric     std::vector<Constant*> asmUsed2;
42091bc56edSDimitry Andric     for (auto *GV : AsmUsed) {
421f785676fSDimitry Andric       Constant *c = ConstantExpr::getBitCast(GV, i8PTy);
422f785676fSDimitry Andric       asmUsed2.push_back(c);
423f785676fSDimitry Andric     }
424f785676fSDimitry Andric 
425f785676fSDimitry Andric     llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size());
426f785676fSDimitry Andric     LLVMCompilerUsed =
427f785676fSDimitry Andric       new llvm::GlobalVariable(*mergedModule, ATy, false,
428f785676fSDimitry Andric                                llvm::GlobalValue::AppendingLinkage,
429f785676fSDimitry Andric                                llvm::ConstantArray::get(ATy, asmUsed2),
430f785676fSDimitry Andric                                "llvm.compiler.used");
431f785676fSDimitry Andric 
432f785676fSDimitry Andric     LLVMCompilerUsed->setSection("llvm.metadata");
433f785676fSDimitry Andric   }
434f785676fSDimitry Andric 
435f785676fSDimitry Andric   passes.add(createInternalizePass(MustPreserveList));
436f785676fSDimitry Andric 
437f785676fSDimitry Andric   // apply scope restrictions
438f785676fSDimitry Andric   passes.run(*mergedModule);
439f785676fSDimitry Andric 
440f785676fSDimitry Andric   ScopeRestrictionsDone = true;
441f785676fSDimitry Andric }
442f785676fSDimitry Andric 
443f785676fSDimitry Andric /// Optimize merged modules using various IPO passes
444f785676fSDimitry Andric bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
445f785676fSDimitry Andric                                           bool DisableOpt,
446f785676fSDimitry Andric                                           bool DisableInline,
447f785676fSDimitry Andric                                           bool DisableGVNLoadPRE,
448f785676fSDimitry Andric                                           std::string &errMsg) {
449f785676fSDimitry Andric   if (!this->determineTarget(errMsg))
450f785676fSDimitry Andric     return false;
451f785676fSDimitry Andric 
45291bc56edSDimitry Andric   Module *mergedModule = IRLinker.getModule();
453f785676fSDimitry Andric 
454f785676fSDimitry Andric   // Mark which symbols can not be internalized
455f785676fSDimitry Andric   this->applyScopeRestrictions();
456f785676fSDimitry Andric 
457f785676fSDimitry Andric   // Instantiate the pass manager to organize the passes.
458f785676fSDimitry Andric   PassManager passes;
459f785676fSDimitry Andric 
460f785676fSDimitry Andric   // Start off with a verification pass.
461f785676fSDimitry Andric   passes.add(createVerifierPass());
46291bc56edSDimitry Andric   passes.add(createDebugInfoVerifierPass());
463f785676fSDimitry Andric 
464f785676fSDimitry Andric   // Add an appropriate DataLayout instance for this module...
46591bc56edSDimitry Andric   mergedModule->setDataLayout(TargetMach->getDataLayout());
46691bc56edSDimitry Andric   passes.add(new DataLayoutPass(mergedModule));
46791bc56edSDimitry Andric 
46891bc56edSDimitry Andric   // Add appropriate TargetLibraryInfo for this module.
46991bc56edSDimitry Andric   passes.add(new TargetLibraryInfo(Triple(TargetMach->getTargetTriple())));
47091bc56edSDimitry Andric 
471f785676fSDimitry Andric   TargetMach->addAnalysisPasses(passes);
472f785676fSDimitry Andric 
473f785676fSDimitry Andric   // Enabling internalize here would use its AllButMain variant. It
474f785676fSDimitry Andric   // keeps only main if it exists and does nothing for libraries. Instead
475f785676fSDimitry Andric   // we create the pass ourselves with the symbol list provided by the linker.
476f785676fSDimitry Andric   if (!DisableOpt)
477f785676fSDimitry Andric     PassManagerBuilder().populateLTOPassManager(passes,
478f785676fSDimitry Andric                                               /*Internalize=*/false,
479f785676fSDimitry Andric                                               !DisableInline,
480f785676fSDimitry Andric                                               DisableGVNLoadPRE);
481f785676fSDimitry Andric 
482f785676fSDimitry Andric   // Make sure everything is still good.
483f785676fSDimitry Andric   passes.add(createVerifierPass());
48491bc56edSDimitry Andric   passes.add(createDebugInfoVerifierPass());
485f785676fSDimitry Andric 
486f785676fSDimitry Andric   PassManager codeGenPasses;
487f785676fSDimitry Andric 
48891bc56edSDimitry Andric   codeGenPasses.add(new DataLayoutPass(mergedModule));
489f785676fSDimitry Andric 
490f785676fSDimitry Andric   formatted_raw_ostream Out(out);
491f785676fSDimitry Andric 
492f785676fSDimitry Andric   // If the bitcode files contain ARC code and were compiled with optimization,
493f785676fSDimitry Andric   // the ObjCARCContractPass must be run, so do it unconditionally here.
494f785676fSDimitry Andric   codeGenPasses.add(createObjCARCContractPass());
495f785676fSDimitry Andric 
496f785676fSDimitry Andric   if (TargetMach->addPassesToEmitFile(codeGenPasses, Out,
497f785676fSDimitry Andric                                       TargetMachine::CGFT_ObjectFile)) {
498f785676fSDimitry Andric     errMsg = "target file type not supported";
499f785676fSDimitry Andric     return false;
500f785676fSDimitry Andric   }
501f785676fSDimitry Andric 
502f785676fSDimitry Andric   // Run our queue of passes all at once now, efficiently.
503f785676fSDimitry Andric   passes.run(*mergedModule);
504f785676fSDimitry Andric 
505f785676fSDimitry Andric   // Run the code generator, and write assembly file
506f785676fSDimitry Andric   codeGenPasses.run(*mergedModule);
507f785676fSDimitry Andric 
508f785676fSDimitry Andric   return true;
509f785676fSDimitry Andric }
510f785676fSDimitry Andric 
511f785676fSDimitry Andric /// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging
512f785676fSDimitry Andric /// LTO problems.
513f785676fSDimitry Andric void LTOCodeGenerator::setCodeGenDebugOptions(const char *options) {
514f785676fSDimitry Andric   for (std::pair<StringRef, StringRef> o = getToken(options);
515f785676fSDimitry Andric        !o.first.empty(); o = getToken(o.second)) {
516f785676fSDimitry Andric     // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add
517f785676fSDimitry Andric     // that.
518f785676fSDimitry Andric     if (CodegenOptions.empty())
519f785676fSDimitry Andric       CodegenOptions.push_back(strdup("libLLVMLTO"));
520f785676fSDimitry Andric     CodegenOptions.push_back(strdup(o.first.str().c_str()));
521f785676fSDimitry Andric   }
522f785676fSDimitry Andric }
523f785676fSDimitry Andric 
524f785676fSDimitry Andric void LTOCodeGenerator::parseCodeGenDebugOptions() {
525f785676fSDimitry Andric   // if options were requested, set them
526f785676fSDimitry Andric   if (!CodegenOptions.empty())
527f785676fSDimitry Andric     cl::ParseCommandLineOptions(CodegenOptions.size(),
528f785676fSDimitry Andric                                 const_cast<char **>(&CodegenOptions[0]));
529f785676fSDimitry Andric }
53091bc56edSDimitry Andric 
53191bc56edSDimitry Andric void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI,
53291bc56edSDimitry Andric                                          void *Context) {
53391bc56edSDimitry Andric   ((LTOCodeGenerator *)Context)->DiagnosticHandler2(DI);
53491bc56edSDimitry Andric }
53591bc56edSDimitry Andric 
53691bc56edSDimitry Andric void LTOCodeGenerator::DiagnosticHandler2(const DiagnosticInfo &DI) {
53791bc56edSDimitry Andric   // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
53891bc56edSDimitry Andric   lto_codegen_diagnostic_severity_t Severity;
53991bc56edSDimitry Andric   switch (DI.getSeverity()) {
54091bc56edSDimitry Andric   case DS_Error:
54191bc56edSDimitry Andric     Severity = LTO_DS_ERROR;
54291bc56edSDimitry Andric     break;
54391bc56edSDimitry Andric   case DS_Warning:
54491bc56edSDimitry Andric     Severity = LTO_DS_WARNING;
54591bc56edSDimitry Andric     break;
54691bc56edSDimitry Andric   case DS_Remark:
54791bc56edSDimitry Andric     Severity = LTO_DS_REMARK;
54891bc56edSDimitry Andric     break;
54991bc56edSDimitry Andric   case DS_Note:
55091bc56edSDimitry Andric     Severity = LTO_DS_NOTE;
55191bc56edSDimitry Andric     break;
55291bc56edSDimitry Andric   }
55391bc56edSDimitry Andric   // Create the string that will be reported to the external diagnostic handler.
55491bc56edSDimitry Andric   std::string MsgStorage;
55591bc56edSDimitry Andric   raw_string_ostream Stream(MsgStorage);
55691bc56edSDimitry Andric   DiagnosticPrinterRawOStream DP(Stream);
55791bc56edSDimitry Andric   DI.print(DP);
55891bc56edSDimitry Andric   Stream.flush();
55991bc56edSDimitry Andric 
56091bc56edSDimitry Andric   // If this method has been called it means someone has set up an external
56191bc56edSDimitry Andric   // diagnostic handler. Assert on that.
56291bc56edSDimitry Andric   assert(DiagHandler && "Invalid diagnostic handler");
56391bc56edSDimitry Andric   (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
56491bc56edSDimitry Andric }
56591bc56edSDimitry Andric 
56691bc56edSDimitry Andric void
56791bc56edSDimitry Andric LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler,
56891bc56edSDimitry Andric                                        void *Ctxt) {
56991bc56edSDimitry Andric   this->DiagHandler = DiagHandler;
57091bc56edSDimitry Andric   this->DiagContext = Ctxt;
57191bc56edSDimitry Andric   if (!DiagHandler)
57291bc56edSDimitry Andric     return Context.setDiagnosticHandler(nullptr, nullptr);
57391bc56edSDimitry Andric   // Register the LTOCodeGenerator stub in the LLVMContext to forward the
57491bc56edSDimitry Andric   // diagnostic to the external DiagHandler.
57591bc56edSDimitry Andric   Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this);
57691bc56edSDimitry Andric }
577