1 //===- Translation.cpp - Translation registry -----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // Definitions of the translation registry.
11 //===----------------------------------------------------------------------===//
13 #include "mlir/Tools/mlir-translate/Translation.h"
14 #include "mlir/IR/AsmState.h"
15 #include "mlir/IR/BuiltinOps.h"
16 #include "mlir/IR/Dialect.h"
17 #include "mlir/IR/Verifier.h"
18 #include "mlir/Parser/Parser.h"
19 #include "mlir/Tools/ParseUtilities.h"
20 #include "llvm/Support/ManagedStatic.h"
21 #include "llvm/Support/SourceMgr.h"
26 //===----------------------------------------------------------------------===//
27 // Translation CommandLine Options
28 //===----------------------------------------------------------------------===//
30 struct TranslationOptions
{
31 llvm::cl::opt
<bool> noImplicitModule
{
33 llvm::cl::desc("Disable the parsing of an implicit top-level module op"),
34 llvm::cl::init(false)};
37 static llvm::ManagedStatic
<TranslationOptions
> clOptions
;
39 void mlir::registerTranslationCLOptions() { *clOptions
; }
41 //===----------------------------------------------------------------------===//
42 // Translation Registry
43 //===----------------------------------------------------------------------===//
45 /// Get the mutable static map between registered file-to-file MLIR
47 static llvm::StringMap
<Translation
> &getTranslationRegistry() {
48 static llvm::StringMap
<Translation
> translationBundle
;
49 return translationBundle
;
52 /// Register the given translation.
53 static void registerTranslation(StringRef name
, StringRef description
,
54 std::optional
<llvm::Align
> inputAlignment
,
55 const TranslateFunction
&function
) {
56 auto ®istry
= getTranslationRegistry();
57 if (registry
.count(name
))
58 llvm::report_fatal_error(
59 "Attempting to overwrite an existing <file-to-file> function");
61 "Attempting to register an empty translate <file-to-file> function");
62 registry
[name
] = Translation(function
, description
, inputAlignment
);
65 TranslateRegistration::TranslateRegistration(
66 StringRef name
, StringRef description
, const TranslateFunction
&function
) {
67 registerTranslation(name
, description
, /*inputAlignment=*/std::nullopt
,
71 //===----------------------------------------------------------------------===//
72 // Translation to MLIR
73 //===----------------------------------------------------------------------===//
75 // Puts `function` into the to-MLIR translation registry unless there is already
76 // a function registered for the same name.
77 static void registerTranslateToMLIRFunction(
78 StringRef name
, StringRef description
,
79 const DialectRegistrationFunction
&dialectRegistration
,
80 std::optional
<llvm::Align
> inputAlignment
,
81 const TranslateSourceMgrToMLIRFunction
&function
) {
82 auto wrappedFn
= [function
, dialectRegistration
](
83 const std::shared_ptr
<llvm::SourceMgr
> &sourceMgr
,
84 raw_ostream
&output
, MLIRContext
*context
) {
85 DialectRegistry registry
;
86 dialectRegistration(registry
);
87 context
->appendDialectRegistry(registry
);
88 OwningOpRef
<Operation
*> op
= function(sourceMgr
, context
);
89 if (!op
|| failed(verify(*op
)))
91 op
.get()->print(output
);
94 registerTranslation(name
, description
, inputAlignment
, wrappedFn
);
97 TranslateToMLIRRegistration::TranslateToMLIRRegistration(
98 StringRef name
, StringRef description
,
99 const TranslateSourceMgrToMLIRFunction
&function
,
100 const DialectRegistrationFunction
&dialectRegistration
,
101 std::optional
<llvm::Align
> inputAlignment
) {
102 registerTranslateToMLIRFunction(name
, description
, dialectRegistration
,
103 inputAlignment
, function
);
105 TranslateToMLIRRegistration::TranslateToMLIRRegistration(
106 StringRef name
, StringRef description
,
107 const TranslateRawSourceMgrToMLIRFunction
&function
,
108 const DialectRegistrationFunction
&dialectRegistration
,
109 std::optional
<llvm::Align
> inputAlignment
) {
110 registerTranslateToMLIRFunction(
111 name
, description
, dialectRegistration
, inputAlignment
,
112 [function
](const std::shared_ptr
<llvm::SourceMgr
> &sourceMgr
,
113 MLIRContext
*ctx
) { return function(*sourceMgr
, ctx
); });
115 /// Wraps `function` with a lambda that extracts a StringRef from a source
116 /// manager and registers the wrapper lambda as a to-MLIR conversion.
117 TranslateToMLIRRegistration::TranslateToMLIRRegistration(
118 StringRef name
, StringRef description
,
119 const TranslateStringRefToMLIRFunction
&function
,
120 const DialectRegistrationFunction
&dialectRegistration
,
121 std::optional
<llvm::Align
> inputAlignment
) {
122 registerTranslateToMLIRFunction(
123 name
, description
, dialectRegistration
, inputAlignment
,
124 [function
](const std::shared_ptr
<llvm::SourceMgr
> &sourceMgr
,
126 const llvm::MemoryBuffer
*buffer
=
127 sourceMgr
->getMemoryBuffer(sourceMgr
->getMainFileID());
128 return function(buffer
->getBuffer(), ctx
);
132 //===----------------------------------------------------------------------===//
133 // Translation from MLIR
134 //===----------------------------------------------------------------------===//
136 TranslateFromMLIRRegistration::TranslateFromMLIRRegistration(
137 StringRef name
, StringRef description
,
138 const TranslateFromMLIRFunction
&function
,
139 const DialectRegistrationFunction
&dialectRegistration
) {
141 name
, description
, /*inputAlignment=*/std::nullopt
,
143 dialectRegistration
](const std::shared_ptr
<llvm::SourceMgr
> &sourceMgr
,
144 raw_ostream
&output
, MLIRContext
*context
) {
145 DialectRegistry registry
;
146 dialectRegistration(registry
);
147 context
->appendDialectRegistry(registry
);
148 bool implicitModule
=
149 (!clOptions
.isConstructed() || !clOptions
->noImplicitModule
);
150 OwningOpRef
<Operation
*> op
=
151 parseSourceFileForTool(sourceMgr
, context
, implicitModule
);
152 if (!op
|| failed(verify(*op
)))
154 return function(op
.get(), output
);
158 //===----------------------------------------------------------------------===//
159 // Translation Parser
160 //===----------------------------------------------------------------------===//
162 TranslationParser::TranslationParser(llvm::cl::Option
&opt
)
163 : llvm::cl::parser
<const Translation
*>(opt
) {
164 for (const auto &kv
: getTranslationRegistry())
165 addLiteralOption(kv
.first(), &kv
.second
, kv
.second
.getDescription());
168 void TranslationParser::printOptionInfo(const llvm::cl::Option
&o
,
169 size_t globalWidth
) const {
170 TranslationParser
*tp
= const_cast<TranslationParser
*>(this);
171 llvm::array_pod_sort(tp
->Values
.begin(), tp
->Values
.end(),
172 [](const TranslationParser::OptionInfo
*lhs
,
173 const TranslationParser::OptionInfo
*rhs
) {
174 return lhs
->Name
.compare(rhs
->Name
);
176 llvm::cl::parser
<const Translation
*>::printOptionInfo(o
, globalWidth
);