diff tools/lto/lto.cpp @ 120:1172e4bd9c6f

update 4.0.0
author mir3636
date Fri, 25 Nov 2016 19:14:25 +0900
parents 7d135dc70f03
children 803732b1fca8
line wrap: on
line diff
--- a/tools/lto/lto.cpp	Tue Jan 26 22:56:36 2016 +0900
+++ b/tools/lto/lto.cpp	Fri Nov 25 19:14:25 2016 +0900
@@ -14,15 +14,18 @@
 
 #include "llvm-c/lto.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/LLVMContext.h"
-#include "llvm/LTO/LTOCodeGenerator.h"
-#include "llvm/LTO/LTOModule.h"
+#include "llvm/LTO/legacy/LTOCodeGenerator.h"
+#include "llvm/LTO/legacy/LTOModule.h"
+#include "llvm/LTO/legacy/ThinLTOCodeGenerator.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/raw_ostream.h"
 
 // extra command-line flags needed for LTOCodeGenerator
 static cl::opt<char>
@@ -99,7 +102,8 @@
     InitializeAllAsmPrinters();
     InitializeAllDisassemblers();
 
-    LTOContext = &getGlobalContext();
+    static LLVMContext Context;
+    LTOContext = &Context;
     LTOContext->setDiagnosticHandler(diagnosticHandler, nullptr, true);
     initialized = true;
   }
@@ -116,16 +120,18 @@
 // libLTO API semantics, which require that the code generator owns the object
 // file.
 struct LibLTOCodeGenerator : LTOCodeGenerator {
-  LibLTOCodeGenerator() : LTOCodeGenerator(*LTOContext) {
-    setDiagnosticHandler(handleLibLTODiagnostic, nullptr); }
+  LibLTOCodeGenerator() : LTOCodeGenerator(*LTOContext) { init(); }
   LibLTOCodeGenerator(std::unique_ptr<LLVMContext> Context)
       : LTOCodeGenerator(*Context), OwnedContext(std::move(Context)) {
-    setDiagnosticHandler(handleLibLTODiagnostic, nullptr); }
+    init();
+  }
 
   // Reset the module first in case MergedModule is created in OwnedContext.
   // Module must be destructed before its context gets destructed.
   ~LibLTOCodeGenerator() { resetMergedModule(); }
 
+  void init() { setDiagnosticHandler(handleLibLTODiagnostic, nullptr); }
+
   std::unique_ptr<MemoryBuffer> NativeObjectFile;
   std::unique_ptr<LLVMContext> OwnedContext;
 };
@@ -133,6 +139,7 @@
 }
 
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LibLTOCodeGenerator, lto_code_gen_t)
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThinLTOCodeGenerator, thinlto_code_gen_t)
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t)
 
 // Convert the subtarget features into a string to pass to LTOCodeGenerator.
@@ -146,7 +153,7 @@
       attrs.append(MAttrs[i]);
     }
 
-    CG->setAttr(attrs.c_str());
+    CG->setAttr(attrs);
   }
 
   if (OptLevel < '0' || OptLevel > '3')
@@ -163,7 +170,7 @@
 }
 
 bool lto_module_is_object_file(const char* path) {
-  return LTOModule::isBitcodeFile(path);
+  return LTOModule::isBitcodeFile(StringRef(path));
 }
 
 bool lto_module_is_object_file_for_target(const char* path,
@@ -171,7 +178,18 @@
   ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer = MemoryBuffer::getFile(path);
   if (!Buffer)
     return false;
-  return LTOModule::isBitcodeForTarget(Buffer->get(), target_triplet_prefix);
+  return LTOModule::isBitcodeForTarget(Buffer->get(),
+                                       StringRef(target_triplet_prefix));
+}
+
+bool lto_module_has_objc_category(const void *mem, size_t length) {
+  std::unique_ptr<MemoryBuffer> Buffer(LTOModule::makeBuffer(mem, length));
+  if (!Buffer)
+    return false;
+  LLVMContext Ctx;
+  ErrorOr<bool> Result = expectedToErrorOrAndEmitErrors(
+      Ctx, llvm::isBitcodeContainingObjCCategory(*Buffer));
+  return Result && *Result;
 }
 
 bool lto_module_is_object_file_in_memory(const void* mem, size_t length) {
@@ -185,14 +203,15 @@
   std::unique_ptr<MemoryBuffer> buffer(LTOModule::makeBuffer(mem, length));
   if (!buffer)
     return false;
-  return LTOModule::isBitcodeForTarget(buffer.get(), target_triplet_prefix);
+  return LTOModule::isBitcodeForTarget(buffer.get(),
+                                       StringRef(target_triplet_prefix));
 }
 
 lto_module_t lto_module_create(const char* path) {
   lto_initialize();
   llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
   ErrorOr<std::unique_ptr<LTOModule>> M =
-      LTOModule::createFromFile(*LTOContext, path, Options);
+      LTOModule::createFromFile(*LTOContext, StringRef(path), Options);
   if (!M)
     return nullptr;
   return wrap(M->release());
@@ -201,8 +220,8 @@
 lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) {
   lto_initialize();
   llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
-  ErrorOr<std::unique_ptr<LTOModule>> M =
-      LTOModule::createFromOpenFile(*LTOContext, fd, path, size, Options);
+  ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromOpenFile(
+      *LTOContext, fd, StringRef(path), size, Options);
   if (!M)
     return nullptr;
   return wrap(M->release());
@@ -215,7 +234,7 @@
   lto_initialize();
   llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
   ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromOpenFileSlice(
-      *LTOContext, fd, path, map_size, offset, Options);
+      *LTOContext, fd, StringRef(path), map_size, offset, Options);
   if (!M)
     return nullptr;
   return wrap(M->release());
