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-exception 6 // 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 19 namespace mlir { 20 #define GEN_PASS_DEF_UBTOLLVMCONVERSIONPASS 21 #include "mlir/Conversion/Passes.h.inc" 22 } // namespace mlir 23 24 using namespace mlir; 25 26 namespace { 27 28 struct PoisonOpLowering : public ConvertOpToLLVMPattern<ub::PoisonOp> { 29 using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; 30 31 LogicalResult 32 matchAndRewrite(ub::PoisonOp op, OpAdaptor adaptor, 33 ConversionPatternRewriter &rewriter) const override; 34 }; 35 36 } // namespace 37 38 //===----------------------------------------------------------------------===// 39 // PoisonOpLowering 40 //===----------------------------------------------------------------------===// 41 42 LogicalResult 43 PoisonOpLowering::matchAndRewrite(ub::PoisonOp op, OpAdaptor adaptor, 44 ConversionPatternRewriter &rewriter) const { 45 if (!isa<ub::PoisonAttr>(op.getValue())) { 46 return rewriter.notifyMatchFailure(op, [&](Diagnostic &diag) { 47 diag << "pattern can only convert op with '" 48 << ub::PoisonAttr::getMnemonic() << "' poison value"; 49 }); 50 } 51 52 Type resType = getTypeConverter()->convertType(op.getType()); 53 if (!resType) { 54 return rewriter.notifyMatchFailure(op, [&](Diagnostic &diag) { 55 diag << "failed to convert result type " << op.getType(); 56 }); 57 } 58 59 rewriter.replaceOpWithNewOp<LLVM::PoisonOp>(op, resType); 60 return success(); 61 } 62 63 //===----------------------------------------------------------------------===// 64 // Pass Definition 65 //===----------------------------------------------------------------------===// 66 67 namespace { 68 struct UBToLLVMConversionPass 69 : public impl::UBToLLVMConversionPassBase<UBToLLVMConversionPass> { 70 using Base::Base; 71 72 void runOnOperation() override { 73 LLVMConversionTarget target(getContext()); 74 RewritePatternSet patterns(&getContext()); 75 76 LowerToLLVMOptions options(&getContext()); 77 if (indexBitwidth != kDeriveIndexBitwidthFromDataLayout) 78 options.overrideIndexBitwidth(indexBitwidth); 79 80 LLVMTypeConverter converter(&getContext(), options); 81 mlir::ub::populateUBToLLVMConversionPatterns(converter, patterns); 82 83 if (failed(applyPartialConversion(getOperation(), target, 84 std::move(patterns)))) 85 signalPassFailure(); 86 } 87 }; 88 } // namespace 89 90 //===----------------------------------------------------------------------===// 91 // Pattern Population 92 //===----------------------------------------------------------------------===// 93 94 void mlir::ub::populateUBToLLVMConversionPatterns( 95 const LLVMTypeConverter &converter, RewritePatternSet &patterns) { 96 patterns.add<PoisonOpLowering>(converter); 97 } 98 99 //===----------------------------------------------------------------------===// 100 // ConvertToLLVMPatternInterface implementation 101 //===----------------------------------------------------------------------===// 102 103 namespace { 104 /// Implement the interface to convert UB to LLVM. 105 struct UBToLLVMDialectInterface : public ConvertToLLVMPatternInterface { 106 using ConvertToLLVMPatternInterface::ConvertToLLVMPatternInterface; 107 void loadDependentDialects(MLIRContext *context) const final { 108 context->loadDialect<LLVM::LLVMDialect>(); 109 } 110 111 /// Hook for derived dialect interface to provide conversion patterns 112 /// and mark dialect legal for the conversion target. 113 void populateConvertToLLVMConversionPatterns( 114 ConversionTarget &target, LLVMTypeConverter &typeConverter, 115 RewritePatternSet &patterns) const final { 116 ub::populateUBToLLVMConversionPatterns(typeConverter, patterns); 117 } 118 }; 119 } // namespace 120 121 void mlir::ub::registerConvertUBToLLVMInterface(DialectRegistry ®istry) { 122 registry.addExtension(+[](MLIRContext *ctx, ub::UBDialect *dialect) { 123 dialect->addInterfaces<UBToLLVMDialectInterface>(); 124 }); 125 } 126