Switch lto codegen to using diagnostic handlers.
authorYunzhong Gao <Yunzhong_Gao@playstation.sony.com>
Tue, 17 Nov 2015 19:48:12 +0000 (19:48 +0000)
committerYunzhong Gao <Yunzhong_Gao@playstation.sony.com>
Tue, 17 Nov 2015 19:48:12 +0000 (19:48 +0000)
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

include/llvm/LTO/LTOCodeGenerator.h
lib/LTO/LTOCodeGenerator.cpp
tools/llvm-lto/llvm-lto.cpp
tools/lto/lto.cpp

index f69dfb1e7f6c1ce255df6142e24704f12e4c682b..68ef3d5f22cccb3185e406c98cae266f699fcb50 100644 (file)
@@ -101,7 +101,7 @@ struct LTOCodeGenerator {
 
   /// Write the merged module to the file specified by the given path.  Return
   /// true on success.
 
   /// 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
 
   /// 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,
   /// 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
 
   /// 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<MemoryBuffer> compile(bool DisableVerify, bool DisableInline,
                                         bool DisableGVNLoadPRE,
   /// successful.
   std::unique_ptr<MemoryBuffer> 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,
 
   /// 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.
 
   /// 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<MemoryBuffer> compileOptimized(std::string &ErrMsg);
+  std::unique_ptr<MemoryBuffer> 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.
 
   /// 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<raw_pwrite_stream *> Out, std::string &ErrMsg);
+  bool compileOptimized(ArrayRef<raw_pwrite_stream *> Out);
 
   void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
 
 
   void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
 
@@ -148,18 +147,20 @@ struct LTOCodeGenerator {
 private:
   void initializeLTOPasses();
 
 private:
   void initializeLTOPasses();
 
-  bool compileOptimizedToFile(const char **Name, std::string &ErrMsg);
+  bool compileOptimizedToFile(const char **Name);
   void applyScopeRestrictions();
   void applyRestriction(GlobalValue &GV, ArrayRef<StringRef> Libcalls,
                         std::vector<const char *> &MustPreserveList,
                         SmallPtrSetImpl<GlobalValue *> &AsmUsed,
                         Mangler &Mangler);
   void applyScopeRestrictions();
   void applyRestriction(GlobalValue &GV, ArrayRef<StringRef> Libcalls,
                         std::vector<const char *> &MustPreserveList,
                         SmallPtrSetImpl<GlobalValue *> &AsmUsed,
                         Mangler &Mangler);
-  bool determineTarget(std::string &ErrMsg);
+  bool determineTarget();
 
   static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context);
 
   void DiagnosticHandler2(const DiagnosticInfo &DI);
 
 
   static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context);
 
   void DiagnosticHandler2(const DiagnosticInfo &DI);
 
+  void emitError(const std::string &ErrMsg);
+
   typedef StringMap<uint8_t> StringSet;
 
   std::unique_ptr<LLVMContext> OwnedContext;
   typedef StringMap<uint8_t> StringSet;
 
   std::unique_ptr<LLVMContext> OwnedContext;
index 56240502c02821f51f7785c39623ad6fb4e9f9bf..1604769aba8c20f04e4624dfa7ccba23f0266f14 100644 (file)
@@ -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
     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) {
   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;
     ErrMsg += Path;
+    emitError(ErrMsg);
     return false;
   }
 
     return false;
   }
 
@@ -194,8 +194,9 @@ bool LTOCodeGenerator::writeMergedModules(const char *Path,
   Out.os().close();
 
   if (Out.os().has_error()) {
   Out.os().close();
 
   if (Out.os().has_error()) {
-    ErrMsg = "could not write bitcode file: ";
+    std::string ErrMsg = "could not write bitcode file: ";
     ErrMsg += Path;
     ErrMsg += Path;
+    emitError(ErrMsg);
     Out.os().clear_error();
     return false;
   }
     Out.os().clear_error();
     return false;
   }
@@ -204,22 +205,21 @@ bool LTOCodeGenerator::writeMergedModules(const char *Path,
   return true;
 }
 
   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) {
   // 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);
 
     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();
   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<MemoryBuffer>
 }
 
 std::unique_ptr<MemoryBuffer>
