177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===-lto.cpp - LLVM Link Time Optimizer ----------------------------------===//
277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//
377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//                     The LLVM Compiler Infrastructure
477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//
577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// This file is distributed under the University of Illinois Open Source
677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// License. See LICENSE.TXT for details.
78fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling//
877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===----------------------------------------------------------------------===//
977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//
108fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling// This file implements the Link Time Optimization library. This library is
1177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// intended to be used by linker to optimize code at link time.
1277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//
1377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===----------------------------------------------------------------------===//
1477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
1577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm-c/lto.h"
164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/STLExtras.h"
17c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/CodeGen/CommandFlags.h"
18cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/IR/DiagnosticInfo.h"
19cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/IR/DiagnosticPrinter.h"
20ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/LLVMContext.h"
21cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne#include "llvm/LTO/LTOCodeGenerator.h"
22cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne#include "llvm/LTO/LTOModule.h"
23c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/MemoryBuffer.h"
24ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/Signals.h"
25c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/TargetSelect.h"
2677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
27c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola// extra command-line flags needed for LTOCodeGenerator
284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<char>
294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarOptLevel("O",
304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar         cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                  "(default = '-O2')"),
324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar         cl::Prefix,
334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar         cl::ZeroOrMore,
344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar         cl::init('2'));
35c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola
36c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindolastatic cl::opt<bool>
37c13c9e5a9d288eac494a38f0710d34446167f940Rafael EspindolaDisableInline("disable-inlining", cl::init(false),
38c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola  cl::desc("Do not run the inliner pass"));
39c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola
40c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindolastatic cl::opt<bool>
41c13c9e5a9d288eac494a38f0710d34446167f940Rafael EspindolaDisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false),
42c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola  cl::desc("Do not run the GVN load PRE pass"));
4377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<bool>
4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDisableLTOVectorization("disable-lto-vectorization", cl::init(false),
4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  cl::desc("Do not run loop or slp vectorization during LTO"));
4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
48cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#ifdef NDEBUG
49cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic bool VerifyByDefault = false;
50cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#else
51cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic bool VerifyByDefault = true;
52cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#endif
53cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
54cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic cl::opt<bool> DisableVerify(
55cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    "disable-llvm-verifier", cl::init(!VerifyByDefault),
56cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    cl::desc("Don't run the LLVM verifier during the optimization pipeline"));
57cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
588fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling// Holds most recent error string.
598fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling// *** Not thread safe ***
6077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikstatic std::string sLastErrorString;
6177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
62cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne// Holds the initialization state of the LTO module.
63cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne// *** Not thread safe ***
64cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbournestatic bool initialized = false;
65cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne
660e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola// Holds the command-line option parsing state of the LTO module.
670e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindolastatic bool parsedOptions = false;
680e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola
69cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic LLVMContext *LTOContext = nullptr;
70cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
71cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
72cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (DI.getSeverity() != DS_Error) {
73cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    DiagnosticPrinterRawOStream DP(errs());
74cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    DI.print(DP);
75cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    errs() << '\n';
76cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return;
77cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
78cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  sLastErrorString = "";
79cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  {
80cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    raw_string_ostream Stream(sLastErrorString);
81cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    DiagnosticPrinterRawOStream DP(Stream);
82cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    DI.print(DP);
83cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
84cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  sLastErrorString += '\n';
85cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
86cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
87cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne// Initialize the configured targets if they have not been initialized.
88cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbournestatic void lto_initialize() {
89cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  if (!initialized) {
90ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#ifdef LLVM_ON_WIN32
91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Dialog box on crash disabling doesn't work across DLL boundaries, so do
92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // it here.
93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    llvm::sys::DisableSystemDialogsOnCrash();
94ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#endif
95ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
96c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllTargetInfos();
97c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllTargets();
98c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllTargetMCs();
99c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllAsmParsers();
100c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllAsmPrinters();
101c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllDisassemblers();
102cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
103cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    LTOContext = &getGlobalContext();
104cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    LTOContext->setDiagnosticHandler(diagnosticHandler, nullptr, true);
105cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne    initialized = true;
106cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  }
107cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne}
108cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne
1096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarnamespace {
1106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
111cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic void handleLibLTODiagnostic(lto_codegen_diagnostic_severity_t Severity,
112cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                   const char *Msg, void *) {
113cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  sLastErrorString = Msg;
114cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  sLastErrorString += "\n";
115cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
116cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
1176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// This derived class owns the native object file. This helps implement the
1186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// libLTO API semantics, which require that the code generator owns the object
1196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// file.
1206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstruct LibLTOCodeGenerator : LTOCodeGenerator {
121cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  LibLTOCodeGenerator() : LTOCodeGenerator(*LTOContext) {
122cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    setDiagnosticHandler(handleLibLTODiagnostic, nullptr); }
1236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  LibLTOCodeGenerator(std::unique_ptr<LLVMContext> Context)
124cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      : LTOCodeGenerator(*Context), OwnedContext(std::move(Context)) {
125cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    setDiagnosticHandler(handleLibLTODiagnostic, nullptr); }
126cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
127cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Reset the module first in case MergedModule is created in OwnedContext.
128cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Module must be destructed before its context gets destructed.
129cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ~LibLTOCodeGenerator() { resetMergedModule(); }
1306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  std::unique_ptr<MemoryBuffer> NativeObjectFile;
132cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::unique_ptr<LLVMContext> OwnedContext;
1336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar};
1346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
1366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarDEFINE_SIMPLE_CONVERSION_FUNCTIONS(LibLTOCodeGenerator, lto_code_gen_t)
138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t)
139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Convert the subtarget features into a string to pass to LTOCodeGenerator.
141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void lto_add_attrs(lto_code_gen_t cg) {
142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LTOCodeGenerator *CG = unwrap(cg);
143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MAttrs.size()) {
144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    std::string attrs;
145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (unsigned i = 0; i < MAttrs.size(); ++i) {
146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (i > 0)
147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        attrs.append(",");
148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      attrs.append(MAttrs[i]);
149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CG->setAttr(attrs.c_str());
152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (OptLevel < '0' || OptLevel > '3')
1554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    report_fatal_error("Optimization level must be between 0 and 3");
1564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  CG->setOptLevel(OptLevel - '0');
157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1598fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingextern const char* lto_get_version() {
1608fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  return LTOCodeGenerator::getVersionString();
16177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
16277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
1638fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingconst char* lto_get_error_message() {
1648fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  return sLastErrorString.c_str();
16577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
16677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
16707d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_module_is_object_file(const char* path) {
1688fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  return LTOModule::isBitcodeFile(path);
16977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
17077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
17107d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_module_is_object_file_for_target(const char* path,
1728fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                          const char* target_triplet_prefix) {
173c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer = MemoryBuffer::getFile(path);
174c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!Buffer)
175c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
176c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return LTOModule::isBitcodeForTarget(Buffer->get(), target_triplet_prefix);
17777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
17877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
17907d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_module_is_object_file_in_memory(const void* mem, size_t length) {
1808fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  return LTOModule::isBitcodeFile(mem, length);
18177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
18277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
18307d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool
1848fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlinglto_module_is_object_file_in_memory_for_target(const void* mem,
1858fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                            size_t length,
1868fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                            const char* target_triplet_prefix) {
187c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::unique_ptr<MemoryBuffer> buffer(LTOModule::makeBuffer(mem, length));
188c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!buffer)
189c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
190c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return LTOModule::isBitcodeForTarget(buffer.get(), target_triplet_prefix);
19177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
19277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
1938fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlinglto_module_t lto_module_create(const char* path) {
194cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  lto_initialize();
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
196cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M =
197cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      LTOModule::createFromFile(*LTOContext, path, Options);
198cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (!M)
199cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return nullptr;
200cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return wrap(M->release());
20177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
20277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
2038fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlinglto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) {
204cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  lto_initialize();
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
206cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M =
207cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      LTOModule::createFromOpenFile(*LTOContext, fd, path, size, Options);
208cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (!M)
209cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return nullptr;
210cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return wrap(M->release());
211b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola}
21277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
213f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindolalto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path,
214f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola                                                 size_t file_size,
215f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola                                                 size_t map_size,
2168fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                                 off_t offset) {
217cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  lto_initialize();
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
219cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromOpenFileSlice(
220cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      *LTOContext, fd, path, map_size, offset, Options);
221cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (!M)
222cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return nullptr;
223cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return wrap(M->release());
224f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola}
225f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola
2268fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlinglto_module_t lto_module_create_from_memory(const void* mem, size_t length) {
227cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  lto_initialize();
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
229cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M =
230cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      LTOModule::createFromBuffer(*LTOContext, mem, length, Options);
231cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (!M)
232cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return nullptr;
233cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return wrap(M->release());
23477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
23577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineslto_module_t lto_module_create_from_memory_with_path(const void* mem,
23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                     size_t length,
23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                     const char *path) {
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  lto_initialize();
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
241cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M =
242cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      LTOModule::createFromBuffer(*LTOContext, mem, length, Options, path);
243cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (!M)
244cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return nullptr;
245cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return wrap(M->release());
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
24837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hineslto_module_t lto_module_create_in_local_context(const void *mem, size_t length,
24937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                const char *path) {
25037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  lto_initialize();
25137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
252cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M =
253cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      LTOModule::createInLocalContext(mem, length, Options, path);
254cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (!M)
255cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return nullptr;
256cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return wrap(M->release());
25737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hineslto_module_t lto_module_create_in_codegen_context(const void *mem,
26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                  size_t length,
26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                  const char *path,
26237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                  lto_code_gen_t cg) {
26337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  lto_initialize();
26437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
265cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createInContext(
266cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      mem, length, Options, path, &unwrap(cg)->getContext());
267cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return wrap(M->release());
26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid lto_module_dispose(lto_module_t mod) { delete unwrap(mod); }
27177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
2728fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingconst char* lto_module_get_target_triple(lto_module_t mod) {
273c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return unwrap(mod)->getTargetTriple().c_str();
27477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
27577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
2768fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingvoid lto_module_set_target_triple(lto_module_t mod, const char *triple) {
277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return unwrap(mod)->setTargetTriple(triple);
278cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola}
279cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola
2808fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingunsigned int lto_module_get_num_symbols(lto_module_t mod) {
281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return unwrap(mod)->getSymbolCount();
28277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
28377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
2848fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingconst char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) {
285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return unwrap(mod)->getSymbolName(index);
28677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
28777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
2888fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlinglto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
2898fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                                      unsigned int index) {
290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return unwrap(mod)->getSymbolAttributes(index);
29177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
29277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
293cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarconst char* lto_module_get_linkeropts(lto_module_t mod) {
294cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return unwrap(mod)->getLinkerOpts();
29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        lto_diagnostic_handler_t diag_handler,
29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        void *ctxt) {
300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unwrap(cg)->setDiagnosticHandler(diag_handler, ctxt);
30136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic lto_code_gen_t createCodeGen(bool InLocalContext) {
304cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  lto_initialize();
305c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola
30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
307c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola
3086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  LibLTOCodeGenerator *CodeGen =
3096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      InLocalContext ? new LibLTOCodeGenerator(make_unique<LLVMContext>())
3106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                     : new LibLTOCodeGenerator();
3116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  CodeGen->setTargetOptions(Options);
312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return wrap(CodeGen);
31377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
31477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hineslto_code_gen_t lto_codegen_create(void) {
316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return createCodeGen(/* InLocalContext */ false);
317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hineslto_code_gen_t lto_codegen_create_in_local_context(void) {
320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return createCodeGen(/* InLocalContext */ true);
321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid lto_codegen_dispose(lto_code_gen_t cg) { delete unwrap(cg); }
32477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
32507d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) {
32637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return !unwrap(cg)->addModule(unwrap(mod));
32777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
32877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid lto_codegen_set_module(lto_code_gen_t cg, lto_module_t mod) {
330cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  unwrap(cg)->setModule(std::unique_ptr<LTOModule>(unwrap(mod)));
331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
33307d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) {
334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unwrap(cg)->setDebugInfo(debug);
335235089bdaefabcef9e9cde28eb3b0d8937b12a0dShuxin Yang  return false;
33677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
33777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
33807d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) {
339cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  switch (model) {
340cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_STATIC:
341cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    unwrap(cg)->setCodePICModel(Reloc::Static);
342cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return false;
343cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
344cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    unwrap(cg)->setCodePICModel(Reloc::PIC_);
345cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return false;
346cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
347cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    unwrap(cg)->setCodePICModel(Reloc::DynamicNoPIC);
348cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return false;
349cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_DEFAULT:
350cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    unwrap(cg)->setCodePICModel(Reloc::Default);
351cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return false;
352cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
353cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  sLastErrorString = "Unknown PIC model";
354cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return true;
35577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
35677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
357168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendlingvoid lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu) {
358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return unwrap(cg)->setCpu(cpu);
359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3618fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingvoid lto_codegen_set_assembler_path(lto_code_gen_t cg, const char *path) {
362e9efea1194691580c74520aad48887d95fd0ce1bRafael Espindola  // In here only for backwards compatibility. We use MC now.
363cbad58624090933cb8fb85587e03be613a481309Nick Kledzik}
364cbad58624090933cb8fb85587e03be613a481309Nick Kledzik
365168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendlingvoid lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
3668fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                    int nargs) {
367e9efea1194691580c74520aad48887d95fd0ce1bRafael Espindola  // In here only for backwards compatibility. We use MC now.
36898197e55c10176c3ef9100f7d852abbd2347225fRafael Espindola}
36998197e55c10176c3ef9100f7d852abbd2347225fRafael Espindola
3708fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingvoid lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg,
371168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendling                                          const char *symbol) {
372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unwrap(cg)->addMustPreserveSymbol(symbol);
37377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
37477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
3754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic void maybeParseOptions(lto_code_gen_t cg) {
3760e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola  if (!parsedOptions) {
377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unwrap(cg)->parseCodeGenDebugOptions();
378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    lto_add_attrs(cg);
3790e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola    parsedOptions = true;
3800e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola  }
3814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}
3824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
3834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
3844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  maybeParseOptions(cg);
385cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return !unwrap(cg)->writeMergedModules(path);
38677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
38777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
388168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendlingconst void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
3894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  maybeParseOptions(cg);
3906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  LibLTOCodeGenerator *CG = unwrap(cg);
391cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  CG->NativeObjectFile =
392cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      CG->compile(DisableVerify, DisableInline, DisableGVNLoadPRE,
393cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                  DisableLTOVectorization);
3946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!CG->NativeObjectFile)
3956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return nullptr;
3966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  *length = CG->NativeObjectFile->getBufferSize();
3976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return CG->NativeObjectFile->getBufferStart();
39877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
39977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
400ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool lto_codegen_optimize(lto_code_gen_t cg) {
4014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  maybeParseOptions(cg);
402cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return !unwrap(cg)->optimize(DisableVerify, DisableInline, DisableGVNLoadPRE,
403cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                               DisableLTOVectorization);
404ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
405ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesconst void *lto_codegen_compile_optimized(lto_code_gen_t cg, size_t *length) {
4074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  maybeParseOptions(cg);
4086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  LibLTOCodeGenerator *CG = unwrap(cg);
409cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  CG->NativeObjectFile = CG->compileOptimized();
4106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!CG->NativeObjectFile)
4116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return nullptr;
4126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  *length = CG->NativeObjectFile->getBufferSize();
4136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return CG->NativeObjectFile->getBufferStart();
414ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
41607d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
4174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  maybeParseOptions(cg);
41837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return !unwrap(cg)->compile_to_file(
419cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      name, DisableVerify, DisableInline, DisableGVNLoadPRE,
420cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      DisableLTOVectorization);
4216421a8815e14189121a5e20731fd005ea08793e1Rafael Espindola}
4226421a8815e14189121a5e20731fd005ea08793e1Rafael Espindola
423168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendlingvoid lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {
424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unwrap(cg)->setCodeGenDebugOptions(opt);
425d44d4bf04b69fa7b003a0792a78ab132e40fe76fDuncan Sands}
426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesunsigned int lto_api_version() { return LTO_API_VERSION; }
4286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
4296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid lto_codegen_set_should_internalize(lto_code_gen_t cg,
4306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                        bool ShouldInternalize) {
4316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unwrap(cg)->setShouldInternalize(ShouldInternalize);
4326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
4336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
4346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid lto_codegen_set_should_embed_uselists(lto_code_gen_t cg,
4356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                           lto_bool_t ShouldEmbedUselists) {
4366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unwrap(cg)->setShouldEmbedUselists(ShouldEmbedUselists);
4376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
438