Mercurial > hg > CbC > CbC_llvm
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; +}