1//===- TestToLLVMIRTranslation.cpp - Translate Test dialect to LLVM IR ----===//
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// This file implements a translation between the MLIR Test dialect and LLVM IR.
10//
11//===----------------------------------------------------------------------===//
12
13#include "TestDialect.h"
14#include "TestOps.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"
26
27using namespace mlir;
28
29namespace {
30
31class TestDialectLLVMIRTranslationInterface
32 : public LLVMTranslationDialectInterface {
33public:
34 using LLVMTranslationDialectInterface::LLVMTranslationDialectInterface;
35
36 LogicalResult
37 amendOperation(Operation *op, ArrayRef<llvm::Instruction *> instructions,
38 NamedAttribute attribute,
39 LLVM::ModuleTranslation &moduleTranslation) const final;
40
41 LogicalResult
42 convertOperation(Operation *op, llvm::IRBuilderBase &builder,
43 LLVM::ModuleTranslation &moduleTranslation) const final;
44};
45
46} // namespace
47
48LogicalResult TestDialectLLVMIRTranslationInterface::amendOperation(
49 Operation *op, ArrayRef<llvm::Instruction *> instructions,
50 NamedAttribute attribute,
51 LLVM::ModuleTranslation &moduleTranslation) const {
52 return llvm::StringSwitch<llvm::function_ref<LogicalResult(Attribute)>>(
53 attribute.getName())
54 // The `test.discardable_mod_attr` attribute, if present and set to
55 // `true`, results in the addition of a `test.symbol` in the module it is
56 // attached to with name "sym_from_attr".
57 .Case(S: "test.discardable_mod_attr",
58 Value: [&](Attribute attr) {
59 if (!isa<ModuleOp>(Val: op)) {
60 op->emitOpError(message: "attribute 'test.discardable_mod_attr' only "
61 "supported in modules");
62 return failure();
63 }
64
65 bool createSymbol = false;
66 if (auto boolAttr = dyn_cast<BoolAttr>(Val&: attr))
67 createSymbol = boolAttr.getValue();
68
69 if (createSymbol) {
70 OpBuilder builder(op->getRegion(index: 0));
71 builder.create<test::SymbolOp>(
72 op->getLoc(),
73 StringAttr::get(op->getContext(), "sym_from_attr"),
74 /*sym_visibility=*/nullptr);
75 }
76
77 return success();
78 })
79 .Case(S: "test.add_annotation",
80 Value: [&](Attribute attr) {
81 for (llvm::Instruction *instruction : instructions) {
82 if (auto strAttr = dyn_cast<StringAttr>(attr)) {
83 instruction->addAnnotationMetadata("annotation_from_test: " +
84 strAttr.getValue().str());
85 } else {
86 instruction->addAnnotationMetadata(Annotation: "annotation_from_test");
87 }
88 }
89 return success();
90 })
91 .Default(Value: [](Attribute) {
92 // Skip other discardable dialect attributes.
93 return success();
94 })(attribute.getValue());
95}
96
97LogicalResult TestDialectLLVMIRTranslationInterface::convertOperation(
98 Operation *op, llvm::IRBuilderBase &builder,
99 LLVM::ModuleTranslation &moduleTranslation) const {
100 return llvm::TypeSwitch<Operation *, LogicalResult>(op)
101 // `test.symbol`s are translated into global integers in LLVM IR, with a
102 // name equal to the symbol they are translated from.
103 .Case(caseFn: [&](test::SymbolOp symOp) {
104 llvm::Module *mod = moduleTranslation.getLLVMModule();
105 llvm::IntegerType *i32Type =
106 llvm::IntegerType::get(C&: moduleTranslation.getLLVMContext(), NumBits: 32);
107 mod->getOrInsertGlobal(symOp.getSymName(), i32Type);
108 return success();
109 })
110 .Default(defaultFn: [&](Operation *) {
111 return op->emitOpError(message: "unsupported translation of test operation");
112 });
113}
114
115namespace mlir {
116
117void registerTestToLLVMIR() {
118 TranslateFromMLIRRegistration registration(
119 "test-to-llvmir", "test dialect to LLVM IR",
120 [](Operation *op, raw_ostream &output) {
121 llvm::LLVMContext llvmContext;
122 auto llvmModule = translateModuleToLLVMIR(module: op, llvmContext);
123 if (!llvmModule)
124 return failure();
125
126 llvmModule->removeDebugIntrinsicDeclarations();
127 llvmModule->print(OS&: output, AAW: nullptr);
128 return success();
129 },
130 [](DialectRegistry &registry) {
131 registry.insert<test::TestDialect>();
132 registerBuiltinDialectTranslation(registry);
133 registerLLVMDialectTranslation(registry);
134 registry.addExtension(
135 extensionFn: +[](MLIRContext *ctx, test::TestDialect *dialect) {
136 dialect->addInterfaces<TestDialectLLVMIRTranslationInterface>();
137 });
138 });
139}
140
141} // namespace mlir
142

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of mlir/test/lib/Dialect/Test/TestToLLVMIRTranslation.cpp