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 ®istry = 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