brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · 7831b27 Raw
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 &registry) {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