diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
| commit | 01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch) | |
| tree | 4def12e759965de927d963ac65840d663ef9d1ea /tools/lto/lto.cpp | |
| parent | f0f4822ed4b66e3579e92a89f368f8fb860e218e (diff) | |
Diffstat (limited to 'tools/lto/lto.cpp')
| -rw-r--r-- | tools/lto/lto.cpp | 156 |
1 files changed, 144 insertions, 12 deletions
diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index d8f99c050a34c..7109cf4d90970 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -14,15 +14,18 @@ #include "llvm-c/lto.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Bitcode/ReaderWriter.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> @@ -81,7 +84,6 @@ static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { DiagnosticPrinterRawOStream DP(Stream); DI.print(DP); } - sLastErrorString += '\n'; } // Initialize the configured targets if they have not been initialized. @@ -100,7 +102,8 @@ static void lto_initialize() { InitializeAllAsmPrinters(); InitializeAllDisassemblers(); - LTOContext = &getGlobalContext(); + static LLVMContext Context; + LTOContext = &Context; LTOContext->setDiagnosticHandler(diagnosticHandler, nullptr, true); initialized = true; } @@ -111,23 +114,24 @@ namespace { static void handleLibLTODiagnostic(lto_codegen_diagnostic_severity_t Severity, const char *Msg, void *) { sLastErrorString = Msg; - sLastErrorString += "\n"; } // This derived class owns the native object file. This helps implement the // 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; }; @@ -135,6 +139,7 @@ struct LibLTOCodeGenerator : LTOCodeGenerator { } 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. @@ -176,6 +181,14 @@ bool lto_module_is_object_file_for_target(const char* path, return LTOModule::isBitcodeForTarget(Buffer->get(), 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; + return llvm::isBitcodeContainingObjCCategory(*Buffer, Ctx); +} + bool lto_module_is_object_file_in_memory(const void* mem, size_t length) { return LTOModule::isBitcodeFile(mem, length); } @@ -249,8 +262,14 @@ lto_module_t lto_module_create_in_local_context(const void *mem, size_t length, const char *path) { lto_initialize(); llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); + + // 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(mem, length, Options, path); + LTOModule::createInLocalContext(std::move(Context), mem, length, Options, + path); if (!M) return nullptr; return wrap(M->release()); @@ -262,8 +281,8 @@ lto_module_t lto_module_create_in_codegen_context(const void *mem, 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, path); return wrap(M->release()); } @@ -347,7 +366,7 @@ bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) { 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"; @@ -435,3 +454,116 @@ void lto_codegen_set_should_embed_uselists(lto_code_gen_t cg, 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; +} |
