1259698Sdim//===-LTOCodeGenerator.h - 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 declares the LTOCodeGenerator class.
11259698Sdim//
12259698Sdim//   LTO compilation consists of three phases: Pre-IPO, IPO and Post-IPO.
13259698Sdim//
14259698Sdim//   The Pre-IPO phase compiles source code into bitcode file. The resulting
15259698Sdim// bitcode files, along with object files and libraries, will be fed to the
16259698Sdim// linker to through the IPO and Post-IPO phases. By using obj-file extension,
17259698Sdim// the resulting bitcode file disguises itself as an object file, and therefore
18259698Sdim// obviates the need of writing a special set of the make-rules only for LTO
19259698Sdim// compilation.
20259698Sdim//
21259698Sdim//   The IPO phase perform inter-procedural analyses and optimizations, and
22259698Sdim// the Post-IPO consists two sub-phases: intra-procedural scalar optimizations
23259698Sdim// (SOPT), and intra-procedural target-dependent code generator (CG).
24259698Sdim//
25259698Sdim//   As of this writing, we don't separate IPO and the Post-IPO SOPT. They
26259698Sdim// are intermingled together, and are driven by a single pass manager (see
27259698Sdim// PassManagerBuilder::populateLTOPassManager()).
28259698Sdim//
29259698Sdim//   The "LTOCodeGenerator" is the driver for the IPO and Post-IPO stages.
30259698Sdim// The "CodeGenerator" here is bit confusing. Don't confuse the "CodeGenerator"
31259698Sdim// with the machine specific code generator.
32259698Sdim//
33259698Sdim//===----------------------------------------------------------------------===//
34259698Sdim
35259698Sdim#ifndef LTO_CODE_GENERATOR_H
36259698Sdim#define LTO_CODE_GENERATOR_H
37259698Sdim
38259698Sdim#include "llvm-c/lto.h"
39259698Sdim#include "llvm/ADT/SmallPtrSet.h"
40259698Sdim#include "llvm/ADT/StringMap.h"
41259698Sdim#include "llvm/ADT/ArrayRef.h"
42259698Sdim#include "llvm/Linker.h"
43259698Sdim#include "llvm/Target/TargetOptions.h"
44259698Sdim#include <string>
45259698Sdim#include <vector>
46259698Sdim
47259698Sdimnamespace llvm {
48259698Sdim  class LLVMContext;
49259698Sdim  class GlobalValue;
50259698Sdim  class Mangler;
51259698Sdim  class MemoryBuffer;
52259698Sdim  class TargetLibraryInfo;
53259698Sdim  class TargetMachine;
54259698Sdim  class raw_ostream;
55259698Sdim}
56259698Sdim
57259698Sdim//===----------------------------------------------------------------------===//
58259698Sdim/// LTOCodeGenerator - C++ class which implements the opaque lto_code_gen_t
59259698Sdim/// type.
60259698Sdim///
61259698Sdimstruct LTOCodeGenerator {
62259698Sdim  static const char *getVersionString();
63259698Sdim
64259698Sdim  LTOCodeGenerator();
65259698Sdim  ~LTOCodeGenerator();
66259698Sdim
67259698Sdim  // Merge given module, return true on success.
68259698Sdim  bool addModule(struct LTOModule*, std::string &errMsg);
69259698Sdim
70259698Sdim  void setTargetOptions(llvm::TargetOptions options);
71259698Sdim  void setDebugInfo(lto_debug_model);
72259698Sdim  void setCodePICModel(lto_codegen_model);
73259698Sdim
74259698Sdim  void setCpu(const char *mCpu) { MCpu = mCpu; }
75259698Sdim
76259698Sdim  void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; }
77259698Sdim
78259698Sdim  // To pass options to the driver and optimization passes. These options are
79259698Sdim  // not necessarily for debugging purpose (The function name is misleading).
80259698Sdim  // This function should be called before LTOCodeGenerator::compilexxx(),
81259698Sdim  // and LTOCodeGenerator::writeMergedModules().
82259698Sdim  //
83259698Sdim  void setCodeGenDebugOptions(const char *opts);
84259698Sdim
85259698Sdim  // Parse the options set in setCodeGenDebugOptions. Like
86259698Sdim  // setCodeGenDebugOptions, this must be called before
87259698Sdim  // LTOCodeGenerator::compilexxx() and LTOCodeGenerator::writeMergedModules()
88259698Sdim  void parseCodeGenDebugOptions();
89259698Sdim
90259698Sdim  // Write the merged module to the file specified by the given path.
91259698Sdim  // Return true on success.
92259698Sdim  bool writeMergedModules(const char *path, std::string &errMsg);
93259698Sdim
94259698Sdim  // Compile the merged module into a *single* object file; the path to object
95259698Sdim  // file is returned to the caller via argument "name". Return true on
96259698Sdim  // success.
97259698Sdim  //
98259698Sdim  // NOTE that it is up to the linker to remove the intermediate object file.
99259698Sdim  //  Do not try to remove the object file in LTOCodeGenerator's destructor
100259698Sdim  //  as we don't who (LTOCodeGenerator or the obj file) will last longer.
101259698Sdim  //
102259698Sdim  bool compile_to_file(const char **name,
103259698Sdim                       bool disableOpt,
104259698Sdim                       bool disableInline,
105259698Sdim                       bool disableGVNLoadPRE,
106259698Sdim                       std::string &errMsg);
107259698Sdim
108259698Sdim  // As with compile_to_file(), this function compiles the merged module into
109259698Sdim  // single object file. Instead of returning the object-file-path to the caller
110259698Sdim  // (linker), it brings the object to a buffer, and return the buffer to the
111259698Sdim  // caller. This function should delete intermediate object file once its content
112259698Sdim  // is brought to memory. Return NULL if the compilation was not successful.
113259698Sdim  //
114259698Sdim  const void *compile(size_t *length,
115259698Sdim                      bool disableOpt,
116259698Sdim                      bool disableInline,
117259698Sdim                      bool disableGVNLoadPRE,
118259698Sdim                      std::string &errMsg);
119259698Sdim
120259698Sdimprivate:
121259698Sdim  void initializeLTOPasses();
122259698Sdim
123259698Sdim  bool generateObjectFile(llvm::raw_ostream &out,
124259698Sdim                          bool disableOpt,
125259698Sdim                          bool disableInline,
126259698Sdim                          bool disableGVNLoadPRE,
127259698Sdim                          std::string &errMsg);
128259698Sdim  void applyScopeRestrictions();
129259698Sdim  void applyRestriction(llvm::GlobalValue &GV,
130259698Sdim                        const llvm::ArrayRef<llvm::StringRef> &Libcalls,
131259698Sdim                        std::vector<const char*> &MustPreserveList,
132259698Sdim                        llvm::SmallPtrSet<llvm::GlobalValue*, 8> &AsmUsed,
133259698Sdim                        llvm::Mangler &Mangler);
134259698Sdim  bool determineTarget(std::string &errMsg);
135259698Sdim
136259698Sdim  typedef llvm::StringMap<uint8_t> StringSet;
137259698Sdim
138259698Sdim  llvm::LLVMContext &Context;
139259698Sdim  llvm::Linker Linker;
140259698Sdim  llvm::TargetMachine *TargetMach;
141259698Sdim  bool EmitDwarfDebugInfo;
142259698Sdim  bool ScopeRestrictionsDone;
143259698Sdim  lto_codegen_model CodeModel;
144259698Sdim  StringSet MustPreserveSymbols;
145259698Sdim  StringSet AsmUndefinedRefs;
146259698Sdim  llvm::MemoryBuffer *NativeObjectFile;
147259698Sdim  std::vector<char *> CodegenOptions;
148259698Sdim  std::string MCpu;
149259698Sdim  std::string NativeObjectPath;
150259698Sdim  llvm::TargetOptions Options;
151259698Sdim};
152259698Sdim
153259698Sdim#endif // LTO_CODE_GENERATOR_H
154