lto.cpp revision f3ef5332fa3f4d5ec72c178a2b19dac363a19383
1//===-lto.cpp - LLVM Link Time Optimizer ----------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Link Time Optimization library. This library is
11// intended to be used by linker to optimize code at link time.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm-c/lto.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/CodeGen/CommandFlags.h"
18#include "llvm/IR/DiagnosticInfo.h"
19#include "llvm/IR/DiagnosticPrinter.h"
20#include "llvm/IR/LLVMContext.h"
21#include "llvm/LTO/LTOCodeGenerator.h"
22#include "llvm/LTO/LTOModule.h"
23#include "llvm/Support/MemoryBuffer.h"
24#include "llvm/Support/Signals.h"
25#include "llvm/Support/TargetSelect.h"
26
27// extra command-line flags needed for LTOCodeGenerator
28static cl::opt<char>
29OptLevel("O",
30         cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
31                  "(default = '-O2')"),
32         cl::Prefix,
33         cl::ZeroOrMore,
34         cl::init('2'));
35
36static cl::opt<bool>
37DisableInline("disable-inlining", cl::init(false),
38  cl::desc("Do not run the inliner pass"));
39
40static cl::opt<bool>
41DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false),
42  cl::desc("Do not run the GVN load PRE pass"));
43
44static cl::opt<bool>
45DisableLTOVectorization("disable-lto-vectorization", cl::init(false),
46  cl::desc("Do not run loop or slp vectorization during LTO"));
47
48#ifdef NDEBUG
49static bool VerifyByDefault = false;
50#else
51static bool VerifyByDefault = true;
52#endif
53
54static cl::opt<bool> DisableVerify(
55    "disable-llvm-verifier", cl::init(!VerifyByDefault),
56    cl::desc("Don't run the LLVM verifier during the optimization pipeline"));
57
58// Holds most recent error string.
59// *** Not thread safe ***
60static std::string sLastErrorString;
61
62// Holds the initialization state of the LTO module.
63// *** Not thread safe ***
64static bool initialized = false;
65
66// Holds the command-line option parsing state of the LTO module.
67static bool parsedOptions = false;
68
69static LLVMContext *LTOContext = nullptr;
70
71static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
72  if (DI.getSeverity() != DS_Error) {
73    DiagnosticPrinterRawOStream DP(errs());
74    DI.print(DP);
75    errs() << '\n';
76    return;
77  }
78  sLastErrorString = "";
79  {
80    raw_string_ostream Stream(sLastErrorString);
81    DiagnosticPrinterRawOStream DP(Stream);
82    DI.print(DP);
83  }
84  sLastErrorString += '\n';
85}
86
87// Initialize the configured targets if they have not been initialized.
88static void lto_initialize() {
89  if (!initialized) {
90#ifdef LLVM_ON_WIN32
91    // Dialog box on crash disabling doesn't work across DLL boundaries, so do
92    // it here.
93    llvm::sys::DisableSystemDialogsOnCrash();
94#endif
95
96    InitializeAllTargetInfos();
97    InitializeAllTargets();
98    InitializeAllTargetMCs();
99    InitializeAllAsmParsers();
100    InitializeAllAsmPrinters();
101    InitializeAllDisassemblers();
102
103    LTOContext = &getGlobalContext();
104    LTOContext->setDiagnosticHandler(diagnosticHandler, nullptr, true);
105    initialized = true;
106  }
107}
108
109namespace {
110
111static void handleLibLTODiagnostic(lto_codegen_diagnostic_severity_t Severity,
112                                   const char *Msg, void *) {
113  sLastErrorString = Msg;
114  sLastErrorString += "\n";
115}
116
117// This derived class owns the native object file. This helps implement the
118// libLTO API semantics, which require that the code generator owns the object
119// file.
120struct LibLTOCodeGenerator : LTOCodeGenerator {
121  LibLTOCodeGenerator() : LTOCodeGenerator(*LTOContext) {
122    setDiagnosticHandler(handleLibLTODiagnostic, nullptr); }
123  LibLTOCodeGenerator(std::unique_ptr<LLVMContext> Context)
124      : LTOCodeGenerator(*Context), OwnedContext(std::move(Context)) {
125    setDiagnosticHandler(handleLibLTODiagnostic, nullptr); }
126
127  // Reset the module first in case MergedModule is created in OwnedContext.
128  // Module must be destructed before its context gets destructed.
129  ~LibLTOCodeGenerator() { resetMergedModule(); }
130
131  std::unique_ptr<MemoryBuffer> NativeObjectFile;
132  std::unique_ptr<LLVMContext> OwnedContext;
133};
134
135}
136
137DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LibLTOCodeGenerator, lto_code_gen_t)
138DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t)
139
140// Convert the subtarget features into a string to pass to LTOCodeGenerator.
141static void lto_add_attrs(lto_code_gen_t cg) {
142  LTOCodeGenerator *CG = unwrap(cg);
143  if (MAttrs.size()) {
144    std::string attrs;
145    for (unsigned i = 0; i < MAttrs.size(); ++i) {
146      if (i > 0)
147        attrs.append(",");
148      attrs.append(MAttrs[i]);
149    }
150
151    CG->setAttr(attrs.c_str());
152  }
153
154  if (OptLevel < '0' || OptLevel > '3')
155    report_fatal_error("Optimization level must be between 0 and 3");
156  CG->setOptLevel(OptLevel - '0');
157}
158
159extern const char* lto_get_version() {
160  return LTOCodeGenerator::getVersionString();
161}
162
163const char* lto_get_error_message() {
164  return sLastErrorString.c_str();
165}
166
167bool lto_module_is_object_file(const char* path) {
168  return LTOModule::isBitcodeFile(path);
169}
170
171bool lto_module_is_object_file_for_target(const char* path,
172                                          const char* target_triplet_prefix) {
173  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer = MemoryBuffer::getFile(path);
174  if (!Buffer)
175    return false;
176  return LTOModule::isBitcodeForTarget(Buffer->get(), target_triplet_prefix);
177}
178
179bool lto_module_is_object_file_in_memory(const void* mem, size_t length) {
180  return LTOModule::isBitcodeFile(mem, length);
181}
182
183bool
184lto_module_is_object_file_in_memory_for_target(const void* mem,
185                                            size_t length,
186                                            const char* target_triplet_prefix) {
187  std::unique_ptr<MemoryBuffer> buffer(LTOModule::makeBuffer(mem, length));
188  if (!buffer)
189    return false;
190  return LTOModule::isBitcodeForTarget(buffer.get(), target_triplet_prefix);
191}
192
193lto_module_t lto_module_create(const char* path) {
194  lto_initialize();
195  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
196  ErrorOr<std::unique_ptr<LTOModule>> M =
197      LTOModule::createFromFile(*LTOContext, path, Options);
198  if (!M)
199    return nullptr;
200  return wrap(M->release());
201}
202
203lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) {
204  lto_initialize();
205  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
206  ErrorOr<std::unique_ptr<LTOModule>> M =
207      LTOModule::createFromOpenFile(*LTOContext, fd, path, size, Options);
208  if (!M)
209    return nullptr;
210  return wrap(M->release());
211}
212
213lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path,
214                                                 size_t file_size,
215                                                 size_t map_size,
216                                                 off_t offset) {
217  lto_initialize();
218  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
219  ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromOpenFileSlice(
220      *LTOContext, fd, path, map_size, offset, Options);
221  if (!M)
222    return nullptr;
223  return wrap(M->release());
224}
225
226lto_module_t lto_module_create_from_memory(const void* mem, size_t length) {
227  lto_initialize();
228  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
229  ErrorOr<std::unique_ptr<LTOModule>> M =
230      LTOModule::createFromBuffer(*LTOContext, mem, length, Options);
231  if (!M)
232    return nullptr;
233  return wrap(M->release());
234}
235
236lto_module_t lto_module_create_from_memory_with_path(const void* mem,
237                                                     size_t length,
238                                                     const char *path) {
239  lto_initialize();
240  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
241  ErrorOr<std::unique_ptr<LTOModule>> M =
242      LTOModule::createFromBuffer(*LTOContext, mem, length, Options, path);
243  if (!M)
244    return nullptr;
245  return wrap(M->release());
246}
247
248lto_module_t lto_module_create_in_local_context(const void *mem, size_t length,
249                                                const char *path) {
250  lto_initialize();
251  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
252  ErrorOr<std::unique_ptr<LTOModule>> M =
253      LTOModule::createInLocalContext(mem, length, Options, path);
254  if (!M)
255    return nullptr;
256  return wrap(M->release());
257}
258
259lto_module_t lto_module_create_in_codegen_context(const void *mem,
260                                                  size_t length,
261                                                  const char *path,
262                                                  lto_code_gen_t cg) {
263  lto_initialize();
264  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
265  ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createInContext(
266      mem, length, Options, path, &unwrap(cg)->getContext());
267  return wrap(M->release());
268}
269
270void lto_module_dispose(lto_module_t mod) { delete unwrap(mod); }
271
272const char* lto_module_get_target_triple(lto_module_t mod) {
273  return unwrap(mod)->getTargetTriple().c_str();
274}
275
276void lto_module_set_target_triple(lto_module_t mod, const char *triple) {
277  return unwrap(mod)->setTargetTriple(triple);
278}
279
280unsigned int lto_module_get_num_symbols(lto_module_t mod) {
281  return unwrap(mod)->getSymbolCount();
282}
283
284const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) {
285  return unwrap(mod)->getSymbolName(index);
286}
287
288lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
289                                                      unsigned int index) {
290  return unwrap(mod)->getSymbolAttributes(index);
291}
292
293const char* lto_module_get_linkeropts(lto_module_t mod) {
294  return unwrap(mod)->getLinkerOpts();
295}
296
297void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
298                                        lto_diagnostic_handler_t diag_handler,
299                                        void *ctxt) {
300  unwrap(cg)->setDiagnosticHandler(diag_handler, ctxt);
301}
302
303static lto_code_gen_t createCodeGen(bool InLocalContext) {
304  lto_initialize();
305
306  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
307
308  LibLTOCodeGenerator *CodeGen =
309      InLocalContext ? new LibLTOCodeGenerator(make_unique<LLVMContext>())
310                     : new LibLTOCodeGenerator();
311  CodeGen->setTargetOptions(Options);
312  return wrap(CodeGen);
313}
314
315lto_code_gen_t lto_codegen_create(void) {
316  return createCodeGen(/* InLocalContext */ false);
317}
318
319lto_code_gen_t lto_codegen_create_in_local_context(void) {
320  return createCodeGen(/* InLocalContext */ true);
321}
322
323void lto_codegen_dispose(lto_code_gen_t cg) { delete unwrap(cg); }
324
325bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) {
326  return !unwrap(cg)->addModule(unwrap(mod));
327}
328
329void lto_codegen_set_module(lto_code_gen_t cg, lto_module_t mod) {
330  unwrap(cg)->setModule(std::unique_ptr<LTOModule>(unwrap(mod)));
331}
332
333bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) {
334  unwrap(cg)->setDebugInfo(debug);
335  return false;
336}
337
338bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) {
339  switch (model) {
340  case LTO_CODEGEN_PIC_MODEL_STATIC:
341    unwrap(cg)->setCodePICModel(Reloc::Static);
342    return false;
343  case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
344    unwrap(cg)->setCodePICModel(Reloc::PIC_);
345    return false;
346  case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
347    unwrap(cg)->setCodePICModel(Reloc::DynamicNoPIC);
348    return false;
349  case LTO_CODEGEN_PIC_MODEL_DEFAULT:
350    unwrap(cg)->setCodePICModel(Reloc::Default);
351    return false;
352  }
353  sLastErrorString = "Unknown PIC model";
354  return true;
355}
356
357void lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu) {
358  return unwrap(cg)->setCpu(cpu);
359}
360
361void lto_codegen_set_assembler_path(lto_code_gen_t cg, const char *path) {
362  // In here only for backwards compatibility. We use MC now.
363}
364
365void lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
366                                    int nargs) {
367  // In here only for backwards compatibility. We use MC now.
368}
369
370void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg,
371                                          const char *symbol) {
372  unwrap(cg)->addMustPreserveSymbol(symbol);
373}
374
375static void maybeParseOptions(lto_code_gen_t cg) {
376  if (!parsedOptions) {
377    unwrap(cg)->parseCodeGenDebugOptions();
378    lto_add_attrs(cg);
379    parsedOptions = true;
380  }
381}
382
383bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
384  maybeParseOptions(cg);
385  return !unwrap(cg)->writeMergedModules(path);
386}
387
388const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
389  maybeParseOptions(cg);
390  LibLTOCodeGenerator *CG = unwrap(cg);
391  CG->NativeObjectFile =
392      CG->compile(DisableVerify, DisableInline, DisableGVNLoadPRE,
393                  DisableLTOVectorization);
394  if (!CG->NativeObjectFile)
395    return nullptr;
396  *length = CG->NativeObjectFile->getBufferSize();
397  return CG->NativeObjectFile->getBufferStart();
398}
399
400bool lto_codegen_optimize(lto_code_gen_t cg) {
401  maybeParseOptions(cg);
402  return !unwrap(cg)->optimize(DisableVerify, DisableInline, DisableGVNLoadPRE,
403                               DisableLTOVectorization);
404}
405
406const void *lto_codegen_compile_optimized(lto_code_gen_t cg, size_t *length) {
407  maybeParseOptions(cg);
408  LibLTOCodeGenerator *CG = unwrap(cg);
409  CG->NativeObjectFile = CG->compileOptimized();
410  if (!CG->NativeObjectFile)
411    return nullptr;
412  *length = CG->NativeObjectFile->getBufferSize();
413  return CG->NativeObjectFile->getBufferStart();
414}
415
416bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
417  maybeParseOptions(cg);
418  return !unwrap(cg)->compile_to_file(
419      name, DisableVerify, DisableInline, DisableGVNLoadPRE,
420      DisableLTOVectorization);
421}
422
423void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {
424  unwrap(cg)->setCodeGenDebugOptions(opt);
425}
426
427unsigned int lto_api_version() { return LTO_API_VERSION; }
428
429void lto_codegen_set_should_internalize(lto_code_gen_t cg,
430                                        bool ShouldInternalize) {
431  unwrap(cg)->setShouldInternalize(ShouldInternalize);
432}
433
434void lto_codegen_set_should_embed_uselists(lto_code_gen_t cg,
435                                           lto_bool_t ShouldEmbedUselists) {
436  unwrap(cg)->setShouldEmbedUselists(ShouldEmbedUselists);
437}
438