CIRCT 24.0.0git
Loading...
Searching...
No Matches
AffineToSCF.cpp
Go to the documentation of this file.
1//===- AffineToSCF.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
10#include "mlir/Dialect/Affine/IR/AffineOps.h"
11#include "mlir/Dialect/Affine/Utils.h"
12#include "mlir/Dialect/Arith/IR/Arith.h"
13#include "mlir/Dialect/Arith/Transforms/Passes.h"
14#include "mlir/Dialect/Func/IR/FuncOps.h"
15#include "mlir/Dialect/MemRef/IR/MemRef.h"
16#include "mlir/Dialect/SCF/IR/SCF.h"
17#include "mlir/IR/PatternMatch.h"
18#include "mlir/Pass/PassManager.h"
19#include "mlir/Support/LogicalResult.h"
20#include "mlir/Transforms/DialectConversion.h"
21
22namespace circt {
23namespace calyx {
24#define GEN_PASS_DEF_AFFINETOSCF
25#include "circt/Dialect/Calyx/CalyxPasses.h.inc"
26} // namespace calyx
27} // namespace circt
28
29using namespace mlir;
30using namespace mlir::arith;
31using namespace mlir::memref;
32using namespace mlir::scf;
33using namespace mlir::func;
34using namespace circt;
35
37 : public OpConversionPattern<affine::AffineParallelOp> {
38 using OpConversionPattern::OpConversionPattern;
39
40public:
41 LogicalResult
42 matchAndRewrite(affine::AffineParallelOp affineParallelOp, OpAdaptor adaptor,
43 ConversionPatternRewriter &rewriter) const override {
44 auto affineParallelSteps = affineParallelOp.getSteps();
45 if (llvm::any_of(affineParallelSteps, [](int step) { return step > 1; }) ||
46 !affineParallelOp->getAttr("calyx.unroll"))
47 return rewriter.notifyMatchFailure(
48 affineParallelOp,
49 "Please run the MLIR canonical '-lower-affine' pass.");
50
51 if (!affineParallelOp.getResults().empty())
52 return rewriter.notifyMatchFailure(
53 affineParallelOp, "Currently doesn't support parallel reduction.");
54
55 Location loc = affineParallelOp.getLoc();
56 SmallVector<Value, 8> steps;
57 for (int64_t step : affineParallelSteps)
58 steps.push_back(arith::ConstantIndexOp::create(rewriter, loc, step));
59
60 auto upperBoundTuple = mlir::affine::expandAffineMap(
61 rewriter, loc, affineParallelOp.getUpperBoundsMap(),
62 affineParallelOp.getUpperBoundsOperands());
63
64 auto lowerBoundTuple = mlir::affine::expandAffineMap(
65 rewriter, loc, affineParallelOp.getLowerBoundsMap(),
66 affineParallelOp.getLowerBoundsOperands());
67
68 auto affineParallelTerminator = cast<affine::AffineYieldOp>(
69 affineParallelOp.getBody()->getTerminator());
70
71 scf::ParallelOp scfParallelOp = scf::ParallelOp::create(
72 rewriter, loc, *lowerBoundTuple, *upperBoundTuple, steps,
73 /*bodyBuilderFn=*/nullptr);
74 scfParallelOp->setAttr("calyx.unroll",
75 affineParallelOp->getAttr("calyx.unroll"));
76 rewriter.eraseBlock(scfParallelOp.getBody());
77 rewriter.inlineRegionBefore(affineParallelOp.getRegion(),
78 scfParallelOp.getRegion(),
79 scfParallelOp.getRegion().end());
80 rewriter.replaceOp(affineParallelOp, scfParallelOp);
81 rewriter.setInsertionPoint(affineParallelTerminator);
82 rewriter.replaceOpWithNewOp<scf::ReduceOp>(affineParallelTerminator);
83
84 return success();
85 }
86};
87
88namespace {
89class AffineToSCFPass
90 : public circt::calyx::impl::AffineToSCFBase<AffineToSCFPass> {
91 void runOnOperation() override;
92};
93} // namespace
94
95void AffineToSCFPass::runOnOperation() {
96 MLIRContext *ctx = &getContext();
97
98 ConversionTarget target(*ctx);
99 target.addLegalDialect<arith::ArithDialect, memref::MemRefDialect,
100 scf::SCFDialect>();
101
102 RewritePatternSet patterns(ctx);
103 patterns.add<AffineParallelOpLowering>(ctx);
104 if (failed(applyPartialConversion(getOperation(), target,
105 std::move(patterns)))) {
106 signalPassFailure();
107 }
108}
109
110std::unique_ptr<mlir::Pass> circt::calyx::createAffineToSCFPass() {
111 return std::make_unique<AffineToSCFPass>();
112}
return success()
LogicalResult matchAndRewrite(affine::AffineParallelOp affineParallelOp, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override
std::unique_ptr< mlir::Pass > createAffineToSCFPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.