CIRCT 20.0.0git
Loading...
Searching...
No Matches
LTLFolds.cpp
Go to the documentation of this file.
1//===- LTLFolds.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
12#include "mlir/IR/PatternMatch.h"
13
14using namespace circt;
15using namespace ltl;
16using namespace mlir;
17
18/// Concatenate two value ranges into a larger range. Useful for declarative
19/// rewrites.
20static SmallVector<Value> concatValues(ValueRange a, ValueRange b) {
21 SmallVector<Value> v;
22 v.append(a.begin(), a.end());
23 v.append(b.begin(), b.end());
24 return v;
25}
26
27/// Inline all `ConcatOp`s in a range of values.
28static SmallVector<Value> flattenConcats(ValueRange values) {
29 SmallVector<Value> flatInputs;
30 for (auto value : values) {
31 if (auto concatOp = value.getDefiningOp<ConcatOp>()) {
32 auto inputs = concatOp.getInputs();
33 flatInputs.append(inputs.begin(), inputs.end());
34 } else {
35 flatInputs.push_back(value);
36 }
37 }
38 return flatInputs;
39}
40
41//===----------------------------------------------------------------------===//
42// Declarative Rewrites
43//===----------------------------------------------------------------------===//
44
45namespace patterns {
46#include "circt/Dialect/LTL/LTLFolds.cpp.inc"
47} // namespace patterns
48
49//===----------------------------------------------------------------------===//
50// AndOp / OrOp / IntersectOp
51//===----------------------------------------------------------------------===//
52
53LogicalResult AndOp::canonicalize(AndOp op, PatternRewriter &rewriter) {
54 if (op.getType() == rewriter.getI1Type()) {
55 rewriter.replaceOpWithNewOp<comb::AndOp>(op, op.getInputs(), true);
56 return success();
57 }
58 return failure();
59}
60
61LogicalResult OrOp::canonicalize(OrOp op, PatternRewriter &rewriter) {
62 if (op.getType() == rewriter.getI1Type()) {
63 rewriter.replaceOpWithNewOp<comb::OrOp>(op, op.getInputs(), true);
64 return success();
65 }
66 return failure();
67}
68
69LogicalResult IntersectOp::canonicalize(IntersectOp op,
70 PatternRewriter &rewriter) {
71 if (op.getType() == rewriter.getI1Type()) {
72 rewriter.replaceOpWithNewOp<comb::AndOp>(op, op.getInputs(), true);
73 return success();
74 }
75 return failure();
76}
77
78//===----------------------------------------------------------------------===//
79// DelayOp
80//===----------------------------------------------------------------------===//
81
82OpFoldResult DelayOp::fold(FoldAdaptor adaptor) {
83 // delay(s, 0, 0) -> s
84 if (adaptor.getDelay() == 0 && adaptor.getLength() == 0 &&
85 isa<SequenceType>(getInput().getType()))
86 return getInput();
87
88 return {};
89}
90
91void DelayOp::getCanonicalizationPatterns(RewritePatternSet &results,
92 MLIRContext *context) {
93 results.add<patterns::NestedDelays>(results.getContext());
94 results.add<patterns::MoveDelayIntoConcat>(results.getContext());
95}
96
97//===----------------------------------------------------------------------===//
98// ConcatOp
99//===----------------------------------------------------------------------===//
100
101OpFoldResult ConcatOp::fold(FoldAdaptor adaptor) {
102 // concat(s) -> s
103 if (getInputs().size() == 1)
104 return getInputs()[0];
105
106 return {};
107}
108
109void ConcatOp::getCanonicalizationPatterns(RewritePatternSet &results,
110 MLIRContext *context) {
111 results.add<patterns::FlattenConcats>(results.getContext());
112}
113
114//===----------------------------------------------------------------------===//
115// RepeatLikeOps
116//===----------------------------------------------------------------------===//
117
118namespace {
119struct RepeatLikeOp {
120 static OpFoldResult fold(uint64_t base, uint64_t more, Value input) {
121 // repeat(s, 1, 0) -> s
122 if (base == 1 && more == 0 && isa<SequenceType>(input.getType()))
123 return input;
124
125 return {};
126 }
127};
128} // namespace
129
130OpFoldResult RepeatOp::fold(FoldAdaptor adaptor) {
131 auto more = adaptor.getMore();
132 if (more.has_value())
133 return RepeatLikeOp::fold(adaptor.getBase(), *more, getInput());
134 return {};
135}
136
137OpFoldResult GoToRepeatOp::fold(FoldAdaptor adaptor) {
138 return RepeatLikeOp::fold(adaptor.getBase(), adaptor.getMore(), getInput());
139}
140
141OpFoldResult NonConsecutiveRepeatOp::fold(FoldAdaptor adaptor) {
142 return RepeatLikeOp::fold(adaptor.getBase(), adaptor.getMore(), getInput());
143}
static SmallVector< Value > flattenConcats(ValueRange values)
Inline all ConcatOps in a range of values.
Definition LTLFolds.cpp:28
static SmallVector< Value > concatValues(ValueRange a, ValueRange b)
Concatenate two value ranges into a larger range.
Definition LTLFolds.cpp:20
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition ltl.py:1