From: Jacques Pienaar Date: Wed, 26 Jun 2019 18:12:40 +0000 (-0700) Subject: Split out TranslateClParser and add new parse method that reuses SourceMgr. X-Git-Tag: llvmorg-11-init~1466^2~1326 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d4cf54f2c1d40cdd66d88214a8f87660b21f2213;p=platform%2Fupstream%2Fllvm.git Split out TranslateClParser and add new parse method that reuses SourceMgr. 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 --- diff --git a/mlir/include/mlir/Parser.h b/mlir/include/mlir/Parser.h index 2da728b..85c183a 100644 --- a/mlir/include/mlir/Parser.h +++ b/mlir/include/mlir/Parser.h @@ -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 index 0000000..e936745 --- /dev/null +++ b/mlir/include/mlir/Support/TranslateClParser.h @@ -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 + +namespace mlir { + +class LogicalResult; +class MLIRContext; + +/// Common interface for source-to-source translation functions. +using TranslateFunction = std::function; + +/// Custom parser for TranslateFunction. +/// Wraps TranslateToMLIRFunctions and TranslateFromMLIRFunctions into +/// TranslateFunctions before registering them as options. +struct TranslationParser : public llvm::cl::parser { + 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_ diff --git a/mlir/lib/Parser/Parser.cpp b/mlir/lib/Parser/Parser.cpp index 1fd191f..a384145 100644 --- a/mlir/lib/Parser/Parser.cpp +++ b/mlir/lib/Parser/Parser.cpp @@ -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, diff --git a/mlir/lib/Support/CMakeLists.txt b/mlir/lib/Support/CMakeLists.txt index a82bd82..e725f70 100644 --- a/mlir/lib/Support/CMakeLists.txt +++ b/mlir/lib/Support/CMakeLists.txt @@ -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 index 0000000..eb18acb --- /dev/null +++ b/mlir/lib/Support/TranslateClParser.cpp @@ -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 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(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 = 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( + 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(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::printOptionInfo(O, GlobalWidth); +} diff --git a/mlir/tools/mlir-translate/CMakeLists.txt b/mlir/tools/mlir-translate/CMakeLists.txt index be29c6c..50df9de 100644 --- a/mlir/tools/mlir-translate/CMakeLists.txt +++ b/mlir/tools/mlir-translate/CMakeLists.txt @@ -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) diff --git a/mlir/tools/mlir-translate/mlir-translate.cpp b/mlir/tools/mlir-translate/mlir-translate.cpp index 0577623..0ff5e6e 100644 --- a/mlir/tools/mlir-translate/mlir-translate.cpp +++ b/mlir/tools/mlir-translate/mlir-translate.cpp @@ -20,19 +20,11 @@ // //===----------------------------------------------------------------------===// -#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 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; - -// Storage for the translation function wrappers that survive the parser. -static llvm::SmallVector wrapperStorage; - -// Custom parser for TranslateFunction. -// Wraps TranslateToMLIRFunctions and TranslateFromMLIRFunctions into -// TranslateFunctions before registering them as options. -struct TranslationParser : public llvm::cl::parser { - 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(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 = 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( - 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(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::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)); }