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"
5139d628a0SDimitry Andric #include "llvm/Target/TargetSubtargetInfo.h"
52f785676fSDimitry Andric #include "llvm/Transforms/IPO.h"
53f785676fSDimitry Andric #include "llvm/Transforms/IPO/PassManagerBuilder.h"
54f785676fSDimitry Andric #include "llvm/Transforms/ObjCARC.h"
5591bc56edSDimitry Andric #include <system_error>
56f785676fSDimitry Andric using namespace llvm;
57f785676fSDimitry Andric 
58f785676fSDimitry Andric const char* LTOCodeGenerator::getVersionString() {
59f785676fSDimitry Andric #ifdef LLVM_VERSION_INFO
60f785676fSDimitry Andric   return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
61f785676fSDimitry Andric #else
62f785676fSDimitry Andric   return PACKAGE_NAME " version " PACKAGE_VERSION;
63f785676fSDimitry Andric #endif
64f785676fSDimitry Andric }
65f785676fSDimitry Andric 
66f785676fSDimitry Andric LTOCodeGenerator::LTOCodeGenerator()
6739d628a0SDimitry Andric     : Context(getGlobalContext()), IRLinker(new Module("ld-temp.o", Context)) {
6839d628a0SDimitry Andric   initialize();
6939d628a0SDimitry Andric }
7039d628a0SDimitry Andric 
7139d628a0SDimitry Andric LTOCodeGenerator::LTOCodeGenerator(std::unique_ptr<LLVMContext> Context)
7239d628a0SDimitry Andric     : OwnedContext(std::move(Context)), Context(*OwnedContext),
7339d628a0SDimitry Andric       IRLinker(new Module("ld-temp.o", *OwnedContext)) {
7439d628a0SDimitry Andric   initialize();
7539d628a0SDimitry Andric }
7639d628a0SDimitry Andric 
7739d628a0SDimitry Andric void LTOCodeGenerator::initialize() {
7839d628a0SDimitry Andric   TargetMach = nullptr;
7939d628a0SDimitry Andric   EmitDwarfDebugInfo = false;
8039d628a0SDimitry Andric   ScopeRestrictionsDone = false;
8139d628a0SDimitry Andric   CodeModel = LTO_CODEGEN_PIC_MODEL_DEFAULT;
8239d628a0SDimitry Andric   DiagHandler = nullptr;
8339d628a0SDimitry Andric   DiagContext = nullptr;
8439d628a0SDimitry Andric 
85f785676fSDimitry Andric   initializeLTOPasses();
86f785676fSDimitry Andric }
87f785676fSDimitry Andric 
88f785676fSDimitry Andric LTOCodeGenerator::~LTOCodeGenerator() {
89f785676fSDimitry Andric   delete TargetMach;
9091bc56edSDimitry Andric   TargetMach = nullptr;
91f785676fSDimitry Andric 
9291bc56edSDimitry Andric   IRLinker.deleteModule();
93f785676fSDimitry Andric 
94f785676fSDimitry Andric   for (std::vector<char *>::iterator I = CodegenOptions.begin(),
95f785676fSDimitry Andric                                      E = CodegenOptions.end();
96f785676fSDimitry Andric        I != E; ++I)
97f785676fSDimitry Andric     free(*I);
98f785676fSDimitry Andric }
99f785676fSDimitry Andric 
100f785676fSDimitry Andric // Initialize LTO passes. Please keep this funciton in sync with
101f785676fSDimitry Andric // PassManagerBuilder::populateLTOPassManager(), and make sure all LTO
102f785676fSDimitry Andric // passes are initialized.
103f785676fSDimitry Andric void LTOCodeGenerator::initializeLTOPasses() {
104f785676fSDimitry Andric   PassRegistry &R = *PassRegistry::getPassRegistry();
105f785676fSDimitry Andric 
106f785676fSDimitry Andric   initializeInternalizePassPass(R);
107f785676fSDimitry Andric   initializeIPSCCPPass(R);
108f785676fSDimitry Andric   initializeGlobalOptPass(R);
109f785676fSDimitry Andric   initializeConstantMergePass(R);
110f785676fSDimitry Andric   initializeDAHPass(R);
111f785676fSDimitry Andric   initializeInstCombinerPass(R);
112f785676fSDimitry Andric   initializeSimpleInlinerPass(R);
113f785676fSDimitry Andric   initializePruneEHPass(R);
114f785676fSDimitry Andric   initializeGlobalDCEPass(R);
115f785676fSDimitry Andric   initializeArgPromotionPass(R);
116f785676fSDimitry Andric   initializeJumpThreadingPass(R);
117f785676fSDimitry Andric   initializeSROAPass(R);
118f785676fSDimitry Andric   initializeSROA_DTPass(R);
119f785676fSDimitry Andric   initializeSROA_SSAUpPass(R);
120f785676fSDimitry Andric   initializeFunctionAttrsPass(R);
121f785676fSDimitry Andric   initializeGlobalsModRefPass(R);
122f785676fSDimitry Andric   initializeLICMPass(R);
12391bc56edSDimitry Andric   initializeMergedLoadStoreMotionPass(R);
124f785676fSDimitry Andric   initializeGVNPass(R);
125f785676fSDimitry Andric   initializeMemCpyOptPass(R);
126f785676fSDimitry Andric   initializeDCEPass(R);
127f785676fSDimitry Andric   initializeCFGSimplifyPassPass(R);
128f785676fSDimitry Andric }
129f785676fSDimitry Andric 
13039d628a0SDimitry Andric bool LTOCodeGenerator::addModule(LTOModule *mod) {
13139d628a0SDimitry Andric   assert(&mod->getModule().getContext() == &Context &&
13239d628a0SDimitry Andric          "Expected module in same context");
13339d628a0SDimitry Andric 
13439d628a0SDimitry Andric   bool ret = IRLinker.linkInModule(&mod->getModule());
135f785676fSDimitry Andric 
136f785676fSDimitry Andric   const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs();
137f785676fSDimitry Andric   for (int i = 0, e = undefs.size(); i != e; ++i)
138f785676fSDimitry Andric     AsmUndefinedRefs[undefs[i]] = 1;
139f785676fSDimitry Andric 
140f785676fSDimitry Andric   return !ret;
141f785676fSDimitry Andric }
142f785676fSDimitry Andric 
143f785676fSDimitry Andric void LTOCodeGenerator::setTargetOptions(TargetOptions options) {
14491bc56edSDimitry Andric   Options = options;
145f785676fSDimitry Andric }
146f785676fSDimitry Andric 
147f785676fSDimitry Andric void LTOCodeGenerator::setDebugInfo(lto_debug_model debug) {
148f785676fSDimitry Andric   switch (debug) {
149f785676fSDimitry Andric   case LTO_DEBUG_MODEL_NONE:
150f785676fSDimitry Andric     EmitDwarfDebugInfo = false;
151f785676fSDimitry Andric     return;
152f785676fSDimitry Andric 
153f785676fSDimitry Andric   case LTO_DEBUG_MODEL_DWARF:
154f785676fSDimitry Andric     EmitDwarfDebugInfo = true;
155f785676fSDimitry Andric     return;
156f785676fSDimitry Andric   }
157f785676fSDimitry Andric   llvm_unreachable("Unknown debug format!");
158f785676fSDimitry Andric }
159f785676fSDimitry Andric 
160f785676fSDimitry Andric void LTOCodeGenerator::setCodePICModel(lto_codegen_model model) {
161f785676fSDimitry Andric   switch (model) {
162f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_STATIC:
163f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
164f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
16591bc56edSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DEFAULT:
166f785676fSDimitry Andric     CodeModel = model;
167f785676fSDimitry Andric     return;
168f785676fSDimitry Andric   }
169f785676fSDimitry Andric   llvm_unreachable("Unknown PIC model!");
170f785676fSDimitry Andric }
171f785676fSDimitry Andric 
172f785676fSDimitry Andric bool LTOCodeGenerator::writeMergedModules(const char *path,
173f785676fSDimitry Andric                                           std::string &errMsg) {
174f785676fSDimitry Andric   if (!determineTarget(errMsg))
175f785676fSDimitry Andric     return false;
176f785676fSDimitry Andric 
177f785676fSDimitry Andric   // mark which symbols can not be internalized
178f785676fSDimitry Andric   applyScopeRestrictions();
179f785676fSDimitry Andric 
180f785676fSDimitry Andric   // create output file
18139d628a0SDimitry Andric   std::error_code EC;
18239d628a0SDimitry Andric   tool_output_file Out(path, EC, sys::fs::F_None);
18339d628a0SDimitry Andric   if (EC) {
184f785676fSDimitry Andric     errMsg = "could not open bitcode file for writing: ";
185f785676fSDimitry Andric     errMsg += path;
186f785676fSDimitry Andric     return false;
187f785676fSDimitry Andric   }
188f785676fSDimitry Andric 
189f785676fSDimitry Andric   // write bitcode to it
19091bc56edSDimitry Andric   WriteBitcodeToFile(IRLinker.getModule(), Out.os());
191f785676fSDimitry Andric   Out.os().close();
192f785676fSDimitry Andric 
193f785676fSDimitry Andric   if (Out.os().has_error()) {
194f785676fSDimitry Andric     errMsg = "could not write bitcode file: ";
195f785676fSDimitry Andric     errMsg += path;
196f785676fSDimitry Andric     Out.os().clear_error();
197f785676fSDimitry Andric     return false;
198f785676fSDimitry Andric   }
199f785676fSDimitry Andric 
200f785676fSDimitry Andric   Out.keep();
201f785676fSDimitry Andric   return true;
202f785676fSDimitry Andric }
203f785676fSDimitry Andric 
204f785676fSDimitry Andric bool LTOCodeGenerator::compile_to_file(const char** name,
205f785676fSDimitry Andric                                        bool disableOpt,
206f785676fSDimitry Andric                                        bool disableInline,
207f785676fSDimitry Andric                                        bool disableGVNLoadPRE,
20839d628a0SDimitry Andric                                        bool disableVectorization,
209f785676fSDimitry Andric                                        std::string& errMsg) {
210f785676fSDimitry Andric   // make unique temp .o file to put generated object file
211f785676fSDimitry Andric   SmallString<128> Filename;
212f785676fSDimitry Andric   int FD;
21391bc56edSDimitry Andric   std::error_code EC =
21491bc56edSDimitry Andric       sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename);
215f785676fSDimitry Andric   if (EC) {
216f785676fSDimitry Andric     errMsg = EC.message();
217f785676fSDimitry Andric     return false;
218f785676fSDimitry Andric   }
219f785676fSDimitry Andric 
220f785676fSDimitry Andric   // generate object file
221f785676fSDimitry Andric   tool_output_file objFile(Filename.c_str(), FD);
222f785676fSDimitry Andric 
22339d628a0SDimitry Andric   bool genResult =
22439d628a0SDimitry Andric       generateObjectFile(objFile.os(), disableOpt, disableInline,
22539d628a0SDimitry Andric                          disableGVNLoadPRE, disableVectorization, errMsg);
226f785676fSDimitry Andric   objFile.os().close();
227f785676fSDimitry Andric   if (objFile.os().has_error()) {
228f785676fSDimitry Andric     objFile.os().clear_error();
229f785676fSDimitry Andric     sys::fs::remove(Twine(Filename));
230f785676fSDimitry Andric     return false;
231f785676fSDimitry Andric   }
232f785676fSDimitry Andric 
233f785676fSDimitry Andric   objFile.keep();
234f785676fSDimitry Andric   if (!genResult) {
235f785676fSDimitry Andric     sys::fs::remove(Twine(Filename));
236f785676fSDimitry Andric     return false;
237f785676fSDimitry Andric   }
238f785676fSDimitry Andric 
239f785676fSDimitry Andric   NativeObjectPath = Filename.c_str();
240f785676fSDimitry Andric   *name = NativeObjectPath.c_str();
241f785676fSDimitry Andric   return true;
242f785676fSDimitry Andric }
243f785676fSDimitry Andric 
244f785676fSDimitry Andric const void* LTOCodeGenerator::compile(size_t* length,
245f785676fSDimitry Andric                                       bool disableOpt,
246f785676fSDimitry Andric                                       bool disableInline,
247f785676fSDimitry Andric                                       bool disableGVNLoadPRE,
24839d628a0SDimitry Andric                                       bool disableVectorization,
249f785676fSDimitry Andric                                       std::string& errMsg) {
250f785676fSDimitry Andric   const char *name;
251f785676fSDimitry Andric   if (!compile_to_file(&name, disableOpt, disableInline, disableGVNLoadPRE,
25239d628a0SDimitry Andric                        disableVectorization, errMsg))
25391bc56edSDimitry Andric     return nullptr;
254f785676fSDimitry Andric 
255f785676fSDimitry Andric   // read .o file into memory buffer
25691bc56edSDimitry Andric   ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
25791bc56edSDimitry Andric       MemoryBuffer::getFile(name, -1, false);
25891bc56edSDimitry Andric   if (std::error_code EC = BufferOrErr.getError()) {
25991bc56edSDimitry Andric     errMsg = EC.message();
260f785676fSDimitry Andric     sys::fs::remove(NativeObjectPath);
26191bc56edSDimitry Andric     return nullptr;
262f785676fSDimitry Andric   }
26339d628a0SDimitry Andric   NativeObjectFile = std::move(*BufferOrErr);
264f785676fSDimitry Andric 
265f785676fSDimitry Andric   // remove temp files
266f785676fSDimitry Andric   sys::fs::remove(NativeObjectPath);
267f785676fSDimitry Andric 
268f785676fSDimitry Andric   // return buffer, unless error
26991bc56edSDimitry Andric   if (!NativeObjectFile)
27091bc56edSDimitry Andric     return nullptr;
271f785676fSDimitry Andric   *length = NativeObjectFile->getBufferSize();
272f785676fSDimitry Andric   return NativeObjectFile->getBufferStart();
273f785676fSDimitry Andric }
274f785676fSDimitry Andric 
275f785676fSDimitry Andric bool LTOCodeGenerator::determineTarget(std::string &errMsg) {
27691bc56edSDimitry Andric   if (TargetMach)
277f785676fSDimitry Andric     return true;
278f785676fSDimitry Andric 
27991bc56edSDimitry Andric   std::string TripleStr = IRLinker.getModule()->getTargetTriple();
280f785676fSDimitry Andric   if (TripleStr.empty())
281f785676fSDimitry Andric     TripleStr = sys::getDefaultTargetTriple();
282f785676fSDimitry Andric   llvm::Triple Triple(TripleStr);
283f785676fSDimitry Andric 
284f785676fSDimitry Andric   // create target machine from info for merged modules
285f785676fSDimitry Andric   const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg);
28691bc56edSDimitry Andric   if (!march)
287f785676fSDimitry Andric     return false;
288f785676fSDimitry Andric 
289f785676fSDimitry Andric   // The relocation model is actually a static member of TargetMachine and
290f785676fSDimitry Andric   // needs to be set before the TargetMachine is instantiated.
291f785676fSDimitry Andric   Reloc::Model RelocModel = Reloc::Default;
292f785676fSDimitry Andric   switch (CodeModel) {
293f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_STATIC:
294f785676fSDimitry Andric     RelocModel = Reloc::Static;
295f785676fSDimitry Andric     break;
296f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
297f785676fSDimitry Andric     RelocModel = Reloc::PIC_;
298f785676fSDimitry Andric     break;
299f785676fSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
300f785676fSDimitry Andric     RelocModel = Reloc::DynamicNoPIC;
301f785676fSDimitry Andric     break;
30291bc56edSDimitry Andric   case LTO_CODEGEN_PIC_MODEL_DEFAULT:
30391bc56edSDimitry Andric     // RelocModel is already the default, so leave it that way.
30491bc56edSDimitry Andric     break;
305f785676fSDimitry Andric   }
306f785676fSDimitry Andric 
30791bc56edSDimitry Andric   // Construct LTOModule, hand over ownership of module and target. Use MAttr as
30891bc56edSDimitry Andric   // the default set of features.
30991bc56edSDimitry Andric   SubtargetFeatures Features(MAttr);
310f785676fSDimitry Andric   Features.getDefaultSubtargetFeatures(Triple);
311f785676fSDimitry Andric   std::string FeatureStr = Features.getString();
312f785676fSDimitry Andric   // Set a default CPU for Darwin triples.
313f785676fSDimitry Andric   if (MCpu.empty() && Triple.isOSDarwin()) {
314f785676fSDimitry Andric     if (Triple.getArch() == llvm::Triple::x86_64)
315f785676fSDimitry Andric       MCpu = "core2";
316f785676fSDimitry Andric     else if (Triple.getArch() == llvm::Triple::x86)
317f785676fSDimitry Andric       MCpu = "yonah";
31839d628a0SDimitry Andric     else if (Triple.getArch() == llvm::Triple::aarch64)
31991bc56edSDimitry Andric       MCpu = "cyclone";
320f785676fSDimitry Andric   }
321f785676fSDimitry Andric 
322f785676fSDimitry Andric   TargetMach = march->createTargetMachine(TripleStr, MCpu, FeatureStr, Options,
323f785676fSDimitry Andric                                           RelocModel, CodeModel::Default,
324f785676fSDimitry Andric                                           CodeGenOpt::Aggressive);
325f785676fSDimitry Andric   return true;
326f785676fSDimitry Andric }
327f785676fSDimitry Andric 
328f785676fSDimitry Andric void LTOCodeGenerator::
329f785676fSDimitry Andric applyRestriction(GlobalValue &GV,
33039d628a0SDimitry Andric                  ArrayRef<StringRef> Libcalls,
331f785676fSDimitry Andric                  std::vector<const char*> &MustPreserveList,
33239d628a0SDimitry Andric                  SmallPtrSetImpl<GlobalValue*> &AsmUsed,
333f785676fSDimitry Andric                  Mangler &Mangler) {
33491bc56edSDimitry Andric   // There are no restrictions to apply to declarations.
335f785676fSDimitry Andric   if (GV.isDeclaration())
336f785676fSDimitry Andric     return;
33791bc56edSDimitry Andric 
33891bc56edSDimitry Andric   // There is nothing more restrictive than private linkage.
33991bc56edSDimitry Andric   if (GV.hasPrivateLinkage())
34091bc56edSDimitry Andric     return;
34191bc56edSDimitry Andric 
34291bc56edSDimitry Andric   SmallString<64> Buffer;
34391bc56edSDimitry Andric   TargetMach->getNameWithPrefix(Buffer, &GV, Mangler);
34491bc56edSDimitry Andric 
345f785676fSDimitry Andric   if (MustPreserveSymbols.count(Buffer))
346f785676fSDimitry Andric     MustPreserveList.push_back(GV.getName().data());
347f785676fSDimitry Andric   if (AsmUndefinedRefs.count(Buffer))
348f785676fSDimitry Andric     AsmUsed.insert(&GV);
349f785676fSDimitry Andric 
350f785676fSDimitry Andric   // Conservatively append user-supplied runtime library functions to
351f785676fSDimitry Andric   // llvm.compiler.used.  These could be internalized and deleted by
352f785676fSDimitry Andric   // optimizations like -globalopt, causing problems when later optimizations
353f785676fSDimitry Andric   // add new library calls (e.g., llvm.memset => memset and printf => puts).
354f785676fSDimitry Andric   // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
355f785676fSDimitry Andric   if (isa<Function>(GV) &&
356f785676fSDimitry Andric       std::binary_search(Libcalls.begin(), Libcalls.end(), GV.getName()))
357f785676fSDimitry Andric     AsmUsed.insert(&GV);
358f785676fSDimitry Andric }
359f785676fSDimitry Andric 
360f785676fSDimitry Andric static void findUsedValues(GlobalVariable *LLVMUsed,
36139d628a0SDimitry Andric                            SmallPtrSetImpl<GlobalValue*> &UsedValues) {
36291bc56edSDimitry Andric   if (!LLVMUsed) return;
363f785676fSDimitry Andric 
364f785676fSDimitry Andric   ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
365f785676fSDimitry Andric   for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
366f785676fSDimitry Andric     if (GlobalValue *GV =
367f785676fSDimitry Andric         dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
368f785676fSDimitry Andric       UsedValues.insert(GV);
369f785676fSDimitry Andric }
370f785676fSDimitry Andric 
371f785676fSDimitry Andric static void accumulateAndSortLibcalls(std::vector<StringRef> &Libcalls,
372f785676fSDimitry Andric                                       const TargetLibraryInfo& TLI,
373f785676fSDimitry Andric                                       const TargetLowering *Lowering)
374f785676fSDimitry Andric {
375f785676fSDimitry Andric   // TargetLibraryInfo has info on C runtime library calls on the current
376f785676fSDimitry Andric   // target.
377f785676fSDimitry Andric   for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
378f785676fSDimitry Andric        I != E; ++I) {
379f785676fSDimitry Andric     LibFunc::Func F = static_cast<LibFunc::Func>(I);
380f785676fSDimitry Andric     if (TLI.has(F))
381f785676fSDimitry Andric       Libcalls.push_back(TLI.getName(F));
382f785676fSDimitry Andric   }
383f785676fSDimitry Andric 
384f785676fSDimitry Andric   // TargetLowering has info on library calls that CodeGen expects to be
385f785676fSDimitry Andric   // available, both from the C runtime and compiler-rt.
386f785676fSDimitry Andric   if (Lowering)
387f785676fSDimitry Andric     for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
388f785676fSDimitry Andric          I != E; ++I)
389f785676fSDimitry Andric       if (const char *Name
390f785676fSDimitry Andric           = Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
391f785676fSDimitry Andric         Libcalls.push_back(Name);
392f785676fSDimitry Andric 
393f785676fSDimitry Andric   array_pod_sort(Libcalls.begin(), Libcalls.end());
394f785676fSDimitry Andric   Libcalls.erase(std::unique(Libcalls.begin(), Libcalls.end()),
395f785676fSDimitry Andric                  Libcalls.end());
396f785676fSDimitry Andric }
397f785676fSDimitry Andric 
398f785676fSDimitry Andric void LTOCodeGenerator::applyScopeRestrictions() {
399f785676fSDimitry Andric   if (ScopeRestrictionsDone)
400f785676fSDimitry Andric     return;
40191bc56edSDimitry Andric   Module *mergedModule = IRLinker.getModule();
402f785676fSDimitry Andric 
403f785676fSDimitry Andric   // Start off with a verification pass.
404f785676fSDimitry Andric   PassManager passes;
405f785676fSDimitry Andric   passes.add(createVerifierPass());
40691bc56edSDimitry Andric   passes.add(createDebugInfoVerifierPass());
407f785676fSDimitry Andric 
408f785676fSDimitry Andric   // mark which symbols can not be internalized
40939d628a0SDimitry Andric   Mangler Mangler(TargetMach->getSubtargetImpl()->getDataLayout());
410f785676fSDimitry Andric   std::vector<const char*> MustPreserveList;
411f785676fSDimitry Andric   SmallPtrSet<GlobalValue*, 8> AsmUsed;
412f785676fSDimitry Andric   std::vector<StringRef> Libcalls;
413f785676fSDimitry Andric   TargetLibraryInfo TLI(Triple(TargetMach->getTargetTriple()));
41439d628a0SDimitry Andric   accumulateAndSortLibcalls(
41539d628a0SDimitry Andric       Libcalls, TLI, TargetMach->getSubtargetImpl()->getTargetLowering());
416f785676fSDimitry Andric 
417f785676fSDimitry Andric   for (Module::iterator f = mergedModule->begin(),
418f785676fSDimitry Andric          e = mergedModule->end(); f != e; ++f)
419f785676fSDimitry Andric     applyRestriction(*f, Libcalls, MustPreserveList, AsmUsed, Mangler);
420f785676fSDimitry Andric   for (Module::global_iterator v = mergedModule->global_begin(),
421f785676fSDimitry Andric          e = mergedModule->global_end(); v !=  e; ++v)
422f785676fSDimitry Andric     applyRestriction(*v, Libcalls, MustPreserveList, AsmUsed, Mangler);
423f785676fSDimitry Andric   for (Module::alias_iterator a = mergedModule->alias_begin(),
424f785676fSDimitry Andric          e = mergedModule->alias_end(); a != e; ++a)
425f785676fSDimitry Andric     applyRestriction(*a, Libcalls, MustPreserveList, AsmUsed, Mangler);
426f785676fSDimitry Andric 
427f785676fSDimitry Andric   GlobalVariable *LLVMCompilerUsed =
428f785676fSDimitry Andric     mergedModule->getGlobalVariable("llvm.compiler.used");
429f785676fSDimitry Andric   findUsedValues(LLVMCompilerUsed, AsmUsed);
430f785676fSDimitry Andric   if (LLVMCompilerUsed)
431f785676fSDimitry Andric     LLVMCompilerUsed->eraseFromParent();
432f785676fSDimitry Andric 
433f785676fSDimitry Andric   if (!AsmUsed.empty()) {
434f785676fSDimitry Andric     llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(Context);
435f785676fSDimitry Andric     std::vector<Constant*> asmUsed2;
43691bc56edSDimitry Andric     for (auto *GV : AsmUsed) {
437f785676fSDimitry Andric       Constant *c = ConstantExpr::getBitCast(GV, i8PTy);
438f785676fSDimitry Andric       asmUsed2.push_back(c);
439f785676fSDimitry Andric     }
440f785676fSDimitry Andric 
441f785676fSDimitry Andric     llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size());
442f785676fSDimitry Andric     LLVMCompilerUsed =
443f785676fSDimitry Andric       new llvm::GlobalVariable(*mergedModule, ATy, false,
444f785676fSDimitry Andric                                llvm::GlobalValue::AppendingLinkage,
445f785676fSDimitry Andric                                llvm::ConstantArray::get(ATy, asmUsed2),
446f785676fSDimitry Andric                                "llvm.compiler.used");
447f785676fSDimitry Andric 
448f785676fSDimitry Andric     LLVMCompilerUsed->setSection("llvm.metadata");
449f785676fSDimitry Andric   }
450f785676fSDimitry Andric 
451f785676fSDimitry Andric   passes.add(createInternalizePass(MustPreserveList));
452f785676fSDimitry Andric 
453f785676fSDimitry Andric   // apply scope restrictions
454f785676fSDimitry Andric   passes.run(*mergedModule);
455f785676fSDimitry Andric 
456f785676fSDimitry Andric   ScopeRestrictionsDone = true;
457f785676fSDimitry Andric }
458f785676fSDimitry Andric 
459f785676fSDimitry Andric /// Optimize merged modules using various IPO passes
460f785676fSDimitry Andric bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
461f785676fSDimitry Andric                                           bool DisableOpt,
462f785676fSDimitry Andric                                           bool DisableInline,
463f785676fSDimitry Andric                                           bool DisableGVNLoadPRE,
46439d628a0SDimitry Andric                                           bool DisableVectorization,
465f785676fSDimitry Andric                                           std::string &errMsg) {
466f785676fSDimitry Andric   if (!this->determineTarget(errMsg))
467f785676fSDimitry Andric     return false;
468f785676fSDimitry Andric 
46991bc56edSDimitry Andric   Module *mergedModule = IRLinker.getModule();
470f785676fSDimitry Andric 
471f785676fSDimitry Andric   // Mark which symbols can not be internalized
472f785676fSDimitry Andric   this->applyScopeRestrictions();
473f785676fSDimitry Andric 
474f785676fSDimitry Andric   // Instantiate the pass manager to organize the passes.
475f785676fSDimitry Andric   PassManager passes;
476f785676fSDimitry Andric 
477f785676fSDimitry Andric   // Add an appropriate DataLayout instance for this module...
47839d628a0SDimitry Andric   mergedModule->setDataLayout(TargetMach->getSubtargetImpl()->getDataLayout());
47991bc56edSDimitry Andric 
48039d628a0SDimitry Andric   Triple TargetTriple(TargetMach->getTargetTriple());
48139d628a0SDimitry Andric   PassManagerBuilder PMB;
48239d628a0SDimitry Andric   PMB.DisableGVNLoadPRE = DisableGVNLoadPRE;
48339d628a0SDimitry Andric   PMB.LoopVectorize = !DisableVectorization;
48439d628a0SDimitry Andric   PMB.SLPVectorize = !DisableVectorization;
48539d628a0SDimitry Andric   if (!DisableInline)
48639d628a0SDimitry Andric     PMB.Inliner = createFunctionInliningPass();
48739d628a0SDimitry Andric   PMB.LibraryInfo = new TargetLibraryInfo(TargetTriple);
48839d628a0SDimitry Andric   if (DisableOpt)
48939d628a0SDimitry Andric     PMB.OptLevel = 0;
49039d628a0SDimitry Andric   PMB.VerifyInput = true;
49139d628a0SDimitry Andric   PMB.VerifyOutput = true;
49291bc56edSDimitry Andric 
49339d628a0SDimitry Andric   PMB.populateLTOPassManager(passes, TargetMach);
494f785676fSDimitry Andric 
495f785676fSDimitry Andric   PassManager codeGenPasses;
496f785676fSDimitry Andric 
49739d628a0SDimitry Andric   codeGenPasses.add(new DataLayoutPass());
498f785676fSDimitry Andric 
499f785676fSDimitry Andric   formatted_raw_ostream Out(out);
500f785676fSDimitry Andric 
501f785676fSDimitry Andric   // If the bitcode files contain ARC code and were compiled with optimization,
502f785676fSDimitry Andric   // the ObjCARCContractPass must be run, so do it unconditionally here.
503f785676fSDimitry Andric   codeGenPasses.add(createObjCARCContractPass());
504f785676fSDimitry Andric 
505f785676fSDimitry Andric   if (TargetMach->addPassesToEmitFile(codeGenPasses, Out,
506f785676fSDimitry Andric                                       TargetMachine::CGFT_ObjectFile)) {
507f785676fSDimitry Andric     errMsg = "target file type not supported";
508f785676fSDimitry Andric     return false;
509f785676fSDimitry Andric   }
510f785676fSDimitry Andric 
511f785676fSDimitry Andric   // Run our queue of passes all at once now, efficiently.
512f785676fSDimitry Andric   passes.run(*mergedModule);
513f785676fSDimitry Andric 
514f785676fSDimitry Andric   // Run the code generator, and write assembly file
515f785676fSDimitry Andric   codeGenPasses.run(*mergedModule);
516f785676fSDimitry Andric 
517f785676fSDimitry Andric   return true;
518f785676fSDimitry Andric }
519f785676fSDimitry Andric 
520f785676fSDimitry Andric /// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging
521f785676fSDimitry Andric /// LTO problems.
522f785676fSDimitry Andric void LTOCodeGenerator::setCodeGenDebugOptions(const char *options) {
523f785676fSDimitry Andric   for (std::pair<StringRef, StringRef> o = getToken(options);
524f785676fSDimitry Andric        !o.first.empty(); o = getToken(o.second)) {
525f785676fSDimitry Andric     // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add
526f785676fSDimitry Andric     // that.
527f785676fSDimitry Andric     if (CodegenOptions.empty())
528f785676fSDimitry Andric       CodegenOptions.push_back(strdup("libLLVMLTO"));
529f785676fSDimitry Andric     CodegenOptions.push_back(strdup(o.first.str().c_str()));
530f785676fSDimitry Andric   }
531f785676fSDimitry Andric }
532f785676fSDimitry Andric 
533f785676fSDimitry Andric void LTOCodeGenerator::parseCodeGenDebugOptions() {
534f785676fSDimitry Andric   // if options were requested, set them
535f785676fSDimitry Andric   if (!CodegenOptions.empty())
536f785676fSDimitry Andric     cl::ParseCommandLineOptions(CodegenOptions.size(),
537f785676fSDimitry Andric                                 const_cast<char **>(&CodegenOptions[0]));
538f785676fSDimitry Andric }
53991bc56edSDimitry Andric 
54091bc56edSDimitry Andric void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI,
54191bc56edSDimitry Andric                                          void *Context) {
54291bc56edSDimitry Andric   ((LTOCodeGenerator *)Context)->DiagnosticHandler2(DI);
54391bc56edSDimitry Andric }
54491bc56edSDimitry Andric 
54591bc56edSDimitry Andric void LTOCodeGenerator::DiagnosticHandler2(const DiagnosticInfo &DI) {
54691bc56edSDimitry Andric   // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
54791bc56edSDimitry Andric   lto_codegen_diagnostic_severity_t Severity;
54891bc56edSDimitry Andric   switch (DI.getSeverity()) {
54991bc56edSDimitry Andric   case DS_Error:
55091bc56edSDimitry Andric     Severity = LTO_DS_ERROR;
55191bc56edSDimitry Andric     break;
55291bc56edSDimitry Andric   case DS_Warning:
55391bc56edSDimitry Andric     Severity = LTO_DS_WARNING;
55491bc56edSDimitry Andric     break;
55591bc56edSDimitry Andric   case DS_Remark:
55691bc56edSDimitry Andric     Severity = LTO_DS_REMARK;
55791bc56edSDimitry Andric     break;
55891bc56edSDimitry Andric   case DS_Note:
55991bc56edSDimitry Andric     Severity = LTO_DS_NOTE;
56091bc56edSDimitry Andric     break;
56191bc56edSDimitry Andric   }
56291bc56edSDimitry Andric   // Create the string that will be reported to the external diagnostic handler.
56391bc56edSDimitry Andric   std::string MsgStorage;
56491bc56edSDimitry Andric   raw_string_ostream Stream(MsgStorage);
56591bc56edSDimitry Andric   DiagnosticPrinterRawOStream DP(Stream);
56691bc56edSDimitry Andric   DI.print(DP);
56791bc56edSDimitry Andric   Stream.flush();
56891bc56edSDimitry Andric 
56991bc56edSDimitry Andric   // If this method has been called it means someone has set up an external
57091bc56edSDimitry Andric   // diagnostic handler. Assert on that.
57191bc56edSDimitry Andric   assert(DiagHandler && "Invalid diagnostic handler");
57291bc56edSDimitry Andric   (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
57391bc56edSDimitry Andric }
57491bc56edSDimitry Andric 
57591bc56edSDimitry Andric void
57691bc56edSDimitry Andric LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler,
57791bc56edSDimitry Andric                                        void *Ctxt) {
57891bc56edSDimitry Andric   this->DiagHandler = DiagHandler;
57991bc56edSDimitry Andric   this->DiagContext = Ctxt;
58091bc56edSDimitry Andric   if (!DiagHandler)
58191bc56edSDimitry Andric     return Context.setDiagnosticHandler(nullptr, nullptr);
58291bc56edSDimitry Andric   // Register the LTOCodeGenerator stub in the LLVMContext to forward the
58391bc56edSDimitry Andric   // diagnostic to the external DiagHandler.
58439d628a0SDimitry Andric   Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this,
58539d628a0SDimitry Andric                                /* RespectFilters */ true);
58691bc56edSDimitry Andric }
587