-LTOCodeGenerator::compileOptimized(std::string &ErrMsg) {
+LTOCodeGenerator::compileOptimized() {
   const char *name;
   const char *name;
-  if (!compileOptimizedToFile(&name, ErrMsg))
+  if (!compileOptimizedToFile(&name))
     return nullptr;
 
   // read .o file into memory buffer
   ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
       MemoryBuffer::getFile(name, -1, false);
   if (std::error_code EC = BufferOrErr.getError()) {
     return nullptr;
 
   // read .o file into memory buffer
   ErrorOr<std::unique_ptr<MemoryBuffer>> 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;
   }
     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 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,
   if (!optimize(DisableVerify, DisableInline, DisableGVNLoadPRE,
-                DisableVectorization, ErrMsg))
+                DisableVectorization))
     return false;
 
     return false;
 
-  return compileOptimizedToFile(Name, ErrMsg);
+  return compileOptimizedToFile(Name);
 }
 
 std::unique_ptr<MemoryBuffer>
 LTOCodeGenerator::compile(bool DisableVerify, bool DisableInline,
 }
 
 std::unique_ptr<MemoryBuffer>
 LTOCodeGenerator::compile(bool DisableVerify, bool DisableInline,
-                          bool DisableGVNLoadPRE, bool DisableVectorization,
-                          std::string &ErrMsg) {
+                          bool DisableGVNLoadPRE, bool DisableVectorization) {
   if (!optimize(DisableVerify, DisableInline, DisableGVNLoadPRE,
   if (!optimize(DisableVerify, DisableInline, DisableGVNLoadPRE,
-                DisableVectorization, ErrMsg))
+                DisableVectorization))
     return nullptr;
 
     return nullptr;
 
-  return compileOptimized(ErrMsg);
+  return compileOptimized();
 }
 
 }
 
-bool LTOCodeGenerator::determineTarget(std::string &ErrMsg) {
+bool LTOCodeGenerator::determineTarget() {
   if (TargetMach)
     return true;
 
   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
   llvm::Triple Triple(TripleStr);
 
   // create target machine from info for merged modules
+  std::string ErrMsg;
   const Target *march = TargetRegistry::lookupTarget(TripleStr, ErrMsg);
   const Target *march = TargetRegistry::lookupTarget(TripleStr, ErrMsg);
-  if (!march)
+  if (!march) {
+    emitError(ErrMsg);
     return false;
     return false;
+  }
 
   // Construct LTOModule, hand over ownership of module and target. Use MAttr as
   // the default set of features.
 
   // 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,
 /// 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
     return false;
 
   // Mark which symbols can not be internalized
@@ -496,9 +496,8 @@ bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline,
   return true;
 }
 
   return true;
 }
 
-bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out,
-                                        std::string &ErrMsg) {
-  if (!this->determineTarget(ErrMsg))
+bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out) {
+  if (!this->determineTarget())
     return false;
 
   legacy::PassManager preCodeGenPasses;
     return false;
 
   legacy::PassManager preCodeGenPasses;
@@ -586,3 +585,20 @@ LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler,
   Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this,
                                /* RespectFilters */ true);
 }
   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));
+}
index 04050c548704dbc8644452db068301a824d72835..c74353282b6c75ba7b439f7932fc3550e89c1ae1 100644 (file)
@@ -318,10 +318,10 @@ int main(int argc, char **argv) {
     CodeGen.setAttr(attrs.c_str());
 
   if (!OutputFilename.empty()) {
     CodeGen.setAttr(attrs.c_str());
 
   if (!OutputFilename.empty()) {
-    std::string ErrorInfo;
     if (!CodeGen.optimize(DisableVerify, DisableInline, DisableGVNLoadPRE,
     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;
     }
 
       return 1;
     }
 
@@ -341,8 +341,9 @@ int main(int argc, char **argv) {
       OSPtrs.push_back(&OSs.back().os());
     }
 
       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;
     }
 
       return 1;
     }
 
@@ -354,14 +355,11 @@ int main(int argc, char **argv) {
       return 1;
     }
 
       return 1;
     }
 
-    std::string ErrorInfo;
     const char *OutputName = nullptr;
     if (!CodeGen.compile_to_file(&OutputName, DisableVerify, DisableInline,
     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;
     }
 
       return 1;
     }
 
index 0839a566cc5832ec0461cf18c8ae13f62472998a..ee389da2499ef5b7db3275cbb01dc80758c991a9 100644 (file)
@@ -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);
 
 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) {
 }
 
 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,
   LibLTOCodeGenerator *CG = unwrap(cg);
   CG->NativeObjectFile =
       CG->compile(DisableVerify, DisableInline, DisableGVNLoadPRE,
-                  DisableLTOVectorization, sLastErrorString);
+                  DisableLTOVectorization);
   if (!CG->NativeObjectFile)
     return nullptr;
   *length = CG->NativeObjectFile->getBufferSize();
   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,
 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);
 }
 
 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();
   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,
   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) {
 }
 
 void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {