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
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 conversion
25struct 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(op: funcOp);
39 return success();
40 }
41};
42
43struct 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
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 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>(arg&: typeConverter);
92 patterns.add<ReturnOpConversion>(arg&: typeConverter);
93
94 LLVMConversionTarget target(getContext());
95 if (failed(applyPartialConversion(getOperation(), target,
96 std::move(patterns))))
97 signalPassFailure();
98 }
99};
100
101} // namespace
102
103namespace mlir::test {
104void registerConvertFuncOpPass() { PassRegistration<TestConvertFuncOp>(); }
105} // namespace mlir::test
106

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of mlir/test/lib/Conversion/FuncToLLVM/TestConvertFuncOp.cpp