X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Flto%2Flto.cpp;h=8f62929b326bb66dae91008b3d2ce8edd9fb2532;hb=97c9f0cae01cdb52212c8c427cc94b7c8f929f13;hp=ef37c90ba3b4350fa109838fc1fd65622fabd1c6;hpb=4f897091e40c5cf6fe9ff0d9bf5dc0d28945b389;p=oota-llvm.git diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index ef37c90ba3b..8f62929b326 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -13,16 +13,23 @@ //===----------------------------------------------------------------------===// #include "llvm-c/lto.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/CommandFlags.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/LTO/LTOCodeGenerator.h" #include "llvm/LTO/LTOModule.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Signals.h" #include "llvm/Support/TargetSelect.h" // extra command-line flags needed for LTOCodeGenerator -static cl::opt -DisableOpt("disable-opt", cl::init(false), - cl::desc("Do not run any optimization passes")); +static cl::opt +OptLevel("O", + cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " + "(default = '-O2')"), + cl::Prefix, + cl::ZeroOrMore, + cl::init('2')); static cl::opt DisableInline("disable-inlining", cl::init(false), @@ -50,6 +57,12 @@ static bool parsedOptions = false; // Initialize the configured targets if they have not been initialized. static void lto_initialize() { if (!initialized) { +#ifdef LLVM_ON_WIN32 + // Dialog box on crash disabling doesn't work across DLL boundaries, so do + // it here. + llvm::sys::DisableSystemDialogsOnCrash(); +#endif + InitializeAllTargetInfos(); InitializeAllTargets(); InitializeAllTargetMCs(); @@ -60,7 +73,22 @@ static void lto_initialize() { } } -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOCodeGenerator, lto_code_gen_t) +namespace { + +// 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() {} + LibLTOCodeGenerator(std::unique_ptr Context) + : LTOCodeGenerator(std::move(Context)) {} + + std::unique_ptr NativeObjectFile; +}; + +} + +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LibLTOCodeGenerator, lto_code_gen_t) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t) // Convert the subtarget features into a string to pass to LTOCodeGenerator. @@ -76,6 +104,10 @@ static void lto_add_attrs(lto_code_gen_t cg) { CG->setAttr(attrs.c_str()); } + + if (OptLevel < '0' || OptLevel > '3') + report_fatal_error("Optimization level must be between 0 and 3"); + CG->setOptLevel(OptLevel - '0'); } extern const char* lto_get_version() { @@ -191,20 +223,8 @@ lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod, return unwrap(mod)->getSymbolAttributes(index); } -unsigned int lto_module_get_num_deplibs(lto_module_t mod) { - return unwrap(mod)->getDependentLibraryCount(); -} - -const char* lto_module_get_deplib(lto_module_t mod, unsigned int index) { - return unwrap(mod)->getDependentLibrary(index); -} - -unsigned int lto_module_get_num_linkeropts(lto_module_t mod) { - return unwrap(mod)->getLinkerOptCount(); -} - -const char* lto_module_get_linkeropt(lto_module_t mod, unsigned int index) { - return unwrap(mod)->getLinkerOpt(index); +const char* lto_module_get_linkeropts(lto_module_t mod) { + return unwrap(mod)->getLinkerOpts(); } void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg, @@ -213,31 +233,58 @@ void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg, unwrap(cg)->setDiagnosticHandler(diag_handler, ctxt); } -lto_code_gen_t lto_codegen_create(void) { +static lto_code_gen_t createCodeGen(bool InLocalContext) { lto_initialize(); TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - LTOCodeGenerator *CodeGen = new LTOCodeGenerator(); - if (CodeGen) - CodeGen->setTargetOptions(Options); + LibLTOCodeGenerator *CodeGen = + InLocalContext ? new LibLTOCodeGenerator(make_unique()) + : new LibLTOCodeGenerator(); + CodeGen->setTargetOptions(Options); return wrap(CodeGen); } +lto_code_gen_t lto_codegen_create(void) { + return createCodeGen(/* InLocalContext */ false); +} + +lto_code_gen_t lto_codegen_create_in_local_context(void) { + return createCodeGen(/* InLocalContext */ true); +} + void lto_codegen_dispose(lto_code_gen_t cg) { delete unwrap(cg); } bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) { return !unwrap(cg)->addModule(unwrap(mod)); } +void lto_codegen_set_module(lto_code_gen_t cg, lto_module_t mod) { + unwrap(cg)->setModule(std::unique_ptr(unwrap(mod))); +} + bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) { unwrap(cg)->setDebugInfo(debug); return false; } bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) { - unwrap(cg)->setCodePICModel(model); - return false; + 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(Reloc::Default); + return false; + } + sLastErrorString = "Unknown PIC model"; + return true; } void lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu) { @@ -258,37 +305,66 @@ void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, unwrap(cg)->addMustPreserveSymbol(symbol); } -bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) { +static void maybeParseOptions(lto_code_gen_t cg) { if (!parsedOptions) { unwrap(cg)->parseCodeGenDebugOptions(); lto_add_attrs(cg); parsedOptions = true; } +} + +bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) { + maybeParseOptions(cg); return !unwrap(cg)->writeMergedModules(path, sLastErrorString); } const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) { - if (!parsedOptions) { - unwrap(cg)->parseCodeGenDebugOptions(); - lto_add_attrs(cg); - parsedOptions = true; - } - return unwrap(cg)->compile(length, DisableOpt, DisableInline, - DisableGVNLoadPRE, DisableLTOVectorization, - sLastErrorString); + maybeParseOptions(cg); + LibLTOCodeGenerator *CG = unwrap(cg); + CG->NativeObjectFile = CG->compile(DisableInline, DisableGVNLoadPRE, + DisableLTOVectorization, sLastErrorString); + if (!CG->NativeObjectFile) + return nullptr; + *length = CG->NativeObjectFile->getBufferSize(); + return CG->NativeObjectFile->getBufferStart(); +} + +bool lto_codegen_optimize(lto_code_gen_t cg) { + maybeParseOptions(cg); + return !unwrap(cg)->optimize(DisableInline, + DisableGVNLoadPRE, DisableLTOVectorization, + sLastErrorString); +} + +const void *lto_codegen_compile_optimized(lto_code_gen_t cg, size_t *length) { + maybeParseOptions(cg); + LibLTOCodeGenerator *CG = unwrap(cg); + CG->NativeObjectFile = CG->compileOptimized(sLastErrorString); + if (!CG->NativeObjectFile) + return nullptr; + *length = CG->NativeObjectFile->getBufferSize(); + return CG->NativeObjectFile->getBufferStart(); } bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { - if (!parsedOptions) { - unwrap(cg)->parseCodeGenDebugOptions(); - lto_add_attrs(cg); - parsedOptions = true; - } + maybeParseOptions(cg); return !unwrap(cg)->compile_to_file( - name, DisableOpt, DisableInline, DisableGVNLoadPRE, + name, DisableInline, DisableGVNLoadPRE, DisableLTOVectorization, sLastErrorString); } void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) { unwrap(cg)->setCodeGenDebugOptions(opt); } + +unsigned int lto_api_version() { return LTO_API_VERSION; } + +void lto_codegen_set_should_internalize(lto_code_gen_t cg, + bool ShouldInternalize) { + unwrap(cg)->setShouldInternalize(ShouldInternalize); +} + +void lto_codegen_set_should_embed_uselists(lto_code_gen_t cg, + lto_bool_t ShouldEmbedUselists) { + unwrap(cg)->setShouldEmbedUselists(ShouldEmbedUselists); +}