@@ -236,8 +255,8 @@
                                                      const char *path) {
   lto_initialize();
   llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
-  ErrorOr<std::unique_ptr<LTOModule>> M =
-      LTOModule::createFromBuffer(*LTOContext, mem, length, Options, path);
+  ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromBuffer(
+      *LTOContext, mem, length, Options, StringRef(path));
   if (!M)
     return nullptr;
   return wrap(M->release());
@@ -247,8 +266,13 @@
                                                 const char *path) {
   lto_initialize();
   llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
-  ErrorOr<std::unique_ptr<LTOModule>> M =
-      LTOModule::createInLocalContext(mem, length, Options, path);
+
+  // Create a local context. Ownership will be transfered to LTOModule.
+  std::unique_ptr<LLVMContext> Context = llvm::make_unique<LLVMContext>();
+  Context->setDiagnosticHandler(diagnosticHandler, nullptr, true);
+
+  ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createInLocalContext(
+      std::move(Context), mem, length, Options, StringRef(path));
   if (!M)
     return nullptr;
   return wrap(M->release());
@@ -260,8 +284,8 @@
                                                   lto_code_gen_t cg) {
   lto_initialize();
   llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
-  ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createInContext(
-      mem, length, Options, path, &unwrap(cg)->getContext());
+  ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromBuffer(
+      unwrap(cg)->getContext(), mem, length, Options, StringRef(path));
   return wrap(M->release());
 }
 
@@ -272,7 +296,7 @@
 }
 
 void lto_module_set_target_triple(lto_module_t mod, const char *triple) {
-  return unwrap(mod)->setTargetTriple(triple);
+  return unwrap(mod)->setTargetTriple(StringRef(triple));
 }
 
 unsigned int lto_module_get_num_symbols(lto_module_t mod) {
@@ -280,7 +304,7 @@
 }
 
 const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) {
-  return unwrap(mod)->getSymbolName(index);
+  return unwrap(mod)->getSymbolName(index).data();
 }
 
 lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
@@ -289,7 +313,7 @@
 }
 
 const char* lto_module_get_linkeropts(lto_module_t mod) {
-  return unwrap(mod)->getLinkerOpts();
+  return unwrap(mod)->getLinkerOpts().data();
 }
 
 void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
@@ -345,7 +369,7 @@
     unwrap(cg)->setCodePICModel(Reloc::DynamicNoPIC);
     return false;
   case LTO_CODEGEN_PIC_MODEL_DEFAULT:
-    unwrap(cg)->setCodePICModel(Reloc::Default);
+    unwrap(cg)->setCodePICModel(None);
     return false;
   }
   sLastErrorString = "Unknown PIC model";
@@ -433,3 +457,116 @@
                                            lto_bool_t ShouldEmbedUselists) {
   unwrap(cg)->setShouldEmbedUselists(ShouldEmbedUselists);
 }
