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