147 lines · cpp
1//===- UBToLLVM.cpp - UB to LLVM dialect conversion -----------------------===//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#include "mlir/Conversion/UBToLLVM/UBToLLVM.h"10 11#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"12#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"13#include "mlir/Conversion/LLVMCommon/Pattern.h"14#include "mlir/Dialect/LLVMIR/LLVMDialect.h"15#include "mlir/Dialect/UB/IR/UBOps.h"16#include "mlir/IR/TypeUtilities.h"17#include "mlir/Pass/Pass.h"18 19namespace mlir {20#define GEN_PASS_DEF_UBTOLLVMCONVERSIONPASS21#include "mlir/Conversion/Passes.h.inc"22} // namespace mlir23 24using namespace mlir;25 26//===----------------------------------------------------------------------===//27// PoisonOpLowering28//===----------------------------------------------------------------------===//29 30namespace {31struct PoisonOpLowering : public ConvertOpToLLVMPattern<ub::PoisonOp> {32 using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;33 34 LogicalResult35 matchAndRewrite(ub::PoisonOp op, OpAdaptor adaptor,36 ConversionPatternRewriter &rewriter) const override;37};38} // namespace39 40LogicalResult41PoisonOpLowering::matchAndRewrite(ub::PoisonOp op, OpAdaptor adaptor,42 ConversionPatternRewriter &rewriter) const {43 if (!isa<ub::PoisonAttr>(op.getValue())) {44 return rewriter.notifyMatchFailure(op, [&](Diagnostic &diag) {45 diag << "pattern can only convert op with '"46 << ub::PoisonAttr::getMnemonic() << "' poison value";47 });48 }49 50 Type resType = getTypeConverter()->convertType(op.getType());51 if (!resType) {52 return rewriter.notifyMatchFailure(op, [&](Diagnostic &diag) {53 diag << "failed to convert result type " << op.getType();54 });55 }56 57 rewriter.replaceOpWithNewOp<LLVM::PoisonOp>(op, resType);58 return success();59}60 61//===----------------------------------------------------------------------===//62// UnreachableOpLowering63//===----------------------------------------------------------------------===//64 65namespace {66struct UnreachableOpLowering67 : public ConvertOpToLLVMPattern<ub::UnreachableOp> {68 using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;69 70 LogicalResult71 matchAndRewrite(ub::UnreachableOp op, OpAdaptor adaptor,72 ConversionPatternRewriter &rewriter) const override;73};74} // namespace75LogicalResult76 77UnreachableOpLowering::matchAndRewrite(78 ub::UnreachableOp op, OpAdaptor adaptor,79 ConversionPatternRewriter &rewriter) const {80 rewriter.replaceOpWithNewOp<LLVM::UnreachableOp>(op);81 return success();82}83 84//===----------------------------------------------------------------------===//85// Pass Definition86//===----------------------------------------------------------------------===//87 88namespace {89struct UBToLLVMConversionPass90 : public impl::UBToLLVMConversionPassBase<UBToLLVMConversionPass> {91 using Base::Base;92 93 void runOnOperation() override {94 LLVMConversionTarget target(getContext());95 RewritePatternSet patterns(&getContext());96 97 LowerToLLVMOptions options(&getContext());98 if (indexBitwidth != kDeriveIndexBitwidthFromDataLayout)99 options.overrideIndexBitwidth(indexBitwidth);100 101 LLVMTypeConverter converter(&getContext(), options);102 mlir::ub::populateUBToLLVMConversionPatterns(converter, patterns);103 104 if (failed(applyPartialConversion(getOperation(), target,105 std::move(patterns))))106 signalPassFailure();107 }108};109} // namespace110 111//===----------------------------------------------------------------------===//112// Pattern Population113//===----------------------------------------------------------------------===//114 115void mlir::ub::populateUBToLLVMConversionPatterns(116 const LLVMTypeConverter &converter, RewritePatternSet &patterns) {117 patterns.add<PoisonOpLowering, UnreachableOpLowering>(converter);118}119 120//===----------------------------------------------------------------------===//121// ConvertToLLVMPatternInterface implementation122//===----------------------------------------------------------------------===//123 124namespace {125/// Implement the interface to convert UB to LLVM.126struct UBToLLVMDialectInterface : public ConvertToLLVMPatternInterface {127 using ConvertToLLVMPatternInterface::ConvertToLLVMPatternInterface;128 void loadDependentDialects(MLIRContext *context) const final {129 context->loadDialect<LLVM::LLVMDialect>();130 }131 132 /// Hook for derived dialect interface to provide conversion patterns133 /// and mark dialect legal for the conversion target.134 void populateConvertToLLVMConversionPatterns(135 ConversionTarget &target, LLVMTypeConverter &typeConverter,136 RewritePatternSet &patterns) const final {137 ub::populateUBToLLVMConversionPatterns(typeConverter, patterns);138 }139};140} // namespace141 142void mlir::ub::registerConvertUBToLLVMInterface(DialectRegistry ®istry) {143 registry.addExtension(+[](MLIRContext *ctx, ub::UBDialect *dialect) {144 dialect->addInterfaces<UBToLLVMDialectInterface>();145 });146}147