142 lines · cpp
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-exception6//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 TestDialectLLVMIRTranslationInterface32 : public LLVMTranslationDialectInterface {33public:34 using LLVMTranslationDialectInterface::LLVMTranslationDialectInterface;35 36 LogicalResult37 amendOperation(Operation *op, ArrayRef<llvm::Instruction *> instructions,38 NamedAttribute attribute,39 LLVM::ModuleTranslation &moduleTranslation) const final;40 41 LogicalResult42 convertOperation(Operation *op, llvm::IRBuilderBase &builder,43 LLVM::ModuleTranslation &moduleTranslation) const final;44};45 46} // namespace47 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 to55 // `true`, results in the addition of a `test.symbol` in the module it is56 // attached to with name "sym_from_attr".57 .Case("test.discardable_mod_attr",58 [&](Attribute attr) {59 if (!isa<ModuleOp>(op)) {60 op->emitOpError("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>(attr))67 createSymbol = boolAttr.getValue();68 69 if (createSymbol) {70 OpBuilder builder(op->getRegion(0));71 test::SymbolOp::create(72 builder, op->getLoc(),73 StringAttr::get(op->getContext(), "sym_from_attr"),74 /*sym_visibility=*/nullptr);75 }76 77 return success();78 })79 .Case("test.add_annotation",80 [&](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_from_test");87 }88 }89 return success();90 })91 .Default([](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 a102 // name equal to the symbol they are translated from.103 .Case([&](test::SymbolOp symOp) {104 llvm::Module *mod = moduleTranslation.getLLVMModule();105 llvm::IntegerType *i32Type =106 llvm::IntegerType::get(moduleTranslation.getLLVMContext(), 32);107 mod->getOrInsertGlobal(symOp.getSymName(), i32Type);108 return success();109 })110 .Default([&](Operation *) {111 return op->emitOpError("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(op, llvmContext);123 if (!llvmModule)124 return failure();125 126 llvmModule->removeDebugIntrinsicDeclarations();127 llvmModule->print(output, nullptr);128 return success();129 },130 [](DialectRegistry ®istry) {131 registry.insert<test::TestDialect>();132 registerBuiltinDialectTranslation(registry);133 registerLLVMDialectTranslation(registry);134 registry.addExtension(135 +[](MLIRContext *ctx, test::TestDialect *dialect) {136 dialect->addInterfaces<TestDialectLLVMIRTranslationInterface>();137 });138 });139}140 141} // namespace mlir142