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"
17de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Bitcode/ReaderWriter.h"
18c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/CodeGen/CommandFlags.h"
19f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/IR/DiagnosticInfo.h"
20f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/IR/DiagnosticPrinter.h"
21ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/LLVMContext.h"
22de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/LTO/legacy/LTOCodeGenerator.h"
23de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/LTO/legacy/LTOModule.h"
24de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/LTO/legacy/ThinLTOCodeGenerator.h"
25c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/MemoryBuffer.h"
26ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/Signals.h"
27c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/TargetSelect.h"
28de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/raw_ostream.h"
2977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
30c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola// extra command-line flags needed for LTOCodeGenerator
314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<char>
324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarOptLevel("O",
334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar         cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                  "(default = '-O2')"),
354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar         cl::Prefix,
364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar         cl::ZeroOrMore,
374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar         cl::init('2'));
38c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola
39c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindolastatic cl::opt<bool>
40c13c9e5a9d288eac494a38f0710d34446167f940Rafael EspindolaDisableInline("disable-inlining", cl::init(false),
41c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola  cl::desc("Do not run the inliner pass"));
42c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola
43c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindolastatic cl::opt<bool>
44c13c9e5a9d288eac494a38f0710d34446167f940Rafael EspindolaDisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false),
45c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola  cl::desc("Do not run the GVN load PRE pass"));
4677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<bool>
4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDisableLTOVectorization("disable-lto-vectorization", cl::init(false),
4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  cl::desc("Do not run loop or slp vectorization during LTO"));
5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
51f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#ifdef NDEBUG
52f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic bool VerifyByDefault = false;
53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#else
54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic bool VerifyByDefault = true;
55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#endif
56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::opt<bool> DisableVerify(
58f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    "disable-llvm-verifier", cl::init(!VerifyByDefault),
59f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    cl::desc("Don't run the LLVM verifier during the optimization pipeline"));
60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
618fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling// Holds most recent error string.
628fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling// *** Not thread safe ***
6377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikstatic std::string sLastErrorString;
6477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
65cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne// Holds the initialization state of the LTO module.
66cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne// *** Not thread safe ***
67cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbournestatic bool initialized = false;
68cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne
690e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola// Holds the command-line option parsing state of the LTO module.
700e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindolastatic bool parsedOptions = false;
710e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola
72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic LLVMContext *LTOContext = nullptr;
73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
74f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
75f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (DI.getSeverity() != DS_Error) {
76f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DiagnosticPrinterRawOStream DP(errs());
77f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DI.print(DP);
78f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    errs() << '\n';
79f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return;
80f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
81f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  sLastErrorString = "";
82f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  {
83f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    raw_string_ostream Stream(sLastErrorString);
84f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DiagnosticPrinterRawOStream DP(Stream);
85f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DI.print(DP);
86f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
87f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
88f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
89cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne// Initialize the configured targets if they have not been initialized.
90cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbournestatic void lto_initialize() {
91cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  if (!initialized) {
92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#ifdef LLVM_ON_WIN32
93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Dialog box on crash disabling doesn't work across DLL boundaries, so do
94ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // it here.
95ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    llvm::sys::DisableSystemDialogsOnCrash();
96ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#endif
97ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
98c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllTargetInfos();
99c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllTargets();
100c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllTargetMCs();
101c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllAsmParsers();
102c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllAsmPrinters();
103c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InitializeAllDisassemblers();
104f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
105de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    static LLVMContext Context;
106de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    LTOContext = &Context;
107f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    LTOContext->setDiagnosticHandler(diagnosticHandler, nullptr, true);
108cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne    initialized = true;
109cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  }
110cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne}
111cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne
1126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarnamespace {
1136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic void handleLibLTODiagnostic(lto_codegen_diagnostic_severity_t Severity,
115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                   const char *Msg, void *) {
116f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  sLastErrorString = Msg;
117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
118f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// This derived class owns the native object file. This helps implement the
1206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// libLTO API semantics, which require that the code generator owns the object
1216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// file.
1226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstruct LibLTOCodeGenerator : LTOCodeGenerator {
123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  LibLTOCodeGenerator() : LTOCodeGenerator(*LTOContext) { init(); }
1246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  LibLTOCodeGenerator(std::unique_ptr<LLVMContext> Context)
125f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      : LTOCodeGenerator(*Context), OwnedContext(std::move(Context)) {
126de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    init();
127de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
128f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Reset the module first in case MergedModule is created in OwnedContext.
130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Module must be destructed before its context gets destructed.
131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ~LibLTOCodeGenerator() { resetMergedModule(); }
1326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
133de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void init() { setDiagnosticHandler(handleLibLTODiagnostic, nullptr); }
134de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  std::unique_ptr<MemoryBuffer> NativeObjectFile;
136f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::unique_ptr<LLVMContext> OwnedContext;
1376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar};
1386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
1406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarDEFINE_SIMPLE_CONVERSION_FUNCTIONS(LibLTOCodeGenerator, lto_code_gen_t)
142de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarDEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThinLTOCodeGenerator, thinlto_code_gen_t)
143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t)
144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Convert the subtarget features into a string to pass to LTOCodeGenerator.
146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void lto_add_attrs(lto_code_gen_t cg) {
147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LTOCodeGenerator *CG = unwrap(cg);
148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MAttrs.size()) {
149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    std::string attrs;
150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (unsigned i = 0; i < MAttrs.size(); ++i) {
151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (i > 0)
152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        attrs.append(",");
153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      attrs.append(MAttrs[i]);
154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CG->setAttr(attrs.c_str());
157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (OptLevel < '0' || OptLevel > '3')
1604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    report_fatal_error("Optimization level must be between 0 and 3");
1614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  CG->setOptLevel(OptLevel - '0');
162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1648fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingextern const char* lto_get_version() {
1658fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  return LTOCodeGenerator::getVersionString();
16677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
16777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
1688fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingconst char* lto_get_error_message() {
1698fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  return sLastErrorString.c_str();
17077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
17177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
17207d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_module_is_object_file(const char* path) {
1738fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  return LTOModule::isBitcodeFile(path);
17477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
17577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
17607d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_module_is_object_file_for_target(const char* path,
1778fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                          const char* target_triplet_prefix) {
178c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer = MemoryBuffer::getFile(path);
179c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!Buffer)
180c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
181c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return LTOModule::isBitcodeForTarget(Buffer->get(), target_triplet_prefix);
18277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
18377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
184de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool lto_module_has_objc_category(const void *mem, size_t length) {
185de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::unique_ptr<MemoryBuffer> Buffer(LTOModule::makeBuffer(mem, length));
186de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!Buffer)
187de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
188de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  LLVMContext Ctx;
189de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return llvm::isBitcodeContainingObjCCategory(*Buffer, Ctx);
190de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
191de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
19207d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_module_is_object_file_in_memory(const void* mem, size_t length) {
1938fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  return LTOModule::isBitcodeFile(mem, length);
19477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
19577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
19607d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool
1978fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlinglto_module_is_object_file_in_memory_for_target(const void* mem,
1988fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                            size_t length,
1998fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                            const char* target_triplet_prefix) {
200c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::unique_ptr<MemoryBuffer> buffer(LTOModule::makeBuffer(mem, length));
201c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!buffer)
202c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
203c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return LTOModule::isBitcodeForTarget(buffer.get(), target_triplet_prefix);
20477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
20577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
2068fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlinglto_module_t lto_module_create(const char* path) {
207cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  lto_initialize();
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M =
210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      LTOModule::createFromFile(*LTOContext, path, Options);
211f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!M)
212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return nullptr;
213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return wrap(M->release());
21477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
21577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
2168fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlinglto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) {
217cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  lto_initialize();
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
219f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M =
220f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      LTOModule::createFromOpenFile(*LTOContext, fd, path, size, Options);
221f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!M)
222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return nullptr;
223f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return wrap(M->release());
224b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola}
22577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
226f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindolalto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path,
227f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola                                                 size_t file_size,
228f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola                                                 size_t map_size,
2298fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                                 off_t offset) {
230cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  lto_initialize();
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
232f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromOpenFileSlice(
233f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      *LTOContext, fd, path, map_size, offset, Options);
234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!M)
235f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return nullptr;
236f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return wrap(M->release());
237f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola}
238f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola
2398fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlinglto_module_t lto_module_create_from_memory(const void* mem, size_t length) {
240cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  lto_initialize();
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
242f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M =
243f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      LTOModule::createFromBuffer(*LTOContext, mem, length, Options);
244f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!M)
245f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return nullptr;
246f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return wrap(M->release());
24777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
24877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineslto_module_t lto_module_create_from_memory_with_path(const void* mem,
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                     size_t length,
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                     const char *path) {
25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  lto_initialize();
25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
254f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M =
255f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      LTOModule::createFromBuffer(*LTOContext, mem, length, Options, path);
256f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!M)
257f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return nullptr;
258f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return wrap(M->release());
25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hineslto_module_t lto_module_create_in_local_context(const void *mem, size_t length,
26237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                const char *path) {
26337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  lto_initialize();
26437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
265de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
266de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Create a local context. Ownership will be transfered to LTOModule.
267de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::unique_ptr<LLVMContext> Context = llvm::make_unique<LLVMContext>();
268de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Context->setDiagnosticHandler(diagnosticHandler, nullptr, true);
269de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
270f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M =
271de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      LTOModule::createInLocalContext(std::move(Context), mem, length, Options,
272de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                      path);
273f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!M)
274f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return nullptr;
275f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return wrap(M->release());
27637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hineslto_module_t lto_module_create_in_codegen_context(const void *mem,
27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                  size_t length,
28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                  const char *path,
28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                  lto_code_gen_t cg) {
28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  lto_initialize();
28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
284de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromBuffer(
285de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      unwrap(cg)->getContext(), mem, length, Options, path);
286f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return wrap(M->release());
28737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
28837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid lto_module_dispose(lto_module_t mod) { delete unwrap(mod); }
29077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
2918fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingconst char* lto_module_get_target_triple(lto_module_t mod) {
292c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return unwrap(mod)->getTargetTriple().c_str();
29377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
29477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
2958fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingvoid lto_module_set_target_triple(lto_module_t mod, const char *triple) {
296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return unwrap(mod)->setTargetTriple(triple);
297cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola}
298cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola
2998fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingunsigned int lto_module_get_num_symbols(lto_module_t mod) {
300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return unwrap(mod)->getSymbolCount();
30177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
30277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
3038fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingconst char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) {
304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return unwrap(mod)->getSymbolName(index);
30577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
30677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
3078fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlinglto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
3088fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                                      unsigned int index) {
309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return unwrap(mod)->getSymbolAttributes(index);
31077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
31177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarconst char* lto_module_get_linkeropts(lto_module_t mod) {
313f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return unwrap(mod)->getLinkerOpts();
31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        lto_diagnostic_handler_t diag_handler,
31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        void *ctxt) {
319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unwrap(cg)->setDiagnosticHandler(diag_handler, ctxt);
32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic lto_code_gen_t createCodeGen(bool InLocalContext) {
323cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  lto_initialize();
324c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola
32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
326c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola
3276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  LibLTOCodeGenerator *CodeGen =
3286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      InLocalContext ? new LibLTOCodeGenerator(make_unique<LLVMContext>())
3296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                     : new LibLTOCodeGenerator();
3306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  CodeGen->setTargetOptions(Options);
331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return wrap(CodeGen);
33277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
33377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hineslto_code_gen_t lto_codegen_create(void) {
335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return createCodeGen(/* InLocalContext */ false);
336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
338ebe69fe11e48d322045d5949c83283927a0d790bStephen Hineslto_code_gen_t lto_codegen_create_in_local_context(void) {
339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return createCodeGen(/* InLocalContext */ true);
340ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
341ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid lto_codegen_dispose(lto_code_gen_t cg) { delete unwrap(cg); }
34377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
34407d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) {
34537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return !unwrap(cg)->addModule(unwrap(mod));
34677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
34777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid lto_codegen_set_module(lto_code_gen_t cg, lto_module_t mod) {
349f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unwrap(cg)->setModule(std::unique_ptr<LTOModule>(unwrap(mod)));
350ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
351ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
35207d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) {
353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unwrap(cg)->setDebugInfo(debug);
354235089bdaefabcef9e9cde28eb3b0d8937b12a0dShuxin Yang  return false;
35577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
35677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
35707d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) {
358f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (model) {
359f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_STATIC:
360f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unwrap(cg)->setCodePICModel(Reloc::Static);
361f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
362f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
363f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unwrap(cg)->setCodePICModel(Reloc::PIC_);
364f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
365f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
366f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unwrap(cg)->setCodePICModel(Reloc::DynamicNoPIC);
367f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
368f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_DEFAULT:
369de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unwrap(cg)->setCodePICModel(None);
370f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
371f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
372f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  sLastErrorString = "Unknown PIC model";
373f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
37477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
37577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
376168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendlingvoid lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu) {
377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return unwrap(cg)->setCpu(cpu);
378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
379dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3808fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingvoid lto_codegen_set_assembler_path(lto_code_gen_t cg, const char *path) {
381e9efea1194691580c74520aad48887d95fd0ce1bRafael Espindola  // In here only for backwards compatibility. We use MC now.
382cbad58624090933cb8fb85587e03be613a481309Nick Kledzik}
383cbad58624090933cb8fb85587e03be613a481309Nick Kledzik
384168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendlingvoid lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
3858fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling                                    int nargs) {
386e9efea1194691580c74520aad48887d95fd0ce1bRafael Espindola  // In here only for backwards compatibility. We use MC now.
38798197e55c10176c3ef9100f7d852abbd2347225fRafael Espindola}
38898197e55c10176c3ef9100f7d852abbd2347225fRafael Espindola
3898fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingvoid lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg,
390168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendling                                          const char *symbol) {
391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unwrap(cg)->addMustPreserveSymbol(symbol);
39277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
39377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
3944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic void maybeParseOptions(lto_code_gen_t cg) {
3950e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola  if (!parsedOptions) {
396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unwrap(cg)->parseCodeGenDebugOptions();
397dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    lto_add_attrs(cg);
3980e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola    parsedOptions = true;
3990e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola  }
4004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}
4014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
4024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
4034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  maybeParseOptions(cg);
404f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return !unwrap(cg)->writeMergedModules(path);
40577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
40677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
407168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendlingconst void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
4084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  maybeParseOptions(cg);
4096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  LibLTOCodeGenerator *CG = unwrap(cg);
410f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  CG->NativeObjectFile =
411f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      CG->compile(DisableVerify, DisableInline, DisableGVNLoadPRE,
412f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  DisableLTOVectorization);
4136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!CG->NativeObjectFile)
4146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return nullptr;
4156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  *length = CG->NativeObjectFile->getBufferSize();
4166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return CG->NativeObjectFile->getBufferStart();
41777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
41877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool lto_codegen_optimize(lto_code_gen_t cg) {
4204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  maybeParseOptions(cg);
421f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return !unwrap(cg)->optimize(DisableVerify, DisableInline, DisableGVNLoadPRE,
422f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                               DisableLTOVectorization);
423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
424ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesconst void *lto_codegen_compile_optimized(lto_code_gen_t cg, size_t *length) {
4264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  maybeParseOptions(cg);
4276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  LibLTOCodeGenerator *CG = unwrap(cg);
428f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  CG->NativeObjectFile = CG->compileOptimized();
4296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!CG->NativeObjectFile)
4306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return nullptr;
4316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  *length = CG->NativeObjectFile->getBufferSize();
4326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return CG->NativeObjectFile->getBufferStart();
433ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
434ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
43507d5aef3057b2e403b20d683e7477c93fde67d99Reid Klecknerbool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
4364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  maybeParseOptions(cg);
43737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return !unwrap(cg)->compile_to_file(
438f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      name, DisableVerify, DisableInline, DisableGVNLoadPRE,
439f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      DisableLTOVectorization);
4406421a8815e14189121a5e20731fd005ea08793e1Rafael Espindola}
4416421a8815e14189121a5e20731fd005ea08793e1Rafael Espindola
442168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendlingvoid lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {
443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unwrap(cg)->setCodeGenDebugOptions(opt);
444d44d4bf04b69fa7b003a0792a78ab132e40fe76fDuncan Sands}
445ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
446ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesunsigned int lto_api_version() { return LTO_API_VERSION; }
4476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
4486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid lto_codegen_set_should_internalize(lto_code_gen_t cg,
4496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                        bool ShouldInternalize) {
4506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unwrap(cg)->setShouldInternalize(ShouldInternalize);
4516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
4526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
4536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid lto_codegen_set_should_embed_uselists(lto_code_gen_t cg,
4546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                           lto_bool_t ShouldEmbedUselists) {
4556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unwrap(cg)->setShouldEmbedUselists(ShouldEmbedUselists);
4566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
457de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
458de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// ThinLTO API below
459de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
460de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarthinlto_code_gen_t thinlto_create_codegen(void) {
461de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  lto_initialize();
462de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ThinLTOCodeGenerator *CodeGen = new ThinLTOCodeGenerator();
463de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  CodeGen->setTargetOptions(InitTargetOptionsFromCodeGenFlags());
464de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
465de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return wrap(CodeGen);
466de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
467de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
468de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_dispose(thinlto_code_gen_t cg) { delete unwrap(cg); }
469de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
470de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_add_module(thinlto_code_gen_t cg, const char *Identifier,
471de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                const char *Data, int Length) {
472de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unwrap(cg)->addModule(Identifier, StringRef(Data, Length));
473de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
474de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
475de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_process(thinlto_code_gen_t cg) { unwrap(cg)->run(); }
476de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
477de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarunsigned int thinlto_module_get_num_objects(thinlto_code_gen_t cg) {
478de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return unwrap(cg)->getProducedBinaries().size();
479de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
480de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarLTOObjectBuffer thinlto_module_get_object(thinlto_code_gen_t cg,
481de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                          unsigned int index) {
482de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  assert(index < unwrap(cg)->getProducedBinaries().size() && "Index overflow");
483de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  auto &MemBuffer = unwrap(cg)->getProducedBinaries()[index];
484de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return LTOObjectBuffer{MemBuffer->getBufferStart(),
485de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                         MemBuffer->getBufferSize()};
486de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
487de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
488de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_disable_codegen(thinlto_code_gen_t cg,
489de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                     lto_bool_t disable) {
490de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unwrap(cg)->disableCodeGen(disable);
491de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
492de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
493de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_set_codegen_only(thinlto_code_gen_t cg,
494de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                      lto_bool_t CodeGenOnly) {
495de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unwrap(cg)->setCodeGenOnly(CodeGenOnly);
496de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
497de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
498de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_debug_options(const char *const *options, int number) {
499de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // if options were requested, set them
500de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (number && options) {
501de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    std::vector<const char *> CodegenArgv(1, "libLTO");
502de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    for (auto Arg : ArrayRef<const char *>(options, number))
503de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      CodegenArgv.push_back(Arg);
504de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data());
505de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
506de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
507de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
508de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarlto_bool_t lto_module_is_thinlto(lto_module_t mod) {
509de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return unwrap(mod)->isThinLTO();
510de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
511de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
512de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_add_must_preserve_symbol(thinlto_code_gen_t cg,
513de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                              const char *Name, int Length) {
514de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unwrap(cg)->preserveSymbol(StringRef(Name, Length));
515de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
516de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
517de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_add_cross_referenced_symbol(thinlto_code_gen_t cg,
518de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                 const char *Name, int Length) {
519de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unwrap(cg)->crossReferenceSymbol(StringRef(Name, Length));
520de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
521de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
522de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_set_cpu(thinlto_code_gen_t cg, const char *cpu) {
523de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return unwrap(cg)->setCpu(cpu);
524de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
525de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
526de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_set_cache_dir(thinlto_code_gen_t cg,
527de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                   const char *cache_dir) {
528de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return unwrap(cg)->setCacheDir(cache_dir);
529de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
530de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
531de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_set_cache_pruning_interval(thinlto_code_gen_t cg,
532de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                int interval) {
533de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return unwrap(cg)->setCachePruningInterval(interval);
534de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
535de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
536de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_set_cache_entry_expiration(thinlto_code_gen_t cg,
537de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                unsigned expiration) {
538de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return unwrap(cg)->setCacheEntryExpiration(expiration);
539de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
540de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
541de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_set_final_cache_size_relative_to_available_space(
542de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    thinlto_code_gen_t cg, unsigned Percentage) {
543de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return unwrap(cg)->setMaxCacheSizeRelativeToAvailableSpace(Percentage);
544de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
545de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
546de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid thinlto_codegen_set_savetemps_dir(thinlto_code_gen_t cg,
547de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                       const char *save_temps_dir) {
548de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return unwrap(cg)->setSaveTempsDir(save_temps_dir);
549de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
550de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
551de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarlto_bool_t thinlto_codegen_set_pic_model(thinlto_code_gen_t cg,
552de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                         lto_codegen_model model) {
553de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  switch (model) {
554de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_STATIC:
555de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unwrap(cg)->setCodePICModel(Reloc::Static);
556de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
557de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
558de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unwrap(cg)->setCodePICModel(Reloc::PIC_);
559de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
560de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
561de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unwrap(cg)->setCodePICModel(Reloc::DynamicNoPIC);
562de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
563de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case LTO_CODEGEN_PIC_MODEL_DEFAULT:
564de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unwrap(cg)->setCodePICModel(None);
565de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
566de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
567de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  sLastErrorString = "Unknown PIC model";
568de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return true;
569de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
570