diff options
-rw-r--r-- | llvm/include/llvm/LTO/LTOModule.h | 42 | ||||
-rw-r--r-- | llvm/lib/LTO/LTOModule.cpp | 131 | ||||
-rw-r--r-- | llvm/tools/llvm-lto/llvm-lto.cpp | 49 | ||||
-rw-r--r-- | llvm/tools/lto/lto.cpp | 70 |
4 files changed, 165 insertions, 127 deletions
diff --git a/llvm/include/llvm/LTO/LTOModule.h b/llvm/include/llvm/LTO/LTOModule.h index 83a523613a7..97b5865bd47 100644 --- a/llvm/include/llvm/LTO/LTOModule.h +++ b/llvm/include/llvm/LTO/LTOModule.h @@ -91,25 +91,24 @@ public: /// InitializeAllTargetMCs(); /// InitializeAllAsmPrinters(); /// InitializeAllAsmParsers(); - static LTOModule *createFromFile(const char *path, TargetOptions options, - std::string &errMsg); - static LTOModule *createFromOpenFile(int fd, const char *path, size_t size, - TargetOptions options, - std::string &errMsg); - static LTOModule *createFromOpenFileSlice(int fd, const char *path, - size_t map_size, off_t offset, - TargetOptions options, - std::string &errMsg); - static LTOModule *createFromBuffer(const void *mem, size_t length, - TargetOptions options, std::string &errMsg, - StringRef path = ""); - - static LTOModule *createInLocalContext(const void *mem, size_t length, - TargetOptions options, - std::string &errMsg, StringRef path); - static LTOModule *createInContext(const void *mem, size_t length, - TargetOptions options, std::string &errMsg, - StringRef path, LLVMContext *Context); + static ErrorOr<std::unique_ptr<LTOModule>> + createFromFile(LLVMContext &Context, const char *path, TargetOptions options); + static ErrorOr<std::unique_ptr<LTOModule>> + createFromOpenFile(LLVMContext &Context, int fd, const char *path, + size_t size, TargetOptions options); + static ErrorOr<std::unique_ptr<LTOModule>> + createFromOpenFileSlice(LLVMContext &Context, int fd, const char *path, + size_t map_size, off_t offset, TargetOptions options); + static ErrorOr<std::unique_ptr<LTOModule>> + createFromBuffer(LLVMContext &Context, const void *mem, size_t length, + TargetOptions options, StringRef path = ""); + + static ErrorOr<std::unique_ptr<LTOModule>> + createInLocalContext(const void *mem, size_t length, TargetOptions options, + StringRef path); + static ErrorOr<std::unique_ptr<LTOModule>> + createInContext(const void *mem, size_t length, TargetOptions options, + StringRef path, LLVMContext *Context); const Module &getModule() const { return const_cast<LTOModule*>(this)->getModule(); @@ -207,8 +206,9 @@ private: bool objcClassNameFromExpression(const Constant *c, std::string &name); /// Create an LTOModule (private version). - static LTOModule *makeLTOModule(MemoryBufferRef Buffer, TargetOptions options, - std::string &errMsg, LLVMContext *Context); + static ErrorOr<std::unique_ptr<LTOModule>> + makeLTOModule(MemoryBufferRef Buffer, TargetOptions options, + LLVMContext *Context); }; } #endif diff --git a/llvm/lib/LTO/LTOModule.cpp b/llvm/lib/LTO/LTOModule.cpp index 42a568b54c7..a6a3002e457 100644 --- a/llvm/lib/LTO/LTOModule.cpp +++ b/llvm/lib/LTO/LTOModule.cpp @@ -100,89 +100,72 @@ std::string LTOModule::getProducerString(MemoryBuffer *Buffer) { return getBitcodeProducerString(*BCOrErr, Context); } -LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options, - std::string &errMsg) { +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createFromFile(LLVMContext &Context, const char *path, + TargetOptions options) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile(path); - if (std::error_code EC = BufferOrErr.getError()) { - errMsg = EC.message(); - return nullptr; - } + if (std::error_code EC = BufferOrErr.getError()) + return EC; std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get()); - return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg, - &getGlobalContext()); + return makeLTOModule(Buffer->getMemBufferRef(), options, &Context); } -LTOModule *LTOModule::createFromOpenFile(int fd, const char *path, size_t size, - TargetOptions options, - std::string &errMsg) { - return createFromOpenFileSlice(fd, path, size, 0, options, errMsg); +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createFromOpenFile(LLVMContext &Context, int fd, const char *path, + size_t size, TargetOptions options) { + return createFromOpenFileSlice(Context, fd, path, size, 0, options); } -LTOModule *LTOModule::createFromOpenFileSlice(int fd, const char *path, - size_t map_size, off_t offset, - TargetOptions options, - std::string &errMsg) { +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createFromOpenFileSlice(LLVMContext &Context, int fd, + const char *path, size_t map_size, + off_t offset, TargetOptions options) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getOpenFileSlice(fd, path, map_size, offset); - if (std::error_code EC = BufferOrErr.getError()) { - errMsg = EC.message(); - return nullptr; - } + if (std::error_code EC = BufferOrErr.getError()) + return EC; std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get()); - return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg, - &getGlobalContext()); + return makeLTOModule(Buffer->getMemBufferRef(), options, &Context); } -LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length, - TargetOptions options, - std::string &errMsg, StringRef path) { - return createInContext(mem, length, options, errMsg, path, - &getGlobalContext()); +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createFromBuffer(LLVMContext &Context, const void *mem, + size_t length, TargetOptions options, + StringRef path) { + return createInContext(mem, length, options, path, &Context); } -LTOModule *LTOModule::createInLocalContext(const void *mem, size_t length, - TargetOptions options, - std::string &errMsg, - StringRef path) { - return createInContext(mem, length, options, errMsg, path, nullptr); +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createInLocalContext(const void *mem, size_t length, + TargetOptions options, StringRef path) { + return createInContext(mem, length, options, path, nullptr); } -LTOModule *LTOModule::createInContext(const void *mem, size_t length, - TargetOptions options, - std::string &errMsg, StringRef path, - LLVMContext *Context) { +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createInContext(const void *mem, size_t length, + TargetOptions options, StringRef path, + LLVMContext *Context) { StringRef Data((const char *)mem, length); MemoryBufferRef Buffer(Data, path); - return makeLTOModule(Buffer, options, errMsg, Context); + return makeLTOModule(Buffer, options, Context); } -static std::unique_ptr<Module> parseBitcodeFileImpl(MemoryBufferRef Buffer, - LLVMContext &Context, - bool ShouldBeLazy, - std::string &ErrMsg) { +static ErrorOr<std::unique_ptr<Module>> +parseBitcodeFileImpl(MemoryBufferRef Buffer, LLVMContext &Context, + bool ShouldBeLazy) { // Find the buffer. ErrorOr<MemoryBufferRef> MBOrErr = IRObjectFile::findBitcodeInMemBuffer(Buffer); - if (std::error_code EC = MBOrErr.getError()) { - ErrMsg = EC.message(); - return nullptr; - } - - std::function<void(const DiagnosticInfo &)> DiagnosticHandler = - [&ErrMsg](const DiagnosticInfo &DI) { - raw_string_ostream Stream(ErrMsg); - DiagnosticPrinterRawOStream DP(Stream); - DI.print(DP); - }; + if (std::error_code EC = MBOrErr.getError()) + return EC; if (!ShouldBeLazy) { // Parse the full file. - ErrorOr<std::unique_ptr<Module>> M = - parseBitcodeFile(*MBOrErr, Context, DiagnosticHandler); - if (!M) - return nullptr; + ErrorOr<std::unique_ptr<Module>> M = parseBitcodeFile(*MBOrErr, Context); + if (std::error_code EC = M.getError()) + return EC; return std::move(*M); } @@ -190,16 +173,16 @@ static std::unique_ptr<Module> parseBitcodeFileImpl(MemoryBufferRef Buffer, std::unique_ptr<MemoryBuffer> LightweightBuf = MemoryBuffer::getMemBuffer(*MBOrErr, false); ErrorOr<std::unique_ptr<Module>> M = - getLazyBitcodeModule(std::move(LightweightBuf), Context, - DiagnosticHandler, true /*ShouldLazyLoadMetadata*/); - if (!M) - return nullptr; + getLazyBitcodeModule(std::move(LightweightBuf), Context, nullptr, + true /*ShouldLazyLoadMetadata*/); + if (std::error_code EC = M.getError()) + return EC; return std::move(*M); } -LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, - TargetOptions options, std::string &errMsg, - LLVMContext *Context) { +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::makeLTOModule(MemoryBufferRef Buffer, TargetOptions options, + LLVMContext *Context) { std::unique_ptr<LLVMContext> OwnedContext; if (!Context) { OwnedContext = llvm::make_unique<LLVMContext>(); @@ -208,11 +191,12 @@ LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, // If we own a context, we know this is being used only for symbol // extraction, not linking. Be lazy in that case. - std::unique_ptr<Module> M = parseBitcodeFileImpl( - Buffer, *Context, - /* ShouldBeLazy */ static_cast<bool>(OwnedContext), errMsg); - if (!M) - return nullptr; + ErrorOr<std::unique_ptr<Module>> MOrErr = + parseBitcodeFileImpl(Buffer, *Context, + /* ShouldBeLazy */ static_cast<bool>(OwnedContext)); + if (std::error_code EC = MOrErr.getError()) + return EC; + std::unique_ptr<Module> &M = *MOrErr; std::string TripleStr = M->getTargetTriple(); if (TripleStr.empty()) @@ -220,9 +204,10 @@ LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, llvm::Triple Triple(TripleStr); // find machine architecture for this module + std::string errMsg; const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg); if (!march) - return nullptr; + return std::unique_ptr<LTOModule>(nullptr); // construct LTOModule, hand over ownership of module and target SubtargetFeatures Features; @@ -246,16 +231,16 @@ LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, std::unique_ptr<object::IRObjectFile> IRObj( new object::IRObjectFile(Buffer, std::move(M))); - LTOModule *Ret; + std::unique_ptr<LTOModule> Ret; if (OwnedContext) - Ret = new LTOModule(std::move(IRObj), target, std::move(OwnedContext)); + Ret.reset(new LTOModule(std::move(IRObj), target, std::move(OwnedContext))); else - Ret = new LTOModule(std::move(IRObj), target); + Ret.reset(new LTOModule(std::move(IRObj), target)); Ret->parseSymbols(); Ret->parseMetadata(); - return Ret; + return std::move(Ret); } /// Create a MemoryBuffer from a memory range with an optional name. diff --git a/llvm/tools/llvm-lto/llvm-lto.cpp b/llvm/tools/llvm-lto/llvm-lto.cpp index 07cd9bb1eaf..4bc692279b9 100644 --- a/llvm/tools/llvm-lto/llvm-lto.cpp +++ b/llvm/tools/llvm-lto/llvm-lto.cpp @@ -124,23 +124,27 @@ static void handleDiagnostics(lto_codegen_diagnostic_severity_t Severity, errs() << Msg << "\n"; } +static std::string CurrentActivity; static void diagnosticHandler(const DiagnosticInfo &DI) { raw_ostream &OS = errs(); OS << "llvm-lto: "; switch (DI.getSeverity()) { case DS_Error: - OS << "error: "; + OS << "error"; break; case DS_Warning: - OS << "warning: "; + OS << "warning"; break; case DS_Remark: - OS << "remark: "; + OS << "remark"; break; case DS_Note: - OS << "note: "; + OS << "note"; break; } + if (!CurrentActivity.empty()) + OS << ' ' << CurrentActivity; + OS << ": "; DiagnosticPrinterRawOStream DP(OS); DI.print(DP); @@ -150,6 +154,11 @@ static void diagnosticHandler(const DiagnosticInfo &DI) { exit(1); } +static void diagnosticHandlerWithContenxt(const DiagnosticInfo &DI, + void *Context) { + diagnosticHandler(DI); +} + static void error(const Twine &Msg) { errs() << "llvm-lto: " << Msg << '\n'; exit(1); @@ -172,12 +181,11 @@ getLocalLTOModule(StringRef Path, std::unique_ptr<MemoryBuffer> &Buffer, MemoryBuffer::getFile(Path); error(BufferOrErr, "error loading file '" + Path + "'"); Buffer = std::move(BufferOrErr.get()); - std::string Error; - std::unique_ptr<LTOModule> Ret(LTOModule::createInLocalContext( - Buffer->getBufferStart(), Buffer->getBufferSize(), Options, Error, Path)); - if (!Error.empty()) - error("error loading file '" + Path + "' " + Error); - return Ret; + CurrentActivity = ("loading file '" + Path + "'").str(); + ErrorOr<std::unique_ptr<LTOModule>> Ret = LTOModule::createInLocalContext( + Buffer->getBufferStart(), Buffer->getBufferSize(), Options, Path); + CurrentActivity = ""; + return std::move(*Ret); } /// \brief List symbols in each IR file. @@ -207,10 +215,11 @@ static void createCombinedFunctionIndex() { FunctionInfoIndex CombinedIndex; uint64_t NextModuleId = 0; for (auto &Filename : InputFilenames) { + CurrentActivity = "loading file '" + Filename + "'"; ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr = llvm::getFunctionIndexForFile(Filename, diagnosticHandler); - error(IndexOrErr, "error loading file '" + Filename + "'"); std::unique_ptr<FunctionInfoIndex> Index = std::move(IndexOrErr.get()); + CurrentActivity = ""; // Skip files without a function summary. if (!Index) continue; @@ -257,7 +266,10 @@ int main(int argc, char **argv) { unsigned BaseArg = 0; - LTOCodeGenerator CodeGen(getGlobalContext()); + LLVMContext Context; + Context.setDiagnosticHandler(diagnosticHandlerWithContenxt, nullptr, true); + + LTOCodeGenerator CodeGen(Context); if (UseDiagnosticHandler) CodeGen.setDiagnosticHandler(handleDiagnostics, nullptr); @@ -274,14 +286,11 @@ int main(int argc, char **argv) { std::vector<std::string> KeptDSOSyms; for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) { - std::string error; - std::unique_ptr<LTOModule> Module( - LTOModule::createFromFile(InputFilenames[i].c_str(), Options, error)); - if (!error.empty()) { - errs() << argv[0] << ": error loading file '" << InputFilenames[i] - << "': " << error << "\n"; - return 1; - } + CurrentActivity = "loading file '" + InputFilenames[i] + "'"; + ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr = + LTOModule::createFromFile(Context, InputFilenames[i].c_str(), Options); + std::unique_ptr<LTOModule> &Module = *ModuleOrErr; + CurrentActivity = ""; unsigned NumSyms = Module->getSymbolCount(); for (unsigned I = 0; I < NumSyms; ++I) { diff --git a/llvm/tools/lto/lto.cpp b/llvm/tools/lto/lto.cpp index 6058fb1197e..d13de57e830 100644 --- a/llvm/tools/lto/lto.cpp +++ b/llvm/tools/lto/lto.cpp @@ -15,6 +15,8 @@ #include "llvm-c/lto.h" #include "llvm/ADT/STLExtras.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" @@ -64,6 +66,24 @@ static bool initialized = false; // Holds the command-line option parsing state of the LTO module. static bool parsedOptions = false; +static LLVMContext *LTOContext = nullptr; + +static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { + if (DI.getSeverity() != DS_Error) { + DiagnosticPrinterRawOStream DP(errs()); + DI.print(DP); + errs() << '\n'; + return; + } + sLastErrorString = ""; + { + raw_string_ostream Stream(sLastErrorString); + DiagnosticPrinterRawOStream DP(Stream); + DI.print(DP); + } + sLastErrorString += '\n'; +} + // Initialize the configured targets if they have not been initialized. static void lto_initialize() { if (!initialized) { @@ -79,6 +99,9 @@ static void lto_initialize() { InitializeAllAsmParsers(); InitializeAllAsmPrinters(); InitializeAllDisassemblers(); + + LTOContext = &getGlobalContext(); + LTOContext->setDiagnosticHandler(diagnosticHandler, nullptr, true); initialized = true; } } @@ -95,7 +118,7 @@ static void handleLibLTODiagnostic(lto_codegen_diagnostic_severity_t Severity, // libLTO API semantics, which require that the code generator owns the object // file. struct LibLTOCodeGenerator : LTOCodeGenerator { - LibLTOCodeGenerator() : LTOCodeGenerator(getGlobalContext()) { + LibLTOCodeGenerator() : LTOCodeGenerator(*LTOContext) { setDiagnosticHandler(handleLibLTODiagnostic, nullptr); } LibLTOCodeGenerator(std::unique_ptr<LLVMContext> Context) : LTOCodeGenerator(*Context), OwnedContext(std::move(Context)) { @@ -166,14 +189,21 @@ lto_module_is_object_file_in_memory_for_target(const void* mem, lto_module_t lto_module_create(const char* path) { lto_initialize(); llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - return wrap(LTOModule::createFromFile(path, Options, sLastErrorString)); + ErrorOr<std::unique_ptr<LTOModule>> M = + LTOModule::createFromFile(*LTOContext, path, Options); + if (!M) + return nullptr; + return wrap(M->release()); } lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) { lto_initialize(); llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - return wrap( - LTOModule::createFromOpenFile(fd, path, size, Options, sLastErrorString)); + ErrorOr<std::unique_ptr<LTOModule>> M = + LTOModule::createFromOpenFile(*LTOContext, fd, path, size, Options); + if (!M) + return nullptr; + return wrap(M->release()); } lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path, @@ -182,14 +212,21 @@ lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path, off_t offset) { lto_initialize(); llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - return wrap(LTOModule::createFromOpenFileSlice(fd, path, map_size, offset, - Options, sLastErrorString)); + ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromOpenFileSlice( + *LTOContext, fd, path, map_size, offset, Options); + if (!M) + return nullptr; + return wrap(M->release()); } lto_module_t lto_module_create_from_memory(const void* mem, size_t length) { lto_initialize(); llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - return wrap(LTOModule::createFromBuffer(mem, length, Options, sLastErrorString)); + ErrorOr<std::unique_ptr<LTOModule>> M = + LTOModule::createFromBuffer(*LTOContext, mem, length, Options); + if (!M) + return nullptr; + return wrap(M->release()); } lto_module_t lto_module_create_from_memory_with_path(const void* mem, @@ -197,16 +234,22 @@ lto_module_t lto_module_create_from_memory_with_path(const void* mem, const char *path) { lto_initialize(); llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - return wrap( - LTOModule::createFromBuffer(mem, length, Options, sLastErrorString, path)); + ErrorOr<std::unique_ptr<LTOModule>> M = + LTOModule::createFromBuffer(*LTOContext, mem, length, Options, path); + if (!M) + return nullptr; + return wrap(M->release()); } lto_module_t lto_module_create_in_local_context(const void *mem, size_t length, const char *path) { lto_initialize(); llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - return wrap(LTOModule::createInLocalContext(mem, length, Options, - sLastErrorString, path)); + ErrorOr<std::unique_ptr<LTOModule>> M = + LTOModule::createInLocalContext(mem, length, Options, path); + if (!M) + return nullptr; + return wrap(M->release()); } lto_module_t lto_module_create_in_codegen_context(const void *mem, @@ -215,8 +258,9 @@ lto_module_t lto_module_create_in_codegen_context(const void *mem, lto_code_gen_t cg) { lto_initialize(); llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - return wrap(LTOModule::createInContext(mem, length, Options, sLastErrorString, - path, &unwrap(cg)->getContext())); + ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createInContext( + mem, length, Options, path, &unwrap(cg)->getContext()); + return wrap(M->release()); } void lto_module_dispose(lto_module_t mod) { delete unwrap(mod); } |