Split out TranslateClParser and add new parse method that reuses SourceMgr.
authorJacques Pienaar <jpienaar@google.com>
Wed, 26 Jun 2019 18:12:40 +0000 (11:12 -0700)
committerA. Unique TensorFlower <gardener@tensorflow.org>
Wed, 26 Jun 2019 18:14:45 +0000 (11:14 -0700)
Split out class to command line parser for translate methods into standalone
class. Similar to splitting up mlir-opt to reuse functionality with different
initialization.

PiperOrigin-RevId: 255225790

mlir/include/mlir/Parser.h
mlir/include/mlir/Support/TranslateClParser.h [new file with mode: 0644]
mlir/lib/Parser/Parser.cpp
mlir/lib/Support/CMakeLists.txt
mlir/lib/Support/TranslateClParser.cpp [new file with mode: 0644]
mlir/tools/mlir-translate/CMakeLists.txt
mlir/tools/mlir-translate/mlir-translate.cpp

index 2da728b..85c183a 100644 (file)
@@ -44,6 +44,13 @@ Module *parseSourceFile(const llvm::SourceMgr &sourceMgr, MLIRContext *context);
 /// the error handler registered in the context, and a null pointer is returned.
 Module *parseSourceFile(llvm::StringRef filename, MLIRContext *context);
 
+/// This parses the file specified by the indicated filename using the provided
+/// SourceMgr and returns an MLIR module if it was valid.  If not, the error
+/// message is emitted through the error handler registered in the context, and
+/// a null pointer is returned.
+Module *parseSourceFile(llvm::StringRef filename, llvm::SourceMgr &sourceMgr,
+                        MLIRContext *context);
+
 /// This parses the module string to a MLIR module if it was valid.  If not, the
 /// error message is emitted through the error handler registered in the
 /// context, and a null pointer is returned.
diff --git a/mlir/include/mlir/Support/TranslateClParser.h b/mlir/include/mlir/Support/TranslateClParser.h
new file mode 100644 (file)
index 0000000..e936745
--- /dev/null
@@ -0,0 +1,50 @@
+//===- TranslateClParser.h - Translations command line parser ---*- C++ -*-===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+//
+// This file contains custom command line parser for translations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_SUPPORT_TRANSLATE_CL_PARSER_H_
+#define MLIR_SUPPORT_TRANSLATE_CL_PARSER_H_
+
+#include "mlir/Support/LLVM.h"
+#include "llvm/Support/CommandLine.h"
+#include <functional>
+
+namespace mlir {
+
+class LogicalResult;
+class MLIRContext;
+
+/// Common interface for source-to-source translation functions.
+using TranslateFunction = std::function<LogicalResult(
+    StringRef inputFilename, StringRef outputFilename, MLIRContext *)>;
+
+/// Custom parser for TranslateFunction.
+/// Wraps TranslateToMLIRFunctions and TranslateFromMLIRFunctions into
+/// TranslateFunctions before registering them as options.
+struct TranslationParser : public llvm::cl::parser<const TranslateFunction *> {
+  TranslationParser(llvm::cl::Option &opt);
+
+  void printOptionInfo(const llvm::cl::Option &O,
+                       size_t GlobalWidth) const override;
+};
+
+} // namespace mlir
+
+#endif // MLIR_SUPPORT_TRANSLATE_CL_PARSER_H_
index 1fd191f..a384145 100644 (file)
@@ -4150,17 +4150,32 @@ Module *mlir::parseSourceFile(const llvm::SourceMgr &sourceMgr,
 /// MLIR module if it was valid.  If not, the error message is emitted through
 /// the error handler registered in the context, and a null pointer is returned.
 Module *mlir::parseSourceFile(StringRef filename, MLIRContext *context) {
+  llvm::SourceMgr sourceMgr;
+  return parseSourceFile(filename, sourceMgr, context);
+}
+
+/// This parses the file specified by the indicated filename using the provided
+/// SourceMgr and returns an MLIR module if it was valid.  If not, the error
+/// message is emitted through the error handler registered in the context, and
+/// a null pointer is returned.
+Module *mlir::parseSourceFile(StringRef filename, llvm::SourceMgr &sourceMgr,
+                              MLIRContext *context) {
+  if (sourceMgr.getNumBuffers() != 0) {
+    // TODO(b/136086478): Extend to support multiple buffers.
+    emitError(mlir::UnknownLoc::get(context),
+              "only main buffer parsed at the moment");
+    return nullptr;
+  }
   auto file_or_err = llvm::MemoryBuffer::getFile(filename);
   if (std::error_code error = file_or_err.getError()) {
     emitError(mlir::UnknownLoc::get(context),
-              "Could not open input file " + filename);
+              "could not open input file " + filename);
     return nullptr;
   }
 
   // Load the MLIR module.
-  llvm::SourceMgr source_mgr;
-  source_mgr.AddNewSourceBuffer(std::move(*file_or_err), llvm::SMLoc());
-  return parseSourceFile(source_mgr, context);
+  sourceMgr.AddNewSourceBuffer(std::move(*file_or_err), llvm::SMLoc());
+  return parseSourceFile(sourceMgr, context);
 }
 
 /// This parses the program string to a MLIR module if it was valid. If not,
