xref: /llvm-project/mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp (revision 2ac2e9a5b6c97cbf267db1ef322ed21ebceb2aba)
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-exception
6 //
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 
19 using namespace mlir;
20 
21 namespace {
22 
23 /// Test helper Conversion Pattern to directly call `convertFuncOpToLLVMFuncOp`
24 /// to verify this utility function includes all functionalities of conversion
25 struct FuncOpConversion : public ConvertOpToLLVMPattern<func::FuncOp> {
26   FuncOpConversion(const LLVMTypeConverter &converter)
27       : ConvertOpToLLVMPattern(converter) {}
28 
29   LogicalResult
30   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 
43 struct ReturnOpConversion : public ConvertOpToLLVMPattern<func::ReturnOp> {
44   ReturnOpConversion(const LLVMTypeConverter &converter)
45       : ConvertOpToLLVMPattern(converter) {}
46 
47   LogicalResult
48   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 
60 static std::optional<Type>
61 convertSimpleATypeToStruct(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 
67 struct TestConvertFuncOp
68     : public PassWrapper<TestConvertFuncOp, OperationPass<ModuleOp>> {
69   MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestConvertFuncOp)
70 
71   void getDependentDialects(DialectRegistry &registry) 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 } // namespace
102 
103 namespace mlir::test {
104 void registerConvertFuncOpPass() { PassRegistration<TestConvertFuncOp>(); }
105 } // namespace mlir::test
106