Index: include/llvm/LTO/LTOCodeGenerator.h =================================================================== --- include/llvm/LTO/LTOCodeGenerator.h +++ include/llvm/LTO/LTOCodeGenerator.h @@ -82,7 +82,7 @@ void setShouldInternalize(bool Value) { ShouldInternalize = Value; } void setShouldEmbedUselists(bool Value) { ShouldEmbedUselists = Value; } - void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; } + void addMustPreserveSymbol(StringRef sym) { MustPreserveSymbols[sym] = 1; } // To pass options to the driver and optimization passes. These options are // not necessarily for debugging purpose (The function name is misleading). @@ -117,11 +117,10 @@ // (linker), it brings the object to a buffer, and return the buffer to the // caller. This function should delete intermediate object file once its content // is brought to memory. Return NULL if the compilation was not successful. - const void *compile(size_t *length, - bool disableInline, - bool disableGVNLoadPRE, - bool disableVectorization, - std::string &errMsg); + std::unique_ptr compile(bool disableInline, + bool disableGVNLoadPRE, + bool disableVectorization, + std::string &errMsg); // Optimizes the merged module. Returns true on success. bool optimize(bool disableInline, @@ -132,7 +131,7 @@ // Compiles the merged optimized module into a single object file. It brings // the object to a buffer, and returns the buffer to the caller. Return NULL // if the compilation was not successful. - const void *compileOptimized(size_t *length, std::string &errMsg); + std::unique_ptr compileOptimized(std::string &errMsg); void setDiagnosticHandler(lto_diagnostic_handler_t, void *); @@ -166,7 +165,6 @@ lto_codegen_model CodeModel = LTO_CODEGEN_PIC_MODEL_DEFAULT; StringSet MustPreserveSymbols; StringSet AsmUndefinedRefs; - std::unique_ptr NativeObjectFile; std::vector CodegenOptions; std::string MCpu; std::string MAttr; Index: lib/LTO/LTOCodeGenerator.cpp =================================================================== --- lib/LTO/LTOCodeGenerator.cpp +++ lib/LTO/LTOCodeGenerator.cpp @@ -250,8 +250,8 @@ return true; } -const void *LTOCodeGenerator::compileOptimized(size_t *length, - std::string &errMsg) { +std::unique_ptr +LTOCodeGenerator::compileOptimized(std::string &errMsg) { const char *name; if (!compileOptimizedToFile(&name, errMsg)) return nullptr; @@ -264,16 +264,11 @@ sys::fs::remove(NativeObjectPath); return nullptr; } - NativeObjectFile = std::move(*BufferOrErr); // remove temp files sys::fs::remove(NativeObjectPath); - // return buffer, unless error - if (!NativeObjectFile) - return nullptr; - *length = NativeObjectFile->getBufferSize(); - return NativeObjectFile->getBufferStart(); + return std::move(*BufferOrErr); } @@ -289,16 +284,14 @@ return compileOptimizedToFile(name, errMsg); } -const void* LTOCodeGenerator::compile(size_t *length, - bool disableInline, - bool disableGVNLoadPRE, - bool disableVectorization, - std::string &errMsg) { +std::unique_ptr +LTOCodeGenerator::compile(bool disableInline, bool disableGVNLoadPRE, + bool disableVectorization, std::string &errMsg) { if (!optimize(disableInline, disableGVNLoadPRE, disableVectorization, errMsg)) return nullptr; - return compileOptimized(length, errMsg); + return compileOptimized(errMsg); } bool LTOCodeGenerator::determineTarget(std::string &errMsg) { Index: tools/llvm-lto/llvm-lto.cpp =================================================================== --- tools/llvm-lto/llvm-lto.cpp +++ tools/llvm-lto/llvm-lto.cpp @@ -253,11 +253,9 @@ CodeGen.setAttr(attrs.c_str()); if (!OutputFilename.empty()) { - size_t len = 0; std::string ErrorInfo; - const void *Code = - CodeGen.compile(&len, DisableInline, DisableGVNLoadPRE, - DisableLTOVectorization, ErrorInfo); + std::unique_ptr Code = CodeGen.compile( + DisableInline, DisableGVNLoadPRE, DisableLTOVectorization, ErrorInfo); if (!Code) { errs() << argv[0] << ": error compiling the code: " << ErrorInfo << "\n"; @@ -272,7 +270,7 @@ return 1; } - FileStream.write(reinterpret_cast(Code), len); + FileStream.write(Code->getBufferStart(), Code->getBufferSize()); } else { std::string ErrorInfo; const char *OutputName = nullptr; Index: tools/lto/lto.cpp =================================================================== --- tools/lto/lto.cpp +++ tools/lto/lto.cpp @@ -73,7 +73,22 @@ } } -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. @@ -235,11 +250,10 @@ TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - LTOCodeGenerator *CodeGen = - InLocalContext ? new LTOCodeGenerator(make_unique()) - : new LTOCodeGenerator(); - if (CodeGen) - CodeGen->setTargetOptions(Options); + LibLTOCodeGenerator *CodeGen = + InLocalContext ? new LibLTOCodeGenerator(make_unique()) + : new LibLTOCodeGenerator(); + CodeGen->setTargetOptions(Options); return wrap(CodeGen); } @@ -304,9 +318,13 @@ const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) { maybeParseOptions(cg); - return unwrap(cg)->compile(length, DisableInline, - DisableGVNLoadPRE, DisableLTOVectorization, - sLastErrorString); + 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) { @@ -318,7 +336,12 @@ const void *lto_codegen_compile_optimized(lto_code_gen_t cg, size_t *length) { maybeParseOptions(cg); - return unwrap(cg)->compileOptimized(length, sLastErrorString); + 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) {