index a82bd82..e725f70 100644 (file)
@@ -2,6 +2,7 @@ set(LLVM_OPTIONAL_SOURCES
   FileUtilities.cpp
   MlirOptMain.cpp
   StorageUniquer.cpp
+  TranslateClParser.cpp
   TypeUtilities.cpp
 )
 
@@ -29,3 +30,11 @@ add_llvm_library(MLIROptMain
   ${MLIR_MAIN_INCLUDE_DIR}/mlir/Support
   )
 target_link_libraries(MLIROptMain LLVMSupport)
+
+add_llvm_library(MLIRTranslateClParser
+  TranslateClParser.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${MLIR_MAIN_INCLUDE_DIR}/mlir/Support
+  )
+target_link_libraries(MLIRTranslateClParser LLVMSupport)
diff --git a/mlir/lib/Support/TranslateClParser.cpp b/mlir/lib/Support/TranslateClParser.cpp
new file mode 100644 (file)
index 0000000..eb18acb
--- /dev/null
@@ -0,0 +1,104 @@
+//===- TranslateClParser.h - Translations command line parser -------------===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+//
+// This file contains custom command line parser for translations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Support/TranslateClParser.h"
+
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/Module.h"
+#include "mlir/Parser.h"
+#include "mlir/Support/FileUtilities.h"
+#include "mlir/Support/LogicalResult.h"
+#include "mlir/Translation.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/ToolOutputFile.h"
+
+using namespace mlir;
+
+// Storage for the translation function wrappers that survive the parser.
+static llvm::SmallVector<TranslateFunction, 16> wrapperStorage;
+
+static LogicalResult printMLIROutput(Module &module,
+                                     llvm::StringRef outputFilename) {
+  if (failed(module.verify()))
+    return failure();
+  auto file = openOutputFile(outputFilename);
+  if (!file)
+    return failure();
+  module.print(file->os());
+  file->keep();
+  return success();
+}
+
+TranslationParser::TranslationParser(llvm::cl::Option &opt)
+    : llvm::cl::parser<const TranslateFunction *>(opt) {
+  const auto &toMLIRRegistry = getTranslationToMLIRRegistry();
+  const auto &fromMLIRRegistry = getTranslationFromMLIRRegistry();
+
+  // Reserve the required capacity upfront so that pointers are not
+  // invalidated on reallocation.
+  wrapperStorage.reserve(toMLIRRegistry.size() + fromMLIRRegistry.size());
+  for (const auto &kv : toMLIRRegistry) {
+    TranslateToMLIRFunction function = kv.second;
+    TranslateFunction wrapper = [function](StringRef inputFilename,
+                                           StringRef outputFilename,
+                                           MLIRContext *context) {
+      std::unique_ptr<Module> module = function(inputFilename, context);
+      if (!module)
+        return failure();
+      return printMLIROutput(*module, outputFilename);
+    };
+    wrapperStorage.emplace_back(std::move(wrapper));
+
+    addLiteralOption(kv.first(), &wrapperStorage.back(), kv.first());
+  }
+
+  for (const auto &kv : fromMLIRRegistry) {
+    TranslateFromMLIRFunction function = kv.second;
+    TranslateFunction wrapper = [function](StringRef inputFilename,
+                                           StringRef outputFilename,
+                                           MLIRContext *context) {
+      llvm::SourceMgr sourceMgr;
+      SourceMgrDiagnosticHandler sourceMgrHandler(sourceMgr, context);
+      auto module = std::unique_ptr<Module>(
+          parseSourceFile(inputFilename, sourceMgr, context));
+      if (!module)
+        return failure();
+      return failure(function(module.get(), outputFilename));
+    };
+    wrapperStorage.emplace_back(std::move(wrapper));
+
+    addLiteralOption(kv.first(), &wrapperStorage.back(), kv.first());
+  }
+}
+
+void TranslationParser::printOptionInfo(const llvm::cl::Option &O,
+                                        size_t GlobalWidth) const {
+  TranslationParser *TP = const_cast<TranslationParser *>(this);
+  llvm::array_pod_sort(TP->Values.begin(), TP->Values.end(),
+                       [](const TranslationParser::OptionInfo *VT1,
+                          const TranslationParser::OptionInfo *VT2) {
+                         return VT1->Name.compare(VT2->Name);
+                       });
+  using llvm::cl::parser;
+  parser<const TranslateFunction *>::printOptionInfo(O, GlobalWidth);
+}
index be29c6c..50df9de 100644 (file)
@@ -19,4 +19,4 @@ add_llvm_executable(mlir-translate
 )
 llvm_update_compile_flags(mlir-translate)
 whole_archive_link(mlir-translate ${LIBS})
