Loading [MathJax]/extensions/tex2jax.js
CIRCT 21.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 (std::any_of(affineParallelSteps.begin(), affineParallelSteps.end(),
46 [](int step) { return step > 1; }) ||
47 !affineParallelOp->getAttr("calyx.unroll"))
48 return rewriter.notifyMatchFailure(
49 affineParallelOp,
50 "Please run the MLIR canonical '-lower-affine' pass.");
51
52 if (!affineParallelOp.getResults().empty())
53 return rewriter.notifyMatchFailure(
54 affineParallelOp, "Currently doesn't support parallel reduction.");
55
56 Location loc = affineParallelOp.getLoc();
57 SmallVector<Value, 8> steps;
58 for (int64_t step : affineParallelSteps)
59 steps.push_back(rewriter.create<arith::ConstantIndexOp>(loc, step));
60
61 auto upperBoundTuple = mlir::affine::expandAffineMap(
62 rewriter, loc, affineParallelOp.getUpperBoundsMap(),
63 affineParallelOp.getUpperBoundsOperands());
64
65 auto lowerBoundTuple = mlir::affine::expandAffineMap(
66 rewriter, loc, affineParallelOp.getLowerBoundsMap(),
67 affineParallelOp.getLowerBoundsOperands());
68
69 auto affineParallelTerminator = cast<affine::AffineYieldOp>(
70 affineParallelOp.getBody()->getTerminator());
71
72 scf::ParallelOp scfParallelOp = rewriter.create<scf::ParallelOp>(
73 loc, *lowerBoundTuple, *upperBoundTuple, steps,
74 /*bodyBuilderFn=*/nullptr);
75 scfParallelOp->setAttr("calyx.unroll",
76 affineParallelOp->getAttr("calyx.unroll"));
77 rewriter.eraseBlock(scfParallelOp.getBody());
78 rewriter.inlineRegionBefore(affineParallelOp.getRegion(),
79 scfParallelOp.getRegion(),
80 scfParallelOp.getRegion().end());
81 rewriter.replaceOp(affineParallelOp, scfParallelOp);
82 rewriter.setInsertionPoint(affineParallelTerminator);
83 rewriter.replaceOpWithNewOp<scf::ReduceOp>(affineParallelTerminator);
84
85 return success();
86 }
87};
88
89namespace {
90class AffineToSCFPass
91 : public circt::calyx::impl::AffineToSCFBase<AffineToSCFPass> {
92 void runOnOperation() override;
93};
94} // namespace
95
96void AffineToSCFPass::runOnOperation() {
97 MLIRContext *ctx = &getContext();
98
99 ConversionTarget target(*ctx);
100 target.addLegalDialect<arith::ArithDialect, memref::MemRefDialect,
101 scf::SCFDialect>();
102
103 RewritePatternSet patterns(ctx);
105 if (failed(applyPartialConversion(getOperation(), target,
106 std::move(patterns)))) {
107 signalPassFailure();
108 }
109}
110
111std::unique_ptr<mlir::Pass> circt::calyx::createAffineToSCFPass() {
112 return std::make_unique<AffineToSCFPass>();
113}
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.