106 lines · cpp
1//===- TestConvertFuncOp.cpp - Test LLVM Conversion of Func FuncOp --------===//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 "TestDialect.h"10 11#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"12#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"13#include "mlir/Conversion/LLVMCommon/Pattern.h"14#include "mlir/Dialect/Func/IR/FuncOps.h"15#include "mlir/Dialect/LLVMIR/LLVMDialect.h"16#include "mlir/IR/PatternMatch.h"17#include "mlir/Pass/Pass.h"18 19using namespace mlir;20 21namespace {22 23/// Test helper Conversion Pattern to directly call `convertFuncOpToLLVMFuncOp`24/// to verify this utility function includes all functionalities of conversion25struct FuncOpConversion : public ConvertOpToLLVMPattern<func::FuncOp> {26 FuncOpConversion(const LLVMTypeConverter &converter)27 : ConvertOpToLLVMPattern(converter) {}28 29 LogicalResult30 matchAndRewrite(func::FuncOp funcOp, OpAdaptor adaptor,31 ConversionPatternRewriter &rewriter) const override {32 FailureOr<LLVM::LLVMFuncOp> newFuncOp = mlir::convertFuncOpToLLVMFuncOp(33 cast<FunctionOpInterface>(funcOp.getOperation()), rewriter,34 *getTypeConverter());35 if (failed(newFuncOp))36 return rewriter.notifyMatchFailure(funcOp, "Could not convert funcop");37 38 rewriter.eraseOp(funcOp);39 return success();40 }41};42 43struct ReturnOpConversion : public ConvertOpToLLVMPattern<func::ReturnOp> {44 ReturnOpConversion(const LLVMTypeConverter &converter)45 : ConvertOpToLLVMPattern(converter) {}46 47 LogicalResult48 matchAndRewrite(func::ReturnOp returnOp, OpAdaptor adaptor,49 ConversionPatternRewriter &rewriter) const override {50 SmallVector<Type> resTys;51 if (failed(typeConverter->convertTypes(returnOp->getResultTypes(), resTys)))52 return failure();53 54 rewriter.replaceOpWithNewOp<LLVM::ReturnOp>(returnOp, resTys,55 adaptor.getOperands());56 return success();57 }58};59 60static std::optional<Type>61convertSimpleATypeToStruct(test::SimpleAType simpleTy) {62 MLIRContext *ctx = simpleTy.getContext();63 SmallVector<Type> memberTys(2, IntegerType::get(ctx, /*width=*/8));64 return LLVM::LLVMStructType::getLiteral(ctx, memberTys);65}66 67struct TestConvertFuncOp68 : public PassWrapper<TestConvertFuncOp, OperationPass<ModuleOp>> {69 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestConvertFuncOp)70 71 void getDependentDialects(DialectRegistry ®istry) const final {72 registry.insert<LLVM::LLVMDialect>();73 }74 75 StringRef getArgument() const final { return "test-convert-func-op"; }76 77 StringRef getDescription() const final {78 return "Tests conversion of `func.func` to `llvm.func` for different "79 "attributes";80 }81 82 void runOnOperation() override {83 MLIRContext *ctx = &getContext();84 85 LowerToLLVMOptions options(ctx);86 // Populate type conversions.87 LLVMTypeConverter typeConverter(ctx, options);88 typeConverter.addConversion(convertSimpleATypeToStruct);89 90 RewritePatternSet patterns(ctx);91 patterns.add<FuncOpConversion>(typeConverter);92 patterns.add<ReturnOpConversion>(typeConverter);93 94 LLVMConversionTarget target(getContext());95 if (failed(applyPartialConversion(getOperation(), target,96 std::move(patterns))))97 signalPassFailure();98 }99};100 101} // namespace102 103namespace mlir::test {104void registerConvertFuncOpPass() { PassRegistration<TestConvertFuncOp>(); }105} // namespace mlir::test106