CIRCT 20.0.0git
Loading...
Searching...
No Matches
KanagawaInlineSBlocksPass.cpp
Go to the documentation of this file.
1//===- KanagawaInlineSBlocksPass.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/Pass/Pass.h"
12
17#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
18
19#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
20
22#include "mlir/Transforms/DialectConversion.h"
23
24#include <iterator>
25
26namespace circt {
27namespace kanagawa {
28#define GEN_PASS_DEF_KANAGAWAINLINESBLOCKS
29#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc"
30} // namespace kanagawa
31} // namespace circt
32
33using namespace mlir;
34using namespace circt;
35using namespace kanagawa;
36
37namespace {
38
39struct InlineSBlocksPass
40 : public circt::kanagawa::impl::KanagawaInlineSBlocksBase<
41 InlineSBlocksPass> {
42 void runOnOperation() override;
43};
44
45class InlineSBlocksPattern
46 : public OpConversionPattern<kanagawa::StaticBlockOp> {
47public:
48 using OpConversionPattern<kanagawa::StaticBlockOp>::OpConversionPattern;
49 using OpAdaptor =
51
52 LogicalResult
53 matchAndRewrite(kanagawa::StaticBlockOp op, OpAdaptor adaptor,
54 ConversionPatternRewriter &rewriter) const override {
55 Location loc = op.getLoc();
56
57 // We only create block markers in case the sblock has attributes.
58 bool hasAttributes = !op->getAttrs().empty();
59
60 if (hasAttributes) {
61 // Start the inline block...
62 auto inlineStart =
63 rewriter.create<kanagawa::InlineStaticBlockBeginOp>(loc);
64 inlineStart->setAttrs(op->getAttrs());
65 }
66
67 // Inline the sblock.
68 Block *sblockBody = op.getBodyBlock();
69 BlockReturnOp ret = cast<BlockReturnOp>(sblockBody->getTerminator());
70 rewriter.inlineBlockBefore(sblockBody, op->getNextNode());
71
72 // Replace the kanagawa.sblock return values with the values that were
73 // defined (returned from) within the sblock body, and erase the return op.
74 for (auto [res, val] : llvm::zip(op.getResults(), ret.getRetValues()))
75 rewriter.replaceAllUsesWith(res, val);
76
77 if (hasAttributes) {
78 // Close the inline block
79 rewriter.setInsertionPoint(ret);
80 rewriter.create<kanagawa::InlineStaticBlockEndOp>(loc);
81 }
82
83 rewriter.eraseOp(ret);
84 rewriter.eraseOp(op);
85 return success();
86 }
87};
88
89} // anonymous namespace
90
91void InlineSBlocksPass::runOnOperation() {
92 MethodOp parent = getOperation();
93 ConversionTarget target(getContext());
94 target.addIllegalOp<kanagawa::StaticBlockOp>();
95 // Mark everything but `kanagawa.sblock` as legal - we need a legalization
96 // pattern for any possible op that gets inlined from a block.
97 target.markUnknownOpDynamicallyLegal([](Operation *op) { return true; });
98 RewritePatternSet patterns(&getContext());
99 patterns.add<InlineSBlocksPattern>(&getContext());
100
101 if (failed(applyPartialConversion(parent, target, std::move(patterns))))
102 return signalPassFailure();
103}
104
106 return std::make_unique<InlineSBlocksPass>();
107}
std::unique_ptr< mlir::Pass > createInlineSBlocksPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.