1 //===- Translation.h - Translation registry ---------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Registry for user-provided translations. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef MLIR_TOOLS_MLIRTRANSLATE_TRANSLATION_H 14 #define MLIR_TOOLS_MLIRTRANSLATE_TRANSLATION_H 15 16 #include "mlir/IR/Operation.h" 17 #include "llvm/Support/CommandLine.h" 18 #include <optional> 19 20 namespace mlir { 21 template <typename OpTy> 22 class OwningOpRef; 23 24 /// Interface of the function that translates the sources managed by `sourceMgr` 25 /// to MLIR. The source manager has at least one buffer. The implementation 26 /// should create a new MLIR Operation in the given context and return a 27 /// pointer to it, or a nullptr in case of any error. 28 using TranslateSourceMgrToMLIRFunction = std::function<OwningOpRef<Operation *>( 29 const std::shared_ptr<llvm::SourceMgr> &sourceMgr, MLIRContext *)>; 30 using TranslateRawSourceMgrToMLIRFunction = 31 std::function<OwningOpRef<Operation *>(llvm::SourceMgr &sourceMgr, 32 MLIRContext *)>; 33 34 /// Interface of the function that translates the given string to MLIR. The 35 /// implementation should create a new MLIR Operation in the given context. If 36 /// source-related error reporting is required from within the function, use 37 /// TranslateSourceMgrToMLIRFunction instead. 38 using TranslateStringRefToMLIRFunction = 39 std::function<OwningOpRef<Operation *>(llvm::StringRef, MLIRContext *)>; 40 41 /// Interface of the function that translates MLIR to a different format and 42 /// outputs the result to a stream. It is allowed to modify the operation. 43 using TranslateFromMLIRFunction = 44 std::function<LogicalResult(Operation *, llvm::raw_ostream &output)>; 45 46 /// Interface of the function that performs file-to-file translation involving 47 /// MLIR. The input file is held in the given MemoryBuffer; the output file 48 /// should be written to the given raw_ostream. The implementation should create 49 /// all MLIR constructs needed during the process inside the given context. This 50 /// can be used for round-tripping external formats through the MLIR system. 51 using TranslateFunction = std::function<LogicalResult( 52 const std::shared_ptr<llvm::SourceMgr> &sourceMgr, 53 llvm::raw_ostream &output, MLIRContext *)>; 54 55 /// Interface of the function that adds all dialects and dialect extensions used 56 /// for the translation to the given DialectRegistry. 57 using DialectRegistrationFunction = std::function<void(DialectRegistry &)>; 58 59 /// This class contains all of the components necessary for performing a 60 /// translation. 61 class Translation { 62 public: 63 Translation() = default; Translation(TranslateFunction function,StringRef description,std::optional<llvm::Align> inputAlignment)64 Translation(TranslateFunction function, StringRef description, 65 std::optional<llvm::Align> inputAlignment) 66 : function(std::move(function)), description(description), 67 inputAlignment(inputAlignment) {} 68 69 /// Return the description of this translation. getDescription()70 StringRef getDescription() const { return description; } 71 72 /// Return the optional alignment desired for the input of the translation. getInputAlignment()73 std::optional<llvm::Align> getInputAlignment() const { 74 return inputAlignment; 75 } 76 77 /// Invoke the translation function with the given input and output streams. operator()78 LogicalResult operator()(const std::shared_ptr<llvm::SourceMgr> &sourceMgr, 79 llvm::raw_ostream &output, 80 MLIRContext *context) const { 81 return function(sourceMgr, output, context); 82 } 83 84 private: 85 /// The underlying translation function. 86 TranslateFunction function; 87 88 /// The description of the translation. 89 StringRef description; 90 91 /// An optional alignment desired for the input of the translation. 92 std::optional<llvm::Align> inputAlignment; 93 }; 94 95 /// Use Translate[ToMLIR|FromMLIR]Registration as an initializer that 96 /// registers a function and associates it with name. This requires that a 97 /// translation has not been registered to a given name. `inputAlign` is an 98 /// optional expected alignment for the input data. 99 /// 100 /// Usage: 101 /// 102 /// // At file scope. 103 /// namespace mlir { 104 /// void registerTRexToMLIRRegistration() { 105 /// TranslateToMLIRRegistration Unused(&MySubCommand, [] { ... }); 106 /// } 107 /// } // namespace mlir 108 /// 109 /// \{ 110 struct TranslateToMLIRRegistration { 111 TranslateToMLIRRegistration( 112 llvm::StringRef name, llvm::StringRef description, 113 const TranslateSourceMgrToMLIRFunction &function, 114 const DialectRegistrationFunction &dialectRegistration = 115 [](DialectRegistry &) {}, 116 std::optional<llvm::Align> inputAlignment = std::nullopt); 117 TranslateToMLIRRegistration( 118 llvm::StringRef name, llvm::StringRef description, 119 const TranslateRawSourceMgrToMLIRFunction &function, 120 const DialectRegistrationFunction &dialectRegistration = 121 [](DialectRegistry &) {}, 122 std::optional<llvm::Align> inputAlignment = std::nullopt); 123 TranslateToMLIRRegistration( 124 llvm::StringRef name, llvm::StringRef description, 125 const TranslateStringRefToMLIRFunction &function, 126 const DialectRegistrationFunction &dialectRegistration = 127 [](DialectRegistry &) {}, 128 std::optional<llvm::Align> inputAlignment = std::nullopt); 129 }; 130 131 struct TranslateFromMLIRRegistration { 132 TranslateFromMLIRRegistration( 133 llvm::StringRef name, llvm::StringRef description, 134 const TranslateFromMLIRFunction &function, 135 const DialectRegistrationFunction &dialectRegistration = 136 [](DialectRegistry &) {}); 137 138 template <typename FuncTy, typename OpTy = detail::first_argument<FuncTy>, 139 typename = std::enable_if_t<!std::is_same_v<OpTy, Operation *>>> 140 TranslateFromMLIRRegistration( 141 llvm::StringRef name, llvm::StringRef description, FuncTy function, 142 const DialectRegistrationFunction &dialectRegistration = 143 [](DialectRegistry &) {}) 144 : TranslateFromMLIRRegistration( 145 name, description, 146 [function](Operation *op, raw_ostream &os) -> LogicalResult { 147 if (auto casted = dyn_cast<OpTy>(op)) 148 return function(casted, os); 149 return emitError(op->getLoc()) 150 << "expected a '" << OpTy::getOperationName() 151 << "' op, got '" << op->getName().getStringRef() << "'"; 152 }, 153 dialectRegistration) {} 154 }; 155 struct TranslateRegistration { 156 TranslateRegistration(llvm::StringRef name, llvm::StringRef description, 157 const TranslateFunction &function); 158 }; 159 /// \} 160 161 /// A command line parser for translation functions. 162 struct TranslationParser : public llvm::cl::parser<const Translation *> { 163 TranslationParser(llvm::cl::Option &opt); 164 165 void printOptionInfo(const llvm::cl::Option &o, 166 size_t globalWidth) const override; 167 }; 168 169 /// Register command-line options used by the translation registry. 170 void registerTranslationCLOptions(); 171 172 } // namespace mlir 173 174 #endif // MLIR_TOOLS_MLIRTRANSLATE_TRANSLATION_H 175