From: Yunzhong Gao Date: Tue, 17 Nov 2015 19:48:12 +0000 (+0000) Subject: Switch lto codegen to using diagnostic handlers. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=576772b030398af6f21887d306d29ac3be988a72 Switch lto codegen to using diagnostic handlers. This patch removes the std::string& argument from a number of C++ LTO API calls and instead makes them use the installed diagnostic handler. This would also improve consistency of diagnostic handling infrastructure: if an LTO client used lto_codegen_set_diagnostic_handler() to install a custom error handler, we do not want some error messages to go through the custom error handler, and some other error messages to go into sLastErrorString. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253367 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/LTO/LTOCodeGenerator.h b/include/llvm/LTO/LTOCodeGenerator.h index f69dfb1e7f6..68ef3d5f22c 100644 --- a/include/llvm/LTO/LTOCodeGenerator.h +++ b/include/llvm/LTO/LTOCodeGenerator.h @@ -101,7 +101,7 @@ struct LTOCodeGenerator { /// Write the merged module to the file specified by the given path. Return /// true on success. - bool writeMergedModules(const char *Path, std::string &ErrMsg); + bool writeMergedModules(const char *Path); /// Compile the merged module into a *single* object file; the path to object /// file is returned to the caller via argument "name". Return true on @@ -112,7 +112,7 @@ struct LTOCodeGenerator { /// don't who (LTOCodeGenerator or the obj file) will last longer. bool compile_to_file(const char **Name, bool DisableVerify, bool DisableInline, bool DisableGVNLoadPRE, - bool DisableVectorization, std::string &ErrMsg); + bool DisableVectorization); /// As with compile_to_file(), this function compiles the merged module into /// single object file. Instead of returning the object-file-path to the @@ -122,24 +122,23 @@ struct LTOCodeGenerator { /// successful. std::unique_ptr compile(bool DisableVerify, bool DisableInline, bool DisableGVNLoadPRE, - bool DisableVectorization, - std::string &errMsg); + bool DisableVectorization); /// Optimizes the merged module. Returns true on success. bool optimize(bool DisableVerify, bool DisableInline, bool DisableGVNLoadPRE, - bool DisableVectorization, std::string &ErrMsg); + bool DisableVectorization); /// 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. - std::unique_ptr compileOptimized(std::string &ErrMsg); + std::unique_ptr compileOptimized(); /// Compile the merged optimized module into out.size() object files each /// representing a linkable partition of the module. If out contains more /// than one element, code generation is done in parallel with out.size() /// threads. Object files will be written to members of out. Returns true on /// success. - bool compileOptimized(ArrayRef Out, std::string &ErrMsg); + bool compileOptimized(ArrayRef Out); void setDiagnosticHandler(lto_diagnostic_handler_t, void *); @@ -148,18 +147,20 @@ struct LTOCodeGenerator { private: void initializeLTOPasses(); - bool compileOptimizedToFile(const char **Name, std::string &ErrMsg); + bool compileOptimizedToFile(const char **Name); void applyScopeRestrictions(); void applyRestriction(GlobalValue &GV, ArrayRef Libcalls, std::vector &MustPreserveList, SmallPtrSetImpl &AsmUsed, Mangler &Mangler); - bool determineTarget(std::string &ErrMsg); + bool determineTarget(); static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context); void DiagnosticHandler2(const DiagnosticInfo &DI); + void emitError(const std::string &ErrMsg); + typedef StringMap StringSet; std::unique_ptr OwnedContext; diff --git a/lib/LTO/LTOCodeGenerator.cpp b/lib/LTO/LTOCodeGenerator.cpp index 56240502c02..1604769aba8 100644 --- a/lib/LTO/LTOCodeGenerator.cpp +++ b/lib/LTO/LTOCodeGenerator.cpp @@ -172,9 +172,8 @@ void LTOCodeGenerator::setOptLevel(unsigned Level) { } } -bool LTOCodeGenerator::writeMergedModules(const char *Path, - std::string &ErrMsg) { - if (!determineTarget(ErrMsg)) +bool LTOCodeGenerator::writeMergedModules(const char *Path) { + if (!determineTarget()) return false; // mark which symbols can not be internalized @@ -184,8 +183,9 @@ bool LTOCodeGenerator::writeMergedModules(const char *Path, std::error_code EC; tool_output_file Out(Path, EC, sys::fs::F_None); if (EC) { - ErrMsg = "could not open bitcode file for writing: "; + std::string ErrMsg = "could not open bitcode file for writing: "; ErrMsg += Path; + emitError(ErrMsg); return false; } @@ -194,8 +194,9 @@ bool LTOCodeGenerator::writeMergedModules(const char *Path, Out.os().close(); if (Out.os().has_error()) { - ErrMsg = "could not write bitcode file: "; + std::string ErrMsg = "could not write bitcode file: "; ErrMsg += Path; + emitError(ErrMsg); Out.os().clear_error(); return false; } @@ -204,22 +205,21 @@ bool LTOCodeGenerator::writeMergedModules(const char *Path, return true; } -bool LTOCodeGenerator::compileOptimizedToFile(const char **Name, - std::string &ErrMsg) { +bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) { // make unique temp .o file to put generated object file SmallString<128> Filename; int FD; std::error_code EC = sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename); if (EC) { - ErrMsg = EC.message(); + emitError(EC.message()); return false; } // generate object file tool_output_file objFile(Filename.c_str(), FD); - bool genResult = compileOptimized(&objFile.os(), ErrMsg); + bool genResult = compileOptimized(&objFile.os()); objFile.os().close(); if (objFile.os().has_error()) { objFile.os().clear_error(); @@ -239,16 +239,16 @@ bool LTOCodeGenerator::compileOptimizedToFile(const char **Name, } std::unique_ptr -LTOCodeGenerator::compileOptimized(std::string &ErrMsg) { +LTOCodeGenerator::compileOptimized() { const char *name; - if (!compileOptimizedToFile(&name, ErrMsg)) + if (!compileOptimizedToFile(&name)) return nullptr; // read .o file into memory buffer ErrorOr> BufferOrErr = MemoryBuffer::getFile(name, -1, false); if (std::error_code EC = BufferOrErr.getError()) { - ErrMsg = EC.message(); + emitError(EC.message()); sys::fs::remove(NativeObjectPath); return nullptr; } @@ -262,27 +262,25 @@ LTOCodeGenerator::compileOptimized(std::string &ErrMsg) { bool LTOCodeGenerator::compile_to_file(const char **Name, bool DisableVerify, bool DisableInline, bool DisableGVNLoadPRE, - bool DisableVectorization, - std::string &ErrMsg) { + bool DisableVectorization) { if (!optimize(DisableVerify, DisableInline, DisableGVNLoadPRE, - DisableVectorization, ErrMsg)) + DisableVectorization)) return false; - return compileOptimizedToFile(Name, ErrMsg); + return compileOptimizedToFile(Name); } std::unique_ptr LTOCodeGenerator::compile(bool DisableVerify, bool DisableInline, - bool DisableGVNLoadPRE, bool DisableVectorization, - std::string &ErrMsg) { + bool DisableGVNLoadPRE, bool DisableVectorization) { if (!optimize(DisableVerify, DisableInline, DisableGVNLoadPRE, - DisableVectorization, ErrMsg)) + DisableVectorization)) return nullptr; - return compileOptimized(ErrMsg); + return compileOptimized(); } -bool LTOCodeGenerator::determineTarget(std::string &ErrMsg) { +bool LTOCodeGenerator::determineTarget() { if (TargetMach) return true; @@ -294,9 +292,12 @@ bool LTOCodeGenerator::determineTarget(std::string &ErrMsg) { llvm::Triple Triple(TripleStr); // create target machine from info for merged modules + std::string ErrMsg; const Target *march = TargetRegistry::lookupTarget(TripleStr, ErrMsg); - if (!march) + if (!march) { + emitError(ErrMsg); return false; + } // Construct LTOModule, hand over ownership of module and target. Use MAttr as // the default set of features. @@ -459,9 +460,8 @@ void LTOCodeGenerator::applyScopeRestrictions() { /// Optimize merged modules using various IPO passes bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline, bool DisableGVNLoadPRE, - bool DisableVectorization, - std::string &ErrMsg) { - if (!this->determineTarget(ErrMsg)) + bool DisableVectorization) { + if (!this->determineTarget()) return false; // Mark which symbols can not be internalized @@ -496,9 +496,8 @@ bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline, return true; } -bool LTOCodeGenerator::compileOptimized(ArrayRef Out, - std::string &ErrMsg) { - if (!this->determineTarget(ErrMsg)) +bool LTOCodeGenerator::compileOptimized(ArrayRef Out) { + if (!this->determineTarget()) return false; legacy::PassManager preCodeGenPasses; @@ -586,3 +585,20 @@ LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler, Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this, /* RespectFilters */ true); } + +namespace { +class LTODiagnosticInfo : public DiagnosticInfo { + const Twine &Msg; +public: + LTODiagnosticInfo(const Twine &DiagMsg, DiagnosticSeverity Severity=DS_Error) + : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {} + void print(DiagnosticPrinter &DP) const override { DP << Msg; } +}; +} + +void LTOCodeGenerator::emitError(const std::string &ErrMsg) { + if (DiagHandler) + (*DiagHandler)(LTO_DS_ERROR, ErrMsg.c_str(), DiagContext); + else + Context.diagnose(LTODiagnosticInfo(ErrMsg)); +} diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index 04050c54870..c74353282b6 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -318,10 +318,10 @@ int main(int argc, char **argv) { CodeGen.setAttr(attrs.c_str()); if (!OutputFilename.empty()) { - std::string ErrorInfo; if (!CodeGen.optimize(DisableVerify, DisableInline, DisableGVNLoadPRE, - DisableLTOVectorization, ErrorInfo)) { - errs() << argv[0] << ": error optimizing the code: " << ErrorInfo << "\n"; + DisableLTOVectorization)) { + // Diagnostic messages should have been printed by the handler. + errs() << argv[0] << ": error optimizing the code\n"; return 1; } @@ -341,8 +341,9 @@ int main(int argc, char **argv) { OSPtrs.push_back(&OSs.back().os()); } - if (!CodeGen.compileOptimized(OSPtrs, ErrorInfo)) { - errs() << argv[0] << ": error compiling the code: " << ErrorInfo << "\n"; + if (!CodeGen.compileOptimized(OSPtrs)) { + // Diagnostic messages should have been printed by the handler. + errs() << argv[0] << ": error compiling the code\n"; return 1; } @@ -354,14 +355,11 @@ int main(int argc, char **argv) { return 1; } - std::string ErrorInfo; const char *OutputName = nullptr; if (!CodeGen.compile_to_file(&OutputName, DisableVerify, DisableInline, - DisableGVNLoadPRE, DisableLTOVectorization, - ErrorInfo)) { - errs() << argv[0] - << ": error compiling the code: " << ErrorInfo - << "\n"; + DisableGVNLoadPRE, DisableLTOVectorization)) { + // Diagnostic messages should have been printed by the handler. + errs() << argv[0] << ": error compiling the code\n"; return 1; } diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index 0839a566cc5..ee389da2499 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -333,7 +333,7 @@ static void maybeParseOptions(lto_code_gen_t cg) { bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) { maybeParseOptions(cg); - return !unwrap(cg)->writeMergedModules(path, sLastErrorString); + return !unwrap(cg)->writeMergedModules(path); } const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) { @@ -341,7 +341,7 @@ const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) { LibLTOCodeGenerator *CG = unwrap(cg); CG->NativeObjectFile = CG->compile(DisableVerify, DisableInline, DisableGVNLoadPRE, - DisableLTOVectorization, sLastErrorString); + DisableLTOVectorization); if (!CG->NativeObjectFile) return nullptr; *length = CG->NativeObjectFile->getBufferSize(); @@ -351,13 +351,13 @@ const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) { bool lto_codegen_optimize(lto_code_gen_t cg) { maybeParseOptions(cg); return !unwrap(cg)->optimize(DisableVerify, DisableInline, DisableGVNLoadPRE, - DisableLTOVectorization, sLastErrorString); + DisableLTOVectorization); } 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); + CG->NativeObjectFile = CG->compileOptimized(); if (!CG->NativeObjectFile) return nullptr; *length = CG->NativeObjectFile->getBufferSize(); @@ -368,7 +368,7 @@ bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { maybeParseOptions(cg); return !unwrap(cg)->compile_to_file( name, DisableVerify, DisableInline, DisableGVNLoadPRE, - DisableLTOVectorization, sLastErrorString); + DisableLTOVectorization); } void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {