CIRCT 20.0.0git
Loading...
Searching...
No Matches
KanagawaArgifyBlocksPass.cpp
Go to the documentation of this file.
1//===- KanagawaArgifyBlocksPass.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
18#include "mlir/Transforms/DialectConversion.h"
19
20namespace circt {
21namespace kanagawa {
22#define GEN_PASS_DEF_KANAGAWAARGIFYBLOCKS
23#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc"
24} // namespace kanagawa
25} // namespace circt
26
27using namespace circt;
28using namespace kanagawa;
29
30namespace {
31
32// A mapping between values and op operands who use them. A MapVector is used to
33// ensure determinism.
34using ValueMapping = llvm::MapVector<Value, llvm::SmallVector<OpOperand *>>;
35
36// Returns a map of values to op operands, of values that are defined
37// outside of the block op.
38static void getExternallyDefinedOperands(StaticBlockOp blockOp,
39 ValueMapping &mapping) {
40 Block *blockBodyBlock = blockOp.getBodyBlock();
41 for (Operation &op : *blockBodyBlock) {
42 for (OpOperand &operand : op.getOpOperands()) {
43 Value v = operand.get();
44 if (v.getParentBlock() != blockBodyBlock)
45 mapping[v].push_back(&operand);
46 }
47 }
48}
49
50struct BlockConversionPattern : public OpConversionPattern<StaticBlockOp> {
52
53 LogicalResult
54 matchAndRewrite(StaticBlockOp blockOp, OpAdaptor adaptor,
55 ConversionPatternRewriter &rewriter) const override {
56 ValueMapping mapping;
57 getExternallyDefinedOperands(blockOp, mapping);
58 Block *bodyBlock = blockOp.getBodyBlock();
59
60 auto isolatedBlock = rewriter.create<IsolatedStaticBlockOp>(
61 blockOp.getLoc(), blockOp.getResultTypes(), blockOp.getOperands(),
62 blockOp.getMaxThreadsAttr());
63 // Erase the default terminator.
64 Block *isolatedBlockBody = isolatedBlock.getBodyBlock();
65 rewriter.eraseOp(isolatedBlockBody->getTerminator());
66 llvm::SmallVector<Value> preAddBArgs;
67 llvm::copy(blockOp.getBodyBlock()->getArguments(),
68 std::back_inserter(preAddBArgs));
69
70 // Add inputs and block arguments to the block, and replace the operand
71 // uses.
72 for (auto &[value, uses] : mapping) {
73 isolatedBlock.getInputsMutable().append({value});
74 auto newArg =
75 isolatedBlockBody->addArgument(value.getType(), value.getLoc());
76 for (OpOperand *operand : uses)
77 operand->set(newArg);
78 }
79 // Inline the old block into the isolated block
80 rewriter.mergeBlocks(bodyBlock, isolatedBlockBody, preAddBArgs);
81 rewriter.replaceOp(blockOp, isolatedBlock.getResults());
82 return success();
83 }
84};
85
86struct ArgifyBlocksPass
87 : public circt::kanagawa::impl::KanagawaArgifyBlocksBase<ArgifyBlocksPass> {
88 void runOnOperation() override;
89};
90} // anonymous namespace
91
92void ArgifyBlocksPass::runOnOperation() {
93 auto *ctx = &getContext();
94 ConversionTarget target(*ctx);
95 target.addIllegalOp<StaticBlockOp>();
96 target.addLegalDialect<KanagawaDialect>();
97
98 RewritePatternSet patterns(ctx);
99 patterns.add<BlockConversionPattern>(ctx);
100
101 if (failed(
102 applyPartialConversion(getOperation(), target, std::move(patterns))))
103 signalPassFailure();
104}
105
107 return std::make_unique<ArgifyBlocksPass>();
108}
std::unique_ptr< mlir::Pass > createArgifyBlocksPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.