[libc++abi] Build cxxabi with sanitizers (#119612)
[llvm-project.git] / mlir / test / lib / Dialect / Test / TestToLLVMIRTranslation.cpp
blob157c6265be8346b66ae82f5620b9a2256a708701
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.
11 //===----------------------------------------------------------------------===//
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"
27 extern llvm::cl::opt<bool> WriteNewDbgInfoFormat;
29 using namespace mlir;
31 namespace {
33 class TestDialectLLVMIRTranslationInterface
34 : public LLVMTranslationDialectInterface {
35 public:
36 using LLVMTranslationDialectInterface::LLVMTranslationDialectInterface;
38 LogicalResult
39 amendOperation(Operation *op, ArrayRef<llvm::Instruction *> instructions,
40 NamedAttribute attribute,
41 LLVM::ModuleTranslation &moduleTranslation) const final;
43 LogicalResult
44 convertOperation(Operation *op, llvm::IRBuilderBase &builder,
45 LLVM::ModuleTranslation &moduleTranslation) const final;
48 } // namespace
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)>>(
55 attribute.getName())
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",
60 [&](Attribute attr) {
61 if (!isa<ModuleOp>(op)) {
62 op->emitOpError("attribute 'test.discardable_mod_attr' only "
63 "supported in modules");
64 return failure();
67 bool createSymbol = false;
68 if (auto boolAttr = dyn_cast<BoolAttr>(attr))
69 createSymbol = boolAttr.getValue();
71 if (createSymbol) {
72 OpBuilder builder(op->getRegion(0));
73 builder.create<test::SymbolOp>(
74 op->getLoc(),
75 StringAttr::get(op->getContext(), "sym_from_attr"),
76 /*sym_visibility=*/nullptr);
79 return success();
81 .Case("test.add_annotation",
82 [&](Attribute attr) {
83 for (llvm::Instruction *instruction : instructions) {
84 if (auto strAttr = dyn_cast<StringAttr>(attr)) {
85 instruction->addAnnotationMetadata("annotation_from_test: " +
86 strAttr.getValue().str());
87 } else {
88 instruction->addAnnotationMetadata("annotation_from_test");
91 return success();
93 .Default([](Attribute) {
94 // Skip other discardable dialect attributes.
95 return success();
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);
110 return success();
112 .Default([&](Operation *) {
113 return op->emitOpError("unsupported translation of test operation");
117 namespace mlir {
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);
125 if (!llvmModule)
126 return failure();
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);
136 return success();
138 [](DialectRegistry &registry) {
139 registry.insert<test::TestDialect>();
140 registerBuiltinDialectTranslation(registry);
141 registerLLVMDialectTranslation(registry);
142 registry.addExtension(
143 +[](MLIRContext *ctx, test::TestDialect *dialect) {
144 dialect->addInterfaces<TestDialectLLVMIRTranslationInterface>();
149 } // namespace mlir