1 //===- TestToLLVMIRTranslation.cpp - Translate Test dialect to LLVM IR ----===//
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 // This file implements a translation between the MLIR Test dialect and LLVM IR.
11 //===----------------------------------------------------------------------===//
13 #include "TestDialect.h"
15 #include "mlir/IR/Builders.h"
16 #include "mlir/IR/BuiltinAttributes.h"
17 #include "mlir/IR/BuiltinOps.h"
18 #include "mlir/Target/LLVMIR/Dialect/Builtin/BuiltinToLLVMIRTranslation.h"
19 #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
20 #include "mlir/Target/LLVMIR/LLVMTranslationInterface.h"
21 #include "mlir/Target/LLVMIR/ModuleTranslation.h"
22 #include "mlir/Tools/mlir-translate/Translation.h"
23 #include "llvm/ADT/StringSwitch.h"
24 #include "llvm/ADT/TypeSwitch.h"
25 #include "llvm/IR/DebugProgramInstruction.h"
27 extern llvm::cl::opt
<bool> WriteNewDbgInfoFormat
;
33 class TestDialectLLVMIRTranslationInterface
34 : public LLVMTranslationDialectInterface
{
36 using LLVMTranslationDialectInterface::LLVMTranslationDialectInterface
;
39 amendOperation(Operation
*op
, ArrayRef
<llvm::Instruction
*> instructions
,
40 NamedAttribute attribute
,
41 LLVM::ModuleTranslation
&moduleTranslation
) const final
;
44 convertOperation(Operation
*op
, llvm::IRBuilderBase
&builder
,
45 LLVM::ModuleTranslation
&moduleTranslation
) const final
;
50 LogicalResult
TestDialectLLVMIRTranslationInterface::amendOperation(
51 Operation
*op
, ArrayRef
<llvm::Instruction
*> instructions
,
52 NamedAttribute attribute
,
53 LLVM::ModuleTranslation
&moduleTranslation
) const {
54 return llvm::StringSwitch
<llvm::function_ref
<LogicalResult(Attribute
)>>(
56 // The `test.discardable_mod_attr` attribute, if present and set to
57 // `true`, results in the addition of a `test.symbol` in the module it is
58 // attached to with name "sym_from_attr".
59 .Case("test.discardable_mod_attr",
61 if (!isa
<ModuleOp
>(op
)) {
62 op
->emitOpError("attribute 'test.discardable_mod_attr' only "
63 "supported in modules");
67 bool createSymbol
= false;
68 if (auto boolAttr
= dyn_cast
<BoolAttr
>(attr
))
69 createSymbol
= boolAttr
.getValue();
72 OpBuilder
builder(op
->getRegion(0));
73 builder
.create
<test::SymbolOp
>(
75 StringAttr::get(op
->getContext(), "sym_from_attr"),
76 /*sym_visibility=*/nullptr);
81 .Case("test.add_annotation",
83 for (llvm::Instruction
*instruction
: instructions
) {
84 if (auto strAttr
= dyn_cast
<StringAttr
>(attr
)) {
85 instruction
->addAnnotationMetadata("annotation_from_test: " +
86 strAttr
.getValue().str());
88 instruction
->addAnnotationMetadata("annotation_from_test");
93 .Default([](Attribute
) {
94 // Skip other discardable dialect attributes.
96 })(attribute
.getValue());
99 LogicalResult
TestDialectLLVMIRTranslationInterface::convertOperation(
100 Operation
*op
, llvm::IRBuilderBase
&builder
,
101 LLVM::ModuleTranslation
&moduleTranslation
) const {
102 return llvm::TypeSwitch
<Operation
*, LogicalResult
>(op
)
103 // `test.symbol`s are translated into global integers in LLVM IR, with a
104 // name equal to the symbol they are translated from.
105 .Case([&](test::SymbolOp symOp
) {
106 llvm::Module
*mod
= moduleTranslation
.getLLVMModule();
107 llvm::IntegerType
*i32Type
=
108 llvm::IntegerType::get(moduleTranslation
.getLLVMContext(), 32);
109 mod
->getOrInsertGlobal(symOp
.getSymName(), i32Type
);
112 .Default([&](Operation
*) {
113 return op
->emitOpError("unsupported translation of test operation");
119 void registerTestToLLVMIR() {
120 TranslateFromMLIRRegistration
registration(
121 "test-to-llvmir", "test dialect to LLVM IR",
122 [](Operation
*op
, raw_ostream
&output
) {
123 llvm::LLVMContext llvmContext
;
124 auto llvmModule
= translateModuleToLLVMIR(op
, llvmContext
);
128 // When printing LLVM IR, we should convert the module to the debug info
129 // format that LLVM expects us to print.
130 // See https://llvm.org/docs/RemoveDIsDebugInfo.html
131 llvm::ScopedDbgInfoFormatSetter
formatSetter(*llvmModule
,
132 WriteNewDbgInfoFormat
);
133 if (WriteNewDbgInfoFormat
)
134 llvmModule
->removeDebugIntrinsicDeclarations();
135 llvmModule
->print(output
, nullptr);
138 [](DialectRegistry
®istry
) {
139 registry
.insert
<test::TestDialect
>();
140 registerBuiltinDialectTranslation(registry
);
141 registerLLVMDialectTranslation(registry
);
142 registry
.addExtension(
143 +[](MLIRContext
*ctx
, test::TestDialect
*dialect
) {
144 dialect
->addInterfaces
<TestDialectLLVMIRTranslationInterface
>();