CIRCT  19.0.0git
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 
15 using namespace circt;
16 using namespace circt::esi;
17 
18 LogicalResult WrapValidReadyOp::fold(FoldAdaptor,
19  SmallVectorImpl<OpFoldResult> &results) {
20  if (!getChanOutput().getUsers().empty())
21  return failure();
22  results.push_back(NullChannelAttr::get(
23  getContext(), TypeAttr::get(getChanOutput().getType())));
24  results.push_back(IntegerAttr::get(IntegerType::get(getContext(), 1), 1));
25  return success();
26 }
27 
28 LogicalResult UnwrapFIFOOp::mergeAndErase(UnwrapFIFOOp unwrap, WrapFIFOOp wrap,
29  PatternRewriter &rewriter) {
30  if (unwrap && wrap) {
31  rewriter.replaceOp(unwrap, {wrap.getData(), wrap.getEmpty()});
32  rewriter.replaceOp(wrap, {{}, unwrap.getRden()});
33  return success();
34  }
35  return failure();
36 }
37 LogicalResult UnwrapFIFOOp::canonicalize(UnwrapFIFOOp op,
38  PatternRewriter &rewriter) {
39  auto wrap = dyn_cast_or_null<WrapFIFOOp>(op.getChanInput().getDefiningOp());
40  if (succeeded(UnwrapFIFOOp::mergeAndErase(op, wrap, rewriter)))
41  return success();
42  return failure();
43 }
44 
45 LogicalResult WrapFIFOOp::fold(FoldAdaptor,
46  SmallVectorImpl<OpFoldResult> &results) {
47  if (getChanOutput().getUsers().empty()) {
48  results.push_back({});
49  results.push_back(IntegerAttr::get(
50  IntegerType::get(getContext(), 1, IntegerType::Signless), 0));
51  return success();
52  }
53  return failure();
54 }
55 
56 LogicalResult WrapFIFOOp::canonicalize(WrapFIFOOp op,
57  PatternRewriter &rewriter) {
58  auto unwrap =
59  dyn_cast_or_null<UnwrapFIFOOp>(*op.getChanOutput().getUsers().begin());
60  if (succeeded(UnwrapFIFOOp::mergeAndErase(unwrap, op, rewriter)))
61  return success();
62  return failure();
63 }
64 
65 OpFoldResult WrapWindow::fold(FoldAdaptor) {
66  if (auto unwrap = dyn_cast_or_null<UnwrapWindow>(getFrame().getDefiningOp()))
67  return unwrap.getWindow();
68  return {};
69 }
70 OpFoldResult UnwrapWindow::fold(FoldAdaptor) {
71  if (auto wrap = dyn_cast_or_null<WrapWindow>(getWindow().getDefiningOp()))
72  return wrap.getFrame();
73  return {};
74 }
75 
76 LogicalResult PackBundleOp::canonicalize(PackBundleOp pack,
77  PatternRewriter &rewriter) {
78  Value bundle = pack.getBundle();
79  // This condition should be caught by the verifier, but we don't want to
80  // crash if we assume it since canonicalize can get run on IR in a broken
81  // state.
82  if (!bundle.hasOneUse())
83  return rewriter.notifyMatchFailure(pack,
84  "bundle has zero or more than one user");
85 
86  // unpack(pack(x)) -> x
87  auto unpack = dyn_cast<UnpackBundleOp>(*bundle.getUsers().begin());
88  if (unpack) {
89  for (auto [a, b] :
90  llvm::zip_equal(pack.getToChannels(), unpack.getToChannels()))
91  rewriter.replaceAllUsesWith(b, a);
92  for (auto [a, b] :
93  llvm::zip_equal(unpack.getFromChannels(), pack.getFromChannels()))
94  rewriter.replaceAllUsesWith(b, a);
95  rewriter.eraseOp(unpack);
96  rewriter.eraseOp(pack);
97  return success();
98  }
99  return rewriter.notifyMatchFailure(pack,
100  "could not find corresponding unpack");
101 }
102 
103 LogicalResult UnpackBundleOp::canonicalize(UnpackBundleOp unpack,
104  PatternRewriter &rewriter) {
105  Value bundle = unpack.getBundle();
106  // This condition should be caught by the verifier, but we don't want to
107  // crash if we assume it since canonicalize can get run on IR in a broken
108  // state.
109  if (!bundle.hasOneUse())
110  return rewriter.notifyMatchFailure(unpack,
111  "bundle has zero or more than one user");
112 
113  // Reuse pack's canonicalizer.
114  auto pack = dyn_cast_or_null<PackBundleOp>(bundle.getDefiningOp());
115  if (pack)
116  return PackBundleOp::canonicalize(pack, rewriter);
117  return rewriter.notifyMatchFailure(unpack,
118  "could not find corresponding pack");
119 }
return wrap(CMemoryType::get(unwrap(ctx), baseType, numElements))
static InstancePath empty
static EvaluatorValuePtr unwrap(OMEvaluatorValue c)
Definition: OM.cpp:96
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:54
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
Definition: DebugAnalysis.h:21