1259698Sdim//===-LTOCodeGenerator.cpp - LLVM Link Time Optimizer ---------------------===//
2259698Sdim//
3259698Sdim//                     The LLVM Compiler Infrastructure
4259698Sdim//
5259698Sdim// This file is distributed under the University of Illinois Open Source
6259698Sdim// License. See LICENSE.TXT for details.
7259698Sdim//
8259698Sdim//===----------------------------------------------------------------------===//
9259698Sdim//
10259698Sdim// This file implements the Link Time Optimization library. This library is
11259698Sdim// intended to be used by linker to optimize code at link time.
12259698Sdim//
13259698Sdim//===----------------------------------------------------------------------===//
14259698Sdim
15259698Sdim#include "llvm/LTO/LTOCodeGenerator.h"
16259698Sdim#include "llvm/LTO/LTOModule.h"
17259698Sdim#include "llvm/ADT/StringExtras.h"
18259698Sdim#include "llvm/Analysis/Passes.h"
19259698Sdim#include "llvm/Analysis/Verifier.h"
20259698Sdim#include "llvm/Bitcode/ReaderWriter.h"
21259698Sdim#include "llvm/CodeGen/RuntimeLibcalls.h"
22259698Sdim#include "llvm/Config/config.h"
23259698Sdim#include "llvm/IR/Constants.h"
24259698Sdim#include "llvm/IR/DataLayout.h"
25259698Sdim#include "llvm/IR/DerivedTypes.h"
26259698Sdim#include "llvm/IR/LLVMContext.h"
27259698Sdim#include "llvm/IR/Module.h"
28259698Sdim#include "llvm/InitializePasses.h"
29259698Sdim#include "llvm/Linker.h"
30259698Sdim#include "llvm/MC/MCAsmInfo.h"
31259698Sdim#include "llvm/MC/MCContext.h"
32259698Sdim#include "llvm/MC/SubtargetFeature.h"
33259698Sdim#include "llvm/PassManager.h"
34259698Sdim#include "llvm/Support/CommandLine.h"
35259698Sdim#include "llvm/Support/FileSystem.h"
36259698Sdim#include "llvm/Support/FormattedStream.h"
37259698Sdim#include "llvm/Support/Host.h"
38259698Sdim#include "llvm/Support/MemoryBuffer.h"
39259698Sdim#include "llvm/Support/Signals.h"
40259698Sdim#include "llvm/Support/TargetRegistry.h"
41259698Sdim#include "llvm/Support/TargetSelect.h"
42259698Sdim#include "llvm/Support/ToolOutputFile.h"
43259698Sdim#include "llvm/Support/system_error.h"
44259698Sdim#include "llvm/Target/TargetLibraryInfo.h"
45259698Sdim#include "llvm/Target/TargetLowering.h"
46259698Sdim#include "llvm/Target/TargetOptions.h"
47259698Sdim#include "llvm/Target/TargetRegisterInfo.h"
48259698Sdim#include "llvm/Target/Mangler.h"
49259698Sdim#include "llvm/Transforms/IPO.h"
50259698Sdim#include "llvm/Transforms/IPO/PassManagerBuilder.h"
51259698Sdim#include "llvm/Transforms/ObjCARC.h"
52259698Sdimusing namespace llvm;
53259698Sdim
54259698Sdimconst char* LTOCodeGenerator::getVersionString() {
55259698Sdim#ifdef LLVM_VERSION_INFO
56259698Sdim  return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
57259698Sdim#else
58259698Sdim  return PACKAGE_NAME " version " PACKAGE_VERSION;
59259698Sdim#endif
60259698Sdim}
61259698Sdim
62259698SdimLTOCodeGenerator::LTOCodeGenerator()
63259698Sdim    : Context(getGlobalContext()), Linker(new Module("ld-temp.o", Context)),
64259698Sdim      TargetMach(NULL), EmitDwarfDebugInfo(false), ScopeRestrictionsDone(false),
65259698Sdim      CodeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), NativeObjectFile(NULL) {
66259698Sdim  initializeLTOPasses();
67259698Sdim}
68259698Sdim
69259698SdimLTOCodeGenerator::~LTOCodeGenerator() {
70259698Sdim  delete TargetMach;
71259698Sdim  delete NativeObjectFile;
72259698Sdim  TargetMach = NULL;
73259698Sdim  NativeObjectFile = NULL;
74259698Sdim
75259698Sdim  Linker.deleteModule();
76259698Sdim
77259698Sdim  for (std::vector<char *>::iterator I = CodegenOptions.begin(),
78259698Sdim                                     E = CodegenOptions.end();
79259698Sdim       I != E; ++I)
80259698Sdim    free(*I);
81259698Sdim}
82259698Sdim
83259698Sdim// Initialize LTO passes. Please keep this funciton in sync with
84259698Sdim// PassManagerBuilder::populateLTOPassManager(), and make sure all LTO
85259698Sdim// passes are initialized.
86259698Sdim//
87259698Sdimvoid LTOCodeGenerator::initializeLTOPasses() {
88259698Sdim  PassRegistry &R = *PassRegistry::getPassRegistry();
89259698Sdim
90259698Sdim  initializeInternalizePassPass(R);
91259698Sdim  initializeIPSCCPPass(R);
92259698Sdim  initializeGlobalOptPass(R);
93259698Sdim  initializeConstantMergePass(R);
94259698Sdim  initializeDAHPass(R);
95259698Sdim  initializeInstCombinerPass(R);
96259698Sdim  initializeSimpleInlinerPass(R);
97259698Sdim  initializePruneEHPass(R);
98259698Sdim  initializeGlobalDCEPass(R);
99259698Sdim  initializeArgPromotionPass(R);
100259698Sdim  initializeJumpThreadingPass(R);
101259698Sdim  initializeSROAPass(R);
102259698Sdim  initializeSROA_DTPass(R);
103259698Sdim  initializeSROA_SSAUpPass(R);
104259698Sdim  initializeFunctionAttrsPass(R);
105259698Sdim  initializeGlobalsModRefPass(R);
106259698Sdim  initializeLICMPass(R);
107259698Sdim  initializeGVNPass(R);
108259698Sdim  initializeMemCpyOptPass(R);
109259698Sdim  initializeDCEPass(R);
110259698Sdim  initializeCFGSimplifyPassPass(R);
111259698Sdim}
112259698Sdim
113259698Sdimbool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) {
114259698Sdim  bool ret = Linker.linkInModule(mod->getLLVVMModule(), &errMsg);
115259698Sdim
116259698Sdim  const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs();
117259698Sdim  for (int i = 0, e = undefs.size(); i != e; ++i)
118259698Sdim    AsmUndefinedRefs[undefs[i]] = 1;
119259698Sdim
120259698Sdim  return !ret;
121259698Sdim}
122259698Sdim
123259698Sdimvoid LTOCodeGenerator::setTargetOptions(TargetOptions options) {
124259698Sdim  Options.LessPreciseFPMADOption = options.LessPreciseFPMADOption;
125259698Sdim  Options.NoFramePointerElim = options.NoFramePointerElim;
126259698Sdim  Options.AllowFPOpFusion = options.AllowFPOpFusion;
127259698Sdim  Options.UnsafeFPMath = options.UnsafeFPMath;
128259698Sdim  Options.NoInfsFPMath = options.NoInfsFPMath;
129259698Sdim  Options.NoNaNsFPMath = options.NoNaNsFPMath;
130259698Sdim  Options.HonorSignDependentRoundingFPMathOption =
131259698Sdim    options.HonorSignDependentRoundingFPMathOption;
132259698Sdim  Options.UseSoftFloat = options.UseSoftFloat;
133259698Sdim  Options.FloatABIType = options.FloatABIType;
134259698Sdim  Options.NoZerosInBSS = options.NoZerosInBSS;
135259698Sdim  Options.GuaranteedTailCallOpt = options.GuaranteedTailCallOpt;
136259698Sdim  Options.DisableTailCalls = options.DisableTailCalls;
137259698Sdim  Options.StackAlignmentOverride = options.StackAlignmentOverride;
138259698Sdim  Options.TrapFuncName = options.TrapFuncName;
139259698Sdim  Options.PositionIndependentExecutable = options.PositionIndependentExecutable;
140259698Sdim  Options.EnableSegmentedStacks = options.EnableSegmentedStacks;
141259698Sdim  Options.UseInitArray = options.UseInitArray;
142259698Sdim}
143259698Sdim
144259698Sdimvoid LTOCodeGenerator::setDebugInfo(lto_debug_model debug) {
145259698Sdim  switch (debug) {
146259698Sdim  case LTO_DEBUG_MODEL_NONE:
147259698Sdim    EmitDwarfDebugInfo = false;
148259698Sdim    return;
149259698Sdim
150259698Sdim  case LTO_DEBUG_MODEL_DWARF:
151259698Sdim    EmitDwarfDebugInfo = true;
152259698Sdim    return;
153259698Sdim  }
154259698Sdim  llvm_unreachable("Unknown debug format!");
155259698Sdim}
156259698Sdim
157259698Sdimvoid LTOCodeGenerator::setCodePICModel(lto_codegen_model model) {
158259698Sdim  switch (model) {
159259698Sdim  case LTO_CODEGEN_PIC_MODEL_STATIC:
160259698Sdim  case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
161259698Sdim  case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
162259698Sdim    CodeModel = model;
163259698Sdim    return;
164259698Sdim  }
165259698Sdim  llvm_unreachable("Unknown PIC model!");
166259698Sdim}
167259698Sdim
168259698Sdimbool LTOCodeGenerator::writeMergedModules(const char *path,
169259698Sdim                                          std::string &errMsg) {
170259698Sdim  if (!determineTarget(errMsg))
171259698Sdim    return false;
172259698Sdim
173259698Sdim  // mark which symbols can not be internalized
174259698Sdim  applyScopeRestrictions();
175259698Sdim
176259698Sdim  // create output file
177259698Sdim  std::string ErrInfo;
178259698Sdim  tool_output_file Out(path, ErrInfo, sys::fs::F_Binary);
179259698Sdim  if (!ErrInfo.empty()) {
180259698Sdim    errMsg = "could not open bitcode file for writing: ";
181259698Sdim    errMsg += path;
182259698Sdim    return false;
183259698Sdim  }
184259698Sdim
185259698Sdim  // write bitcode to it
186259698Sdim  WriteBitcodeToFile(Linker.getModule(), Out.os());
187259698Sdim  Out.os().close();
188259698Sdim
189259698Sdim  if (Out.os().has_error()) {
190259698Sdim    errMsg = "could not write bitcode file: ";
191259698Sdim    errMsg += path;
192259698Sdim    Out.os().clear_error();
193259698Sdim    return false;
194259698Sdim  }
195259698Sdim
196259698Sdim  Out.keep();
197259698Sdim  return true;
198259698Sdim}
199259698Sdim
200259698Sdimbool LTOCodeGenerator::compile_to_file(const char** name,
201259698Sdim                                       bool disableOpt,
202259698Sdim                                       bool disableInline,
203259698Sdim                                       bool disableGVNLoadPRE,
204259698Sdim                                       std::string& errMsg) {
205259698Sdim  // make unique temp .o file to put generated object file
206259698Sdim  SmallString<128> Filename;
207259698Sdim  int FD;
208259698Sdim  error_code EC = sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename);
209259698Sdim  if (EC) {
210259698Sdim    errMsg = EC.message();
211259698Sdim    return false;
212259698Sdim  }
213259698Sdim
214259698Sdim  // generate object file
215259698Sdim  tool_output_file objFile(Filename.c_str(), FD);
216259698Sdim
217259698Sdim  bool genResult = generateObjectFile(objFile.os(), disableOpt, disableInline,
218259698Sdim                                      disableGVNLoadPRE, errMsg);
219259698Sdim  objFile.os().close();
220259698Sdim  if (objFile.os().has_error()) {
221259698Sdim    objFile.os().clear_error();
222259698Sdim    sys::fs::remove(Twine(Filename));
223259698Sdim    return false;
224259698Sdim  }
225259698Sdim
226259698Sdim  objFile.keep();
227259698Sdim  if (!genResult) {
228259698Sdim    sys::fs::remove(Twine(Filename));
229259698Sdim    return false;
230259698Sdim  }
231259698Sdim
232259698Sdim  NativeObjectPath = Filename.c_str();
233259698Sdim  *name = NativeObjectPath.c_str();
234259698Sdim  return true;
235259698Sdim}
236259698Sdim
237259698Sdimconst void* LTOCodeGenerator::compile(size_t* length,
238259698Sdim                                      bool disableOpt,
239259698Sdim                                      bool disableInline,
240259698Sdim                                      bool disableGVNLoadPRE,
241259698Sdim                                      std::string& errMsg) {
242259698Sdim  const char *name;
243259698Sdim  if (!compile_to_file(&name, disableOpt, disableInline, disableGVNLoadPRE,
244259698Sdim                       errMsg))
245259698Sdim    return NULL;
246259698Sdim
247259698Sdim  // remove old buffer if compile() called twice
248259698Sdim  delete NativeObjectFile;
249259698Sdim
250259698Sdim  // read .o file into memory buffer
251259698Sdim  OwningPtr<MemoryBuffer> BuffPtr;
252259698Sdim  if (error_code ec = MemoryBuffer::getFile(name, BuffPtr, -1, false)) {
253259698Sdim    errMsg = ec.message();
254259698Sdim    sys::fs::remove(NativeObjectPath);
255259698Sdim    return NULL;
256259698Sdim  }
257259698Sdim  NativeObjectFile = BuffPtr.take();
258259698Sdim
259259698Sdim  // remove temp files
260259698Sdim  sys::fs::remove(NativeObjectPath);
261259698Sdim
262259698Sdim  // return buffer, unless error
263259698Sdim  if (NativeObjectFile == NULL)
264259698Sdim    return NULL;
265259698Sdim  *length = NativeObjectFile->getBufferSize();
266259698Sdim  return NativeObjectFile->getBufferStart();
267259698Sdim}
268259698Sdim
269259698Sdimbool LTOCodeGenerator::determineTarget(std::string &errMsg) {
270259698Sdim  if (TargetMach != NULL)
271259698Sdim    return true;
272259698Sdim
273259698Sdim  std::string TripleStr = Linker.getModule()->getTargetTriple();
274259698Sdim  if (TripleStr.empty())
275259698Sdim    TripleStr = sys::getDefaultTargetTriple();
276259698Sdim  llvm::Triple Triple(TripleStr);
277259698Sdim
278259698Sdim  // create target machine from info for merged modules
279259698Sdim  const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg);
280259698Sdim  if (march == NULL)
281259698Sdim    return false;
282259698Sdim
283259698Sdim  // The relocation model is actually a static member of TargetMachine and
284259698Sdim  // needs to be set before the TargetMachine is instantiated.
285259698Sdim  Reloc::Model RelocModel = Reloc::Default;
286259698Sdim  switch (CodeModel) {
287259698Sdim  case LTO_CODEGEN_PIC_MODEL_STATIC:
288259698Sdim    RelocModel = Reloc::Static;
289259698Sdim    break;
290259698Sdim  case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
291259698Sdim    RelocModel = Reloc::PIC_;
292259698Sdim    break;
293259698Sdim  case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
294259698Sdim    RelocModel = Reloc::DynamicNoPIC;
295259698Sdim    break;
296259698Sdim  }
297259698Sdim
298259698Sdim  // construct LTOModule, hand over ownership of module and target
299259698Sdim  SubtargetFeatures Features;
300259698Sdim  Features.getDefaultSubtargetFeatures(Triple);
301259698Sdim  std::string FeatureStr = Features.getString();
302259698Sdim  // Set a default CPU for Darwin triples.
303259698Sdim  if (MCpu.empty() && Triple.isOSDarwin()) {
304259698Sdim    if (Triple.getArch() == llvm::Triple::x86_64)
305259698Sdim      MCpu = "core2";
306259698Sdim    else if (Triple.getArch() == llvm::Triple::x86)
307259698Sdim      MCpu = "yonah";
308259698Sdim  }
309259698Sdim
310259698Sdim  TargetMach = march->createTargetMachine(TripleStr, MCpu, FeatureStr, Options,
311259698Sdim                                          RelocModel, CodeModel::Default,
312259698Sdim                                          CodeGenOpt::Aggressive);
313259698Sdim  return true;
314259698Sdim}
315259698Sdim
316259698Sdimvoid LTOCodeGenerator::
317259698SdimapplyRestriction(GlobalValue &GV,
318259698Sdim                 const ArrayRef<StringRef> &Libcalls,
319259698Sdim                 std::vector<const char*> &MustPreserveList,
320259698Sdim                 SmallPtrSet<GlobalValue*, 8> &AsmUsed,
321259698Sdim                 Mangler &Mangler) {
322259698Sdim  SmallString<64> Buffer;
323259698Sdim  Mangler.getNameWithPrefix(Buffer, &GV, false);
324259698Sdim
325259698Sdim  if (GV.isDeclaration())
326259698Sdim    return;
327259698Sdim  if (MustPreserveSymbols.count(Buffer))
328259698Sdim    MustPreserveList.push_back(GV.getName().data());
329259698Sdim  if (AsmUndefinedRefs.count(Buffer))
330259698Sdim    AsmUsed.insert(&GV);
331259698Sdim
332259698Sdim  // Conservatively append user-supplied runtime library functions to
333259698Sdim  // llvm.compiler.used.  These could be internalized and deleted by
334259698Sdim  // optimizations like -globalopt, causing problems when later optimizations
335259698Sdim  // add new library calls (e.g., llvm.memset => memset and printf => puts).
336259698Sdim  // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
337259698Sdim  if (isa<Function>(GV) &&
338259698Sdim      std::binary_search(Libcalls.begin(), Libcalls.end(), GV.getName()))
339259698Sdim    AsmUsed.insert(&GV);
340259698Sdim}
341259698Sdim
342259698Sdimstatic void findUsedValues(GlobalVariable *LLVMUsed,
343259698Sdim                           SmallPtrSet<GlobalValue*, 8> &UsedValues) {
344259698Sdim  if (LLVMUsed == 0) return;
345259698Sdim
346259698Sdim  ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
347259698Sdim  for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
348259698Sdim    if (GlobalValue *GV =
349259698Sdim        dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
350259698Sdim      UsedValues.insert(GV);
351259698Sdim}
352259698Sdim
353259698Sdimstatic void accumulateAndSortLibcalls(std::vector<StringRef> &Libcalls,
354259698Sdim                                      const TargetLibraryInfo& TLI,
355259698Sdim                                      const TargetLowering *Lowering)
356259698Sdim{
357259698Sdim  // TargetLibraryInfo has info on C runtime library calls on the current
358259698Sdim  // target.
359259698Sdim  for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
360259698Sdim       I != E; ++I) {
361259698Sdim    LibFunc::Func F = static_cast<LibFunc::Func>(I);
362259698Sdim    if (TLI.has(F))
363259698Sdim      Libcalls.push_back(TLI.getName(F));
364259698Sdim  }
365259698Sdim
366259698Sdim  // TargetLowering has info on library calls that CodeGen expects to be
367259698Sdim  // available, both from the C runtime and compiler-rt.
368259698Sdim  if (Lowering)
369259698Sdim    for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
370259698Sdim         I != E; ++I)
371259698Sdim      if (const char *Name
372259698Sdim          = Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
373259698Sdim        Libcalls.push_back(Name);
374259698Sdim
375259698Sdim  array_pod_sort(Libcalls.begin(), Libcalls.end());
376259698Sdim  Libcalls.erase(std::unique(Libcalls.begin(), Libcalls.end()),
377259698Sdim                 Libcalls.end());
378259698Sdim}
379259698Sdim
380259698Sdimvoid LTOCodeGenerator::applyScopeRestrictions() {
381259698Sdim  if (ScopeRestrictionsDone)
382259698Sdim    return;
383259698Sdim  Module *mergedModule = Linker.getModule();
384259698Sdim
385259698Sdim  // Start off with a verification pass.
386259698Sdim  PassManager passes;
387259698Sdim  passes.add(createVerifierPass());
388259698Sdim
389259698Sdim  // mark which symbols can not be internalized
390259698Sdim  Mangler Mangler(TargetMach);
391259698Sdim  std::vector<const char*> MustPreserveList;
392259698Sdim  SmallPtrSet<GlobalValue*, 8> AsmUsed;
393259698Sdim  std::vector<StringRef> Libcalls;
394259698Sdim  TargetLibraryInfo TLI(Triple(TargetMach->getTargetTriple()));
395259698Sdim  accumulateAndSortLibcalls(Libcalls, TLI, TargetMach->getTargetLowering());
396259698Sdim
397259698Sdim  for (Module::iterator f = mergedModule->begin(),
398259698Sdim         e = mergedModule->end(); f != e; ++f)
399259698Sdim    applyRestriction(*f, Libcalls, MustPreserveList, AsmUsed, Mangler);
400259698Sdim  for (Module::global_iterator v = mergedModule->global_begin(),
401259698Sdim         e = mergedModule->global_end(); v !=  e; ++v)
402259698Sdim    applyRestriction(*v, Libcalls, MustPreserveList, AsmUsed, Mangler);
403259698Sdim  for (Module::alias_iterator a = mergedModule->alias_begin(),
404259698Sdim         e = mergedModule->alias_end(); a != e; ++a)
405259698Sdim    applyRestriction(*a, Libcalls, MustPreserveList, AsmUsed, Mangler);
406259698Sdim
407259698Sdim  GlobalVariable *LLVMCompilerUsed =
408259698Sdim    mergedModule->getGlobalVariable("llvm.compiler.used");
409259698Sdim  findUsedValues(LLVMCompilerUsed, AsmUsed);
410259698Sdim  if (LLVMCompilerUsed)
411259698Sdim    LLVMCompilerUsed->eraseFromParent();
412259698Sdim
413259698Sdim  if (!AsmUsed.empty()) {
414259698Sdim    llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(Context);
415259698Sdim    std::vector<Constant*> asmUsed2;
416259698Sdim    for (SmallPtrSet<GlobalValue*, 16>::const_iterator i = AsmUsed.begin(),
417259698Sdim           e = AsmUsed.end(); i !=e; ++i) {
418259698Sdim      GlobalValue *GV = *i;
419259698Sdim      Constant *c = ConstantExpr::getBitCast(GV, i8PTy);
420259698Sdim      asmUsed2.push_back(c);
421259698Sdim    }
422259698Sdim
423259698Sdim    llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size());
424259698Sdim    LLVMCompilerUsed =
425259698Sdim      new llvm::GlobalVariable(*mergedModule, ATy, false,
426259698Sdim                               llvm::GlobalValue::AppendingLinkage,
427259698Sdim                               llvm::ConstantArray::get(ATy, asmUsed2),
428259698Sdim                               "llvm.compiler.used");
429259698Sdim
430259698Sdim    LLVMCompilerUsed->setSection("llvm.metadata");
431259698Sdim  }
432259698Sdim
433259698Sdim  passes.add(createInternalizePass(MustPreserveList));
434259698Sdim
435259698Sdim  // apply scope restrictions
436259698Sdim  passes.run(*mergedModule);
437259698Sdim
438259698Sdim  ScopeRestrictionsDone = true;
439259698Sdim}
440259698Sdim
441259698Sdim/// Optimize merged modules using various IPO passes
442259698Sdimbool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
443259698Sdim                                          bool DisableOpt,
444259698Sdim                                          bool DisableInline,
445259698Sdim                                          bool DisableGVNLoadPRE,
446259698Sdim                                          std::string &errMsg) {
447259698Sdim  if (!this->determineTarget(errMsg))
448259698Sdim    return false;
449259698Sdim
450259698Sdim  Module *mergedModule = Linker.getModule();
451259698Sdim
452259698Sdim  // Mark which symbols can not be internalized
453259698Sdim  this->applyScopeRestrictions();
454259698Sdim
455259698Sdim  // Instantiate the pass manager to organize the passes.
456259698Sdim  PassManager passes;
457259698Sdim
458259698Sdim  // Start off with a verification pass.
459259698Sdim  passes.add(createVerifierPass());
460259698Sdim
461259698Sdim  // Add an appropriate DataLayout instance for this module...
462259698Sdim  passes.add(new DataLayout(*TargetMach->getDataLayout()));
463259698Sdim  TargetMach->addAnalysisPasses(passes);
464259698Sdim
465259698Sdim  // Enabling internalize here would use its AllButMain variant. It
466259698Sdim  // keeps only main if it exists and does nothing for libraries. Instead
467259698Sdim  // we create the pass ourselves with the symbol list provided by the linker.
468259698Sdim  if (!DisableOpt)
469259698Sdim    PassManagerBuilder().populateLTOPassManager(passes,
470259698Sdim                                              /*Internalize=*/false,
471259698Sdim                                              !DisableInline,
472259698Sdim                                              DisableGVNLoadPRE);
473259698Sdim
474259698Sdim  // Make sure everything is still good.
475259698Sdim  passes.add(createVerifierPass());
476259698Sdim
477259698Sdim  PassManager codeGenPasses;
478259698Sdim
479259698Sdim  codeGenPasses.add(new DataLayout(*TargetMach->getDataLayout()));
480259698Sdim  TargetMach->addAnalysisPasses(codeGenPasses);
481259698Sdim
482259698Sdim  formatted_raw_ostream Out(out);
483259698Sdim
484259698Sdim  // If the bitcode files contain ARC code and were compiled with optimization,
485259698Sdim  // the ObjCARCContractPass must be run, so do it unconditionally here.
486259698Sdim  codeGenPasses.add(createObjCARCContractPass());
487259698Sdim
488259698Sdim  if (TargetMach->addPassesToEmitFile(codeGenPasses, Out,
489259698Sdim                                      TargetMachine::CGFT_ObjectFile)) {
490259698Sdim    errMsg = "target file type not supported";
491259698Sdim    return false;
492259698Sdim  }
493259698Sdim
494259698Sdim  // Run our queue of passes all at once now, efficiently.
495259698Sdim  passes.run(*mergedModule);
496259698Sdim
497259698Sdim  // Run the code generator, and write assembly file
498259698Sdim  codeGenPasses.run(*mergedModule);
499259698Sdim
500259698Sdim  return true;
501259698Sdim}
502259698Sdim
503259698Sdim/// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging
504259698Sdim/// LTO problems.
505259698Sdimvoid LTOCodeGenerator::setCodeGenDebugOptions(const char *options) {
506259698Sdim  for (std::pair<StringRef, StringRef> o = getToken(options);
507259698Sdim       !o.first.empty(); o = getToken(o.second)) {
508259698Sdim    // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add
509259698Sdim    // that.
510259698Sdim    if (CodegenOptions.empty())
511259698Sdim      CodegenOptions.push_back(strdup("libLLVMLTO"));
512259698Sdim    CodegenOptions.push_back(strdup(o.first.str().c_str()));
513259698Sdim  }
514259698Sdim}
515259698Sdim
516259698Sdimvoid LTOCodeGenerator::parseCodeGenDebugOptions() {
517259698Sdim  // if options were requested, set them
518259698Sdim  if (!CodegenOptions.empty())
519259698Sdim    cl::ParseCommandLineOptions(CodegenOptions.size(),
520259698Sdim                                const_cast<char **>(&CodegenOptions[0]));
521259698Sdim}
522