+
+// ThinLTO API below
+
+thinlto_code_gen_t thinlto_create_codegen(void) {
+  lto_initialize();
+  ThinLTOCodeGenerator *CodeGen = new ThinLTOCodeGenerator();
+  CodeGen->setTargetOptions(InitTargetOptionsFromCodeGenFlags());
+
+  return wrap(CodeGen);
+}
+
+void thinlto_codegen_dispose(thinlto_code_gen_t cg) { delete unwrap(cg); }
+
+void thinlto_codegen_add_module(thinlto_code_gen_t cg, const char *Identifier,
+                                const char *Data, int Length) {
+  unwrap(cg)->addModule(Identifier, StringRef(Data, Length));
+}
+
+void thinlto_codegen_process(thinlto_code_gen_t cg) { unwrap(cg)->run(); }
+
+unsigned int thinlto_module_get_num_objects(thinlto_code_gen_t cg) {
+  return unwrap(cg)->getProducedBinaries().size();
+}
+LTOObjectBuffer thinlto_module_get_object(thinlto_code_gen_t cg,
+                                          unsigned int index) {
+  assert(index < unwrap(cg)->getProducedBinaries().size() && "Index overflow");
+  auto &MemBuffer = unwrap(cg)->getProducedBinaries()[index];
+  return LTOObjectBuffer{MemBuffer->getBufferStart(),
+                         MemBuffer->getBufferSize()};
+}
+
+void thinlto_codegen_disable_codegen(thinlto_code_gen_t cg,
+                                     lto_bool_t disable) {
+  unwrap(cg)->disableCodeGen(disable);
+}
+
+void thinlto_codegen_set_codegen_only(thinlto_code_gen_t cg,
+                                      lto_bool_t CodeGenOnly) {
+  unwrap(cg)->setCodeGenOnly(CodeGenOnly);
+}
+
+void thinlto_debug_options(const char *const *options, int number) {
+  // if options were requested, set them
+  if (number && options) {
+    std::vector<const char *> CodegenArgv(1, "libLTO");
+    for (auto Arg : ArrayRef<const char *>(options, number))
+      CodegenArgv.push_back(Arg);
+    cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data());
+  }
+}
+
+lto_bool_t lto_module_is_thinlto(lto_module_t mod) {
+  return unwrap(mod)->isThinLTO();
+}
+
+void thinlto_codegen_add_must_preserve_symbol(thinlto_code_gen_t cg,
+                                              const char *Name, int Length) {
+  unwrap(cg)->preserveSymbol(StringRef(Name, Length));
+}
+
+void thinlto_codegen_add_cross_referenced_symbol(thinlto_code_gen_t cg,
+                                                 const char *Name, int Length) {
+  unwrap(cg)->crossReferenceSymbol(StringRef(Name, Length));
+}
+
+void thinlto_codegen_set_cpu(thinlto_code_gen_t cg, const char *cpu) {
+  return unwrap(cg)->setCpu(cpu);
+}
+
+void thinlto_codegen_set_cache_dir(thinlto_code_gen_t cg,
+                                   const char *cache_dir) {
+  return unwrap(cg)->setCacheDir(cache_dir);
+}
+
+void thinlto_codegen_set_cache_pruning_interval(thinlto_code_gen_t cg,
+                                                int interval) {
+  return unwrap(cg)->setCachePruningInterval(interval);
+}
+
+void thinlto_codegen_set_cache_entry_expiration(thinlto_code_gen_t cg,
+                                                unsigned expiration) {
+  return unwrap(cg)->setCacheEntryExpiration(expiration);
+}
+
+void thinlto_codegen_set_final_cache_size_relative_to_available_space(
+    thinlto_code_gen_t cg, unsigned Percentage) {
+  return unwrap(cg)->setMaxCacheSizeRelativeToAvailableSpace(Percentage);
+}
+
+void thinlto_codegen_set_savetemps_dir(thinlto_code_gen_t cg,
+                                       const char *save_temps_dir) {
+  return unwrap(cg)->setSaveTempsDir(save_temps_dir);
+}
+
+lto_bool_t thinlto_codegen_set_pic_model(thinlto_code_gen_t cg,
+                                         lto_codegen_model model) {
+  switch (model) {
+  case LTO_CODEGEN_PIC_MODEL_STATIC:
+    unwrap(cg)->setCodePICModel(Reloc::Static);
+    return false;
+  case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
+    unwrap(cg)->setCodePICModel(Reloc::PIC_);
+    return false;
+  case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
+    unwrap(cg)->setCodePICModel(Reloc::DynamicNoPIC);
+    return false;
+  case LTO_CODEGEN_PIC_MODEL_DEFAULT:
+    unwrap(cg)->setCodePICModel(None);
+    return false;
+  }
+  sLastErrorString = "Unknown PIC model";
+  return true;
+}