xref: /llvm-project/mlir/lib/Tools/mlir-translate/Translation.cpp (revision 0aea1f2f21b8b3984072dc2ea33857d077d91af2)
1ee1d447eSRiver Riddle //===- Translation.cpp - Translation registry -----------------------------===//
2ee1d447eSRiver Riddle //
3ee1d447eSRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ee1d447eSRiver Riddle // See https://llvm.org/LICENSE.txt for license information.
5ee1d447eSRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ee1d447eSRiver Riddle //
7ee1d447eSRiver Riddle //===----------------------------------------------------------------------===//
8ee1d447eSRiver Riddle //
9ee1d447eSRiver Riddle // Definitions of the translation registry.
10ee1d447eSRiver Riddle //
11ee1d447eSRiver Riddle //===----------------------------------------------------------------------===//
12ee1d447eSRiver Riddle 
13ee1d447eSRiver Riddle #include "mlir/Tools/mlir-translate/Translation.h"
14ee1d447eSRiver Riddle #include "mlir/IR/AsmState.h"
15ee1d447eSRiver Riddle #include "mlir/IR/BuiltinOps.h"
16ee1d447eSRiver Riddle #include "mlir/IR/Dialect.h"
17ee1d447eSRiver Riddle #include "mlir/IR/Verifier.h"
18ee1d447eSRiver Riddle #include "mlir/Parser/Parser.h"
1917dbd80fSEmilio Cota #include "mlir/Tools/ParseUtilities.h"
20*0aea1f2fSNikita Popov #include "llvm/Support/ManagedStatic.h"
21ee1d447eSRiver Riddle #include "llvm/Support/SourceMgr.h"
22a1fe1f5fSKazu Hirata #include <optional>
23ee1d447eSRiver Riddle 
24ee1d447eSRiver Riddle using namespace mlir;
25ee1d447eSRiver Riddle 
26ee1d447eSRiver Riddle //===----------------------------------------------------------------------===//
27d30727fbSrkayaith // Translation CommandLine Options
28d30727fbSrkayaith //===----------------------------------------------------------------------===//
29d30727fbSrkayaith 
30d30727fbSrkayaith struct TranslationOptions {
31d30727fbSrkayaith   llvm::cl::opt<bool> noImplicitModule{
32d30727fbSrkayaith       "no-implicit-module",
33d30727fbSrkayaith       llvm::cl::desc("Disable the parsing of an implicit top-level module op"),
34d30727fbSrkayaith       llvm::cl::init(false)};
35d30727fbSrkayaith };
36d30727fbSrkayaith 
37d30727fbSrkayaith static llvm::ManagedStatic<TranslationOptions> clOptions;
38d30727fbSrkayaith 
registerTranslationCLOptions()39d30727fbSrkayaith void mlir::registerTranslationCLOptions() { *clOptions; }
40d30727fbSrkayaith 
41d30727fbSrkayaith //===----------------------------------------------------------------------===//
42ee1d447eSRiver Riddle // Translation Registry
43ee1d447eSRiver Riddle //===----------------------------------------------------------------------===//
44ee1d447eSRiver Riddle 
454155be33SRiver Riddle /// Get the mutable static map between registered file-to-file MLIR
464155be33SRiver Riddle /// translations.
getTranslationRegistry()474155be33SRiver Riddle static llvm::StringMap<Translation> &getTranslationRegistry() {
484155be33SRiver Riddle   static llvm::StringMap<Translation> translationBundle;
49c4cc755cSchangkaiyan   return translationBundle;
50ee1d447eSRiver Riddle }
51ee1d447eSRiver Riddle 
52ee1d447eSRiver Riddle /// Register the given translation.
registerTranslation(StringRef name,StringRef description,std::optional<llvm::Align> inputAlignment,const TranslateFunction & function)53c4cc755cSchangkaiyan static void registerTranslation(StringRef name, StringRef description,
540a81ace0SKazu Hirata                                 std::optional<llvm::Align> inputAlignment,
55ee1d447eSRiver Riddle                                 const TranslateFunction &function) {
564155be33SRiver Riddle   auto &registry = getTranslationRegistry();
574155be33SRiver Riddle   if (registry.count(name))
58ee1d447eSRiver Riddle     llvm::report_fatal_error(
59ee1d447eSRiver Riddle         "Attempting to overwrite an existing <file-to-file> function");
60ee1d447eSRiver Riddle   assert(function &&
61ee1d447eSRiver Riddle          "Attempting to register an empty translate <file-to-file> function");
624155be33SRiver Riddle   registry[name] = Translation(function, description, inputAlignment);
63ee1d447eSRiver Riddle }
64ee1d447eSRiver Riddle 
TranslateRegistration(StringRef name,StringRef description,const TranslateFunction & function)65ee1d447eSRiver Riddle TranslateRegistration::TranslateRegistration(
66c4cc755cSchangkaiyan     StringRef name, StringRef description, const TranslateFunction &function) {
671a36588eSKazu Hirata   registerTranslation(name, description, /*inputAlignment=*/std::nullopt,
684155be33SRiver Riddle                       function);
69ee1d447eSRiver Riddle }
70ee1d447eSRiver Riddle 
71ee1d447eSRiver Riddle //===----------------------------------------------------------------------===//
72ee1d447eSRiver Riddle // Translation to MLIR
73ee1d447eSRiver Riddle //===----------------------------------------------------------------------===//
74ee1d447eSRiver Riddle 
75ee1d447eSRiver Riddle // Puts `function` into the to-MLIR translation registry unless there is already
76ee1d447eSRiver Riddle // a function registered for the same name.
registerTranslateToMLIRFunction(StringRef name,StringRef description,const DialectRegistrationFunction & dialectRegistration,std::optional<llvm::Align> inputAlignment,const TranslateSourceMgrToMLIRFunction & function)77ee1d447eSRiver Riddle static void registerTranslateToMLIRFunction(
78cf487cceSTobias Gysi     StringRef name, StringRef description,
79cf487cceSTobias Gysi     const DialectRegistrationFunction &dialectRegistration,
800a81ace0SKazu Hirata     std::optional<llvm::Align> inputAlignment,
81c4cc755cSchangkaiyan     const TranslateSourceMgrToMLIRFunction &function) {
82cf487cceSTobias Gysi   auto wrappedFn = [function, dialectRegistration](
83cf487cceSTobias Gysi                        const std::shared_ptr<llvm::SourceMgr> &sourceMgr,
8418546ff8SRiver Riddle                        raw_ostream &output, MLIRContext *context) {
85cf487cceSTobias Gysi     DialectRegistry registry;
86cf487cceSTobias Gysi     dialectRegistration(registry);
87cf487cceSTobias Gysi     context->appendDialectRegistry(registry);
88ed90f802Srkayaith     OwningOpRef<Operation *> op = function(sourceMgr, context);
89ed90f802Srkayaith     if (!op || failed(verify(*op)))
90ee1d447eSRiver Riddle       return failure();
91ed90f802Srkayaith     op.get()->print(output);
92ee1d447eSRiver Riddle     return success();
93ee1d447eSRiver Riddle   };
944155be33SRiver Riddle   registerTranslation(name, description, inputAlignment, wrappedFn);
95ee1d447eSRiver Riddle }
96ee1d447eSRiver Riddle 
TranslateToMLIRRegistration(StringRef name,StringRef description,const TranslateSourceMgrToMLIRFunction & function,const DialectRegistrationFunction & dialectRegistration,std::optional<llvm::Align> inputAlignment)97ee1d447eSRiver Riddle TranslateToMLIRRegistration::TranslateToMLIRRegistration(
98c4cc755cSchangkaiyan     StringRef name, StringRef description,
994155be33SRiver Riddle     const TranslateSourceMgrToMLIRFunction &function,
100cf487cceSTobias Gysi     const DialectRegistrationFunction &dialectRegistration,
1010a81ace0SKazu Hirata     std::optional<llvm::Align> inputAlignment) {
102cf487cceSTobias Gysi   registerTranslateToMLIRFunction(name, description, dialectRegistration,
103cf487cceSTobias Gysi                                   inputAlignment, function);
104ee1d447eSRiver Riddle }
TranslateToMLIRRegistration(StringRef name,StringRef description,const TranslateRawSourceMgrToMLIRFunction & function,const DialectRegistrationFunction & dialectRegistration,std::optional<llvm::Align> inputAlignment)10518546ff8SRiver Riddle TranslateToMLIRRegistration::TranslateToMLIRRegistration(
10618546ff8SRiver Riddle     StringRef name, StringRef description,
10718546ff8SRiver Riddle     const TranslateRawSourceMgrToMLIRFunction &function,
108cf487cceSTobias Gysi     const DialectRegistrationFunction &dialectRegistration,
1090a81ace0SKazu Hirata     std::optional<llvm::Align> inputAlignment) {
11018546ff8SRiver Riddle   registerTranslateToMLIRFunction(
111cf487cceSTobias Gysi       name, description, dialectRegistration, inputAlignment,
11218546ff8SRiver Riddle       [function](const std::shared_ptr<llvm::SourceMgr> &sourceMgr,
11318546ff8SRiver Riddle                  MLIRContext *ctx) { return function(*sourceMgr, ctx); });
11418546ff8SRiver Riddle }
115ee1d447eSRiver Riddle /// Wraps `function` with a lambda that extracts a StringRef from a source
116ee1d447eSRiver Riddle /// manager and registers the wrapper lambda as a to-MLIR conversion.
TranslateToMLIRRegistration(StringRef name,StringRef description,const TranslateStringRefToMLIRFunction & function,const DialectRegistrationFunction & dialectRegistration,std::optional<llvm::Align> inputAlignment)117ee1d447eSRiver Riddle TranslateToMLIRRegistration::TranslateToMLIRRegistration(
118c4cc755cSchangkaiyan     StringRef name, StringRef description,
1194155be33SRiver Riddle     const TranslateStringRefToMLIRFunction &function,
120cf487cceSTobias Gysi     const DialectRegistrationFunction &dialectRegistration,
1210a81ace0SKazu Hirata     std::optional<llvm::Align> inputAlignment) {
122ee1d447eSRiver Riddle   registerTranslateToMLIRFunction(
123cf487cceSTobias Gysi       name, description, dialectRegistration, inputAlignment,
12418546ff8SRiver Riddle       [function](const std::shared_ptr<llvm::SourceMgr> &sourceMgr,
12518546ff8SRiver Riddle                  MLIRContext *ctx) {
126ee1d447eSRiver Riddle         const llvm::MemoryBuffer *buffer =
12718546ff8SRiver Riddle             sourceMgr->getMemoryBuffer(sourceMgr->getMainFileID());
128ee1d447eSRiver Riddle         return function(buffer->getBuffer(), ctx);
129ee1d447eSRiver Riddle       });
130ee1d447eSRiver Riddle }
131ee1d447eSRiver Riddle 
132ee1d447eSRiver Riddle //===----------------------------------------------------------------------===//
133ee1d447eSRiver Riddle // Translation from MLIR
134ee1d447eSRiver Riddle //===----------------------------------------------------------------------===//
135ee1d447eSRiver Riddle 
TranslateFromMLIRRegistration(StringRef name,StringRef description,const TranslateFromMLIRFunction & function,const DialectRegistrationFunction & dialectRegistration)136ee1d447eSRiver Riddle TranslateFromMLIRRegistration::TranslateFromMLIRRegistration(
137c4cc755cSchangkaiyan     StringRef name, StringRef description,
138c4cc755cSchangkaiyan     const TranslateFromMLIRFunction &function,
139cf487cceSTobias Gysi     const DialectRegistrationFunction &dialectRegistration) {
140d30727fbSrkayaith   registerTranslation(
1411a36588eSKazu Hirata       name, description, /*inputAlignment=*/std::nullopt,
14218546ff8SRiver Riddle       [function,
14318546ff8SRiver Riddle        dialectRegistration](const std::shared_ptr<llvm::SourceMgr> &sourceMgr,
14418546ff8SRiver Riddle                             raw_ostream &output, MLIRContext *context) {
145ee1d447eSRiver Riddle         DialectRegistry registry;
146ee1d447eSRiver Riddle         dialectRegistration(registry);
147ee1d447eSRiver Riddle         context->appendDialectRegistry(registry);
148d30727fbSrkayaith         bool implicitModule =
149d30727fbSrkayaith             (!clOptions.isConstructed() || !clOptions->noImplicitModule);
150d30727fbSrkayaith         OwningOpRef<Operation *> op =
151d30727fbSrkayaith             parseSourceFileForTool(sourceMgr, context, implicitModule);
152ed90f802Srkayaith         if (!op || failed(verify(*op)))
153ee1d447eSRiver Riddle           return failure();
154ed90f802Srkayaith         return function(op.get(), output);
155ee1d447eSRiver Riddle       });
156ee1d447eSRiver Riddle }
157ee1d447eSRiver Riddle 
158ee1d447eSRiver Riddle //===----------------------------------------------------------------------===//
159ee1d447eSRiver Riddle // Translation Parser
160ee1d447eSRiver Riddle //===----------------------------------------------------------------------===//
161ee1d447eSRiver Riddle 
TranslationParser(llvm::cl::Option & opt)162ee1d447eSRiver Riddle TranslationParser::TranslationParser(llvm::cl::Option &opt)
1634155be33SRiver Riddle     : llvm::cl::parser<const Translation *>(opt) {
1644155be33SRiver Riddle   for (const auto &kv : getTranslationRegistry())
1654155be33SRiver Riddle     addLiteralOption(kv.first(), &kv.second, kv.second.getDescription());
166ee1d447eSRiver Riddle }
167ee1d447eSRiver Riddle 
printOptionInfo(const llvm::cl::Option & o,size_t globalWidth) const168ee1d447eSRiver Riddle void TranslationParser::printOptionInfo(const llvm::cl::Option &o,
169ee1d447eSRiver Riddle                                         size_t globalWidth) const {
170ee1d447eSRiver Riddle   TranslationParser *tp = const_cast<TranslationParser *>(this);
171ee1d447eSRiver Riddle   llvm::array_pod_sort(tp->Values.begin(), tp->Values.end(),
172ee1d447eSRiver Riddle                        [](const TranslationParser::OptionInfo *lhs,
173ee1d447eSRiver Riddle                           const TranslationParser::OptionInfo *rhs) {
174ee1d447eSRiver Riddle                          return lhs->Name.compare(rhs->Name);
175ee1d447eSRiver Riddle                        });
1764155be33SRiver Riddle   llvm::cl::parser<const Translation *>::printOptionInfo(o, globalWidth);
177ee1d447eSRiver Riddle }
178