-target_link_libraries(mlir-translate PRIVATE MLIRIR ${LIBS} LLVMSupport)
+target_link_libraries(mlir-translate PRIVATE MLIRIR MLIRTranslateClParser ${LIBS} LLVMSupport)
index 0577623..0ff5e6e 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "mlir/IR/Diagnostics.h"
 #include "mlir/IR/MLIRContext.h"
-#include "mlir/IR/Module.h"
-#include "mlir/Parser.h"
-#include "mlir/Support/FileUtilities.h"
-#include "mlir/Translation.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FileUtilities.h"
+#include "mlir/Support/LogicalResult.h"
+#include "mlir/Support/TranslateClParser.h"
 #include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/ToolOutputFile.h"
 
 using namespace mlir;
 
@@ -44,102 +36,6 @@ static llvm::cl::opt<std::string>
     outputFilename("o", llvm::cl::desc("Output filename"),
                    llvm::cl::value_desc("filename"), llvm::cl::init("-"));
 
-static Module *parseMLIRInput(StringRef inputFilename, MLIRContext *context,
-                              llvm::SourceMgr &sourceMgr) {
-  // Set up the input file.
-  std::string errorMessage;
-  auto file = openInputFile(inputFilename, &errorMessage);
-  if (!file) {
-    llvm::errs() << errorMessage << "\n";
-    return nullptr;
-  }
-
-  sourceMgr.AddNewSourceBuffer(std::move(file), llvm::SMLoc());
-  return parseSourceFile(sourceMgr, context);
-}
-
-static bool printMLIROutput(Module &module, llvm::StringRef outputFilename) {
-  if (failed(module.verify()))
-    return true;
-  auto file = openOutputFile(outputFilename);
-  if (!file)
-    return true;
-  module.print(file->os());
-  file->keep();
-  return false;
-}
-
-// Common interface for source-to-source translation functions.
-using TranslateFunction =
-    std::function<bool(StringRef, StringRef, MLIRContext *)>;
-
-// Storage for the translation function wrappers that survive the parser.
-static llvm::SmallVector<TranslateFunction, 16> wrapperStorage;
-
-// Custom parser for TranslateFunction.
-// Wraps TranslateToMLIRFunctions and TranslateFromMLIRFunctions into
-// TranslateFunctions before registering them as options.
-struct TranslationParser : public llvm::cl::parser<const TranslateFunction *> {
-  TranslationParser(llvm::cl::Option &opt);
-
-  void printOptionInfo(const llvm::cl::Option &O,
-                       size_t GlobalWidth) const override;
-};
-
-TranslationParser::TranslationParser(llvm::cl::Option &opt)
-    : llvm::cl::parser<const TranslateFunction *>(opt) {
-  const auto &toMLIRRegistry = getTranslationToMLIRRegistry();
-  const auto &fromMLIRRegistry = getTranslationFromMLIRRegistry();
-
-  // Reserve the required capacity upfront so that pointers are not
-  // invalidated on reallocation.
-  wrapperStorage.reserve(toMLIRRegistry.size() + fromMLIRRegistry.size());
-  for (const auto &kv : toMLIRRegistry) {
-    TranslateToMLIRFunction function = kv.second;
-    TranslateFunction wrapper = [function](StringRef inputFilename,
-                                           StringRef outputFilename,
-                                           MLIRContext *context) {
-      std::unique_ptr<Module> module = function(inputFilename, context);
-      if (!module)
-        return true;
-      return printMLIROutput(*module, outputFilename);
-    };
-    wrapperStorage.emplace_back(std::move(wrapper));
-
-    addLiteralOption(kv.first(), &wrapperStorage.back(), kv.first());
-  }
-
-  for (const auto &kv : fromMLIRRegistry) {
-    TranslateFromMLIRFunction function = kv.second;
-    TranslateFunction wrapper = [function](StringRef inputFilename,
-                                           StringRef outputFilename,
-                                           MLIRContext *context) {
-      llvm::SourceMgr sourceMgr;
-      SourceMgrDiagnosticHandler sourceMgrHandler(sourceMgr, context);
-      auto module = std::unique_ptr<Module>(
-          parseMLIRInput(inputFilename, context, sourceMgr));
-      if (!module)
-        return true;
-      return function(module.get(), outputFilename);
-    };
-    wrapperStorage.emplace_back(std::move(wrapper));
-
-    addLiteralOption(kv.first(), &wrapperStorage.back(), kv.first());
-  }
-}
-
-void TranslationParser::printOptionInfo(const llvm::cl::Option &O,
-                                        size_t GlobalWidth) const {
-  TranslationParser *TP = const_cast<TranslationParser *>(this);
-  llvm::array_pod_sort(TP->Values.begin(), TP->Values.end(),
-                       [](const TranslationParser::OptionInfo *VT1,
-                          const TranslationParser::OptionInfo *VT2) {
-                         return VT1->Name.compare(VT2->Name);
-                       });
-  using llvm::cl::parser;
-  parser<const TranslateFunction *>::printOptionInfo(O, GlobalWidth);
-}
-
 int main(int argc, char **argv) {
   llvm::PrettyStackTraceProgram x(argc, argv);
   llvm::InitLLVM y(argc, argv);
@@ -151,5 +47,6 @@ int main(int argc, char **argv) {
   llvm::cl::ParseCommandLineOptions(argc, argv, "MLIR translation driver\n");
 
   MLIRContext context;
-  return (*translationRequested)(inputFilename, outputFilename, &context);
+  return failed(
+      (*translationRequested)(inputFilename, outputFilename, &context));
 }