CIRCT 22.0.0git
Loading...
Searching...
No Matches
LowerArcsToFuncs.cpp
Go to the documentation of this file.
1//===- LowerArcsToFuncs.cpp -----------------------------------------------===//
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
11#include "mlir/Dialect/Func/IR/FuncOps.h"
12#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
13#include "mlir/Transforms/DialectConversion.h"
14#include "llvm/Support/Debug.h"
15
16#define DEBUG_TYPE "arc-lower-arcs-to-funcs"
17
18namespace circt {
19namespace arc {
20#define GEN_PASS_DEF_LOWERARCSTOFUNCS
21#include "circt/Dialect/Arc/ArcPasses.h.inc"
22} // namespace arc
23} // namespace circt
24
25using namespace mlir;
26using namespace circt;
27
28//===----------------------------------------------------------------------===//
29// Pass Implementation
30//===----------------------------------------------------------------------===//
31
32namespace {
33struct LowerArcsToFuncsPass
34 : public arc::impl::LowerArcsToFuncsBase<LowerArcsToFuncsPass> {
35
36 LogicalResult lowerToFuncs();
37 void runOnOperation() override;
38};
39
40struct DefineOpLowering : public OpConversionPattern<arc::DefineOp> {
41 using OpConversionPattern::OpConversionPattern;
42 LogicalResult
43 matchAndRewrite(arc::DefineOp op, OpAdaptor adaptor,
44 ConversionPatternRewriter &rewriter) const final {
45 auto func = mlir::func::FuncOp::create(rewriter, op.getLoc(), op.getName(),
46 op.getFunctionType());
47 func->setAttr(
48 "llvm.linkage",
49 LLVM::LinkageAttr::get(getContext(), LLVM::linkage::Linkage::Internal));
50 rewriter.inlineRegionBefore(op.getRegion(), func.getBody(), func.end());
51 rewriter.eraseOp(op);
52 return success();
53 }
54};
55
56struct OutputOpLowering : public OpConversionPattern<arc::OutputOp> {
57 using OpConversionPattern::OpConversionPattern;
58 LogicalResult
59 matchAndRewrite(arc::OutputOp op, OpAdaptor adaptor,
60 ConversionPatternRewriter &rewriter) const final {
61 if (!isa<arc::DefineOp, func::FuncOp>(op->getParentOp()))
62 return failure();
63 rewriter.replaceOpWithNewOp<func::ReturnOp>(op, adaptor.getOutputs());
64 return success();
65 }
66};
67
68struct CallOpLowering : public OpConversionPattern<arc::CallOp> {
69 using OpConversionPattern::OpConversionPattern;
70 LogicalResult
71 matchAndRewrite(arc::CallOp op, OpAdaptor adaptor,
72 ConversionPatternRewriter &rewriter) const final {
73 SmallVector<Type> newResultTypes;
74 if (failed(
75 typeConverter->convertTypes(op.getResultTypes(), newResultTypes)))
76 return failure();
77 rewriter.replaceOpWithNewOp<func::CallOp>(
78 op, newResultTypes, op.getArcAttr(), adaptor.getInputs());
79 return success();
80 }
81};
82
83struct StateOpLowering : public OpConversionPattern<arc::StateOp> {
84 using OpConversionPattern::OpConversionPattern;
85 LogicalResult
86 matchAndRewrite(arc::StateOp op, OpAdaptor adaptor,
87 ConversionPatternRewriter &rewriter) const final {
88 SmallVector<Type> newResultTypes;
89 if (failed(
90 typeConverter->convertTypes(op.getResultTypes(), newResultTypes)))
91 return failure();
92 rewriter.replaceOpWithNewOp<func::CallOp>(
93 op, newResultTypes, op.getArcAttr(), adaptor.getInputs());
94 return success();
95 }
96};
97
98} // namespace
99
100static void populateLegality(ConversionTarget &target) {
101 target.addLegalDialect<func::FuncDialect>();
102 target.addLegalDialect<LLVM::LLVMDialect>();
103
104 target.addIllegalOp<arc::CallOp>();
105 target.addIllegalOp<arc::DefineOp>();
106 target.addDynamicallyLegalOp<arc::OutputOp>([](auto op) {
107 return !isa<arc::DefineOp, func::FuncOp>(op->getParentOp());
108 });
109 target.addIllegalOp<arc::StateOp>();
110}
111
112static void populateOpConversion(RewritePatternSet &patterns,
113 TypeConverter &typeConverter) {
114 auto *context = patterns.getContext();
116 .add<CallOpLowering, DefineOpLowering, OutputOpLowering, StateOpLowering>(
117 typeConverter, context);
118}
119
120static void populateTypeConversion(TypeConverter &typeConverter) {
121 typeConverter.addConversion([&](Type type) { return type; });
122}
123
124LogicalResult LowerArcsToFuncsPass::lowerToFuncs() {
125 LLVM_DEBUG(llvm::dbgs() << "Lowering arcs to funcs\n");
126 ConversionTarget target(getContext());
127 TypeConverter converter;
128 RewritePatternSet patterns(&getContext());
129 populateLegality(target);
130 populateTypeConversion(converter);
131 populateOpConversion(patterns, converter);
132 return applyPartialConversion(getOperation(), target, std::move(patterns));
133}
134
135void LowerArcsToFuncsPass::runOnOperation() {
136 if (failed(lowerToFuncs()))
137 return signalPassFailure();
138}
139
140std::unique_ptr<Pass> arc::createLowerArcsToFuncsPass() {
141 return std::make_unique<LowerArcsToFuncsPass>();
142}
static void populateLegality(ConversionTarget &target)
static void populateOpConversion(RewritePatternSet &patterns, TypeConverter &typeConverter)
static void populateTypeConversion(TypeConverter &typeConverter)
std::unique_ptr< mlir::Pass > createLowerArcsToFuncsPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.