Loading [MathJax]/extensions/tex2jax.js
CIRCT 22.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ESIFolds.cpp
Go to the documentation of this file.
1//===- ESIFolds.cpp - ESI op folders ----------------------------*- C++ -*-===//
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 "circt/Support/LLVM.h"
11
12#include "mlir/IR/BuiltinAttributes.h"
13#include "mlir/IR/PatternMatch.h"
14
15using namespace circt;
16using namespace circt::esi;
17
18LogicalResult WrapValidReadyOp::fold(FoldAdaptor,
19 SmallVectorImpl<OpFoldResult> &results) {
20 if (!getChanOutput().getUsers().empty())
21 return failure();
22 OpBuilder builder(getContext());
23 results.push_back(
24 builder.create<NullSourceOp>(getLoc(), getChanOutput().getType())
25 .getOut());
26 results.push_back(IntegerAttr::get(IntegerType::get(getContext(), 1), 1));
27 return success();
28}
29
30LogicalResult UnwrapFIFOOp::mergeAndErase(UnwrapFIFOOp unwrap, WrapFIFOOp wrap,
31 PatternRewriter &rewriter) {
32 if (unwrap && wrap) {
33 rewriter.replaceOp(unwrap, {wrap.getData(), wrap.getEmpty()});
34 rewriter.replaceOp(wrap, {{}, unwrap.getRden()});
35 return success();
36 }
37 return failure();
38}
39LogicalResult UnwrapFIFOOp::canonicalize(UnwrapFIFOOp op,
40 PatternRewriter &rewriter) {
41 auto wrap = dyn_cast_or_null<WrapFIFOOp>(op.getChanInput().getDefiningOp());
42 if (succeeded(UnwrapFIFOOp::mergeAndErase(op, wrap, rewriter)))
43 return success();
44 return failure();
45}
46
47LogicalResult WrapFIFOOp::fold(FoldAdaptor,
48 SmallVectorImpl<OpFoldResult> &results) {
49 if (!getChanOutput().getUsers().empty())
50 return failure();
51
52 OpBuilder builder(getContext());
53 results.push_back(
54 builder.create<NullSourceOp>(getLoc(), getChanOutput().getType())
55 .getOut());
56 results.push_back(IntegerAttr::get(
57 IntegerType::get(getContext(), 1, IntegerType::Signless), 0));
58 return success();
59}
60
61LogicalResult WrapFIFOOp::canonicalize(WrapFIFOOp op,
62 PatternRewriter &rewriter) {
63
64 if (!op.getChanOutput().hasOneUse())
65 return rewriter.notifyMatchFailure(
66 op, "channel output doesn't have exactly one use");
67 auto unwrap = dyn_cast_or_null<UnwrapFIFOOp>(
68 op.getChanOutput().getUses().begin()->getOwner());
69 if (succeeded(UnwrapFIFOOp::mergeAndErase(unwrap, op, rewriter)))
70 return success();
71 return rewriter.notifyMatchFailure(
72 op, "could not find corresponding unwrap for wrap");
73}
74
75OpFoldResult WrapWindow::fold(FoldAdaptor) {
76 if (auto unwrap = dyn_cast_or_null<UnwrapWindow>(getFrame().getDefiningOp()))
77 return unwrap.getWindow();
78 return {};
79}
80OpFoldResult UnwrapWindow::fold(FoldAdaptor) {
81 if (auto wrap = dyn_cast_or_null<WrapWindow>(getWindow().getDefiningOp()))
82 return wrap.getFrame();
83 return {};
84}
85
86LogicalResult PackBundleOp::canonicalize(PackBundleOp pack,
87 PatternRewriter &rewriter) {
88 Value bundle = pack.getBundle();
89 // This condition should be caught by the verifier, but we don't want to
90 // crash if we assume it since canonicalize can get run on IR in a broken
91 // state.
92 if (!bundle.hasOneUse())
93 return rewriter.notifyMatchFailure(pack,
94 "bundle has zero or more than one user");
95
96 // unpack(pack(x)) -> x
97 auto unpack = dyn_cast<UnpackBundleOp>(*bundle.getUsers().begin());
98 if (unpack) {
99 for (auto [a, b] :
100 llvm::zip_equal(pack.getToChannels(), unpack.getToChannels()))
101 rewriter.replaceAllUsesWith(b, a);
102 for (auto [a, b] :
103 llvm::zip_equal(unpack.getFromChannels(), pack.getFromChannels()))
104 rewriter.replaceAllUsesWith(b, a);
105 rewriter.eraseOp(unpack);
106 rewriter.eraseOp(pack);
107 return success();
108 }
109 return rewriter.notifyMatchFailure(pack,
110 "could not find corresponding unpack");
111}
112
113LogicalResult UnpackBundleOp::canonicalize(UnpackBundleOp unpack,
114 PatternRewriter &rewriter) {
115 Value bundle = unpack.getBundle();
116 // This condition should be caught by the verifier, but we don't want to
117 // crash if we assume it since canonicalize can get run on IR in a broken
118 // state.
119 if (!bundle.hasOneUse())
120 return rewriter.notifyMatchFailure(unpack,
121 "bundle has zero or more than one user");
122
123 // Reuse pack's canonicalizer.
124 auto pack = dyn_cast_or_null<PackBundleOp>(bundle.getDefiningOp());
125 if (pack)
126 return PackBundleOp::canonicalize(pack, rewriter);
127 return rewriter.notifyMatchFailure(unpack,
128 "could not find corresponding pack");
129}
AIGLongestPathObject wrap(llvm::PointerUnion< Object *, DataflowPath::OutputPort * > object)
Definition AIG.cpp:57
static Location getLoc(DefSlot slot)
Definition Mem2Reg.cpp:217
static EvaluatorValuePtr unwrap(OMEvaluatorValue c)
Definition OM.cpp:111
static InstancePath empty
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.