CIRCT 24.0.0git
Loading...
Searching...
No Matches
CombOps.h
Go to the documentation of this file.
1//===- CombOps.h - Declare Comb dialect operations --------------*- 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//
9// This file declares the operation classes for the Comb dialect.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef CIRCT_DIALECT_COMB_COMBOPS_H
14#define CIRCT_DIALECT_COMB_COMBOPS_H
15
19#include "circt/Support/LLVM.h"
20#include "mlir/Bytecode/BytecodeOpInterface.h"
21#include "mlir/IR/BuiltinOps.h"
22#include "mlir/IR/Matchers.h"
23#include "mlir/IR/OpImplementation.h"
24#include "mlir/Interfaces/FunctionInterfaces.h"
25#include "mlir/Interfaces/InferIntRangeInterface.h"
26#include "mlir/Interfaces/InferTypeOpInterface.h"
27#include "mlir/Interfaces/SideEffectInterfaces.h"
28#include "mlir/Transforms/DialectConversion.h"
29
30namespace llvm {
31struct KnownBits;
32}
33
34namespace mlir {
35class PatternRewriter;
36}
37
38#define GET_OP_CLASSES
39#include "circt/Dialect/Comb/Comb.h.inc"
40
41namespace circt {
42namespace comb {
43
44using llvm::KnownBits;
45
46/// Compute "known bits" information about the specified value - the set of bits
47/// that are guaranteed to always be zero, and the set of bits that are
48/// guaranteed to always be one (these must be exclusive!). A bit that exists
49/// in neither set is unknown.
50KnownBits computeKnownBits(Value value);
51
52/// Return true when both operands are wider than the bitwidth threshold, have
53/// matching extension kinds (both zero-extended, both sign-extended, or
54/// neither), and should use Booth encoding.
55bool shouldUseBoothEncoding(Value lhs, Value rhs, unsigned threshold = 16);
56
57/// Create the ops to zero-extend a value to an integer of equal or larger type.
58Value createZExt(OpBuilder &builder, Location loc, Value value,
59 unsigned targetWidth);
60
61/// Create a sign extension operation from a value of integer type to an equal
62/// or larger integer type.
63Value createOrFoldSExt(OpBuilder &builder, Location loc, Value value,
64 Type destTy);
65Value createOrFoldSExt(ImplicitLocOpBuilder &builder, Value value, Type destTy);
66
67/// Create a ``Not'' gate on a value.
68Value createOrFoldNot(OpBuilder &builder, Location loc, Value value,
69 bool twoState = false);
70Value createOrFoldNot(ImplicitLocOpBuilder &builder, Value value,
71 bool twoState = false);
72
73/// Extract bits from a value.
74void extractBits(OpBuilder &builder, Value val, SmallVectorImpl<Value> &bits);
75
76/// Construct a mux tree for given leaf nodes. `selectors` is the selector for
77/// each level of the tree. Currently the selector is tested from MSB to LSB.
78Value constructMuxTree(OpBuilder &builder, Location loc,
79 ArrayRef<Value> selectors, ArrayRef<Value> leafNodes,
80 Value outOfBoundsValue);
81
82/// Extract a range of bits from an integer at a dynamic offset.
83Value createDynamicExtract(OpBuilder &builder, Location loc, Value value,
84 Value offset, unsigned width);
85
86/// Replace a range of bits in an integer at a dynamic offset, and return the
87/// updated integer value. Calls `createInject` if the offset is constant.
88Value createDynamicInject(OpBuilder &builder, Location loc, Value value,
89 Value offset, Value replacement,
90 bool twoState = false);
91
92/// Replace a range of bits in an integer and return the updated integer value.
93Value createInject(OpBuilder &builder, Location loc, Value value,
94 unsigned offset, Value replacement);
95
96/// Replace a subtraction with an addition of the two's complement.
97LogicalResult convertSubToAdd(comb::SubOp subOp,
98 mlir::PatternRewriter &rewriter);
99
100/// Convert unsigned division or modulo by a power of two.
101/// For division: divu(x, 2^n) -> concat(0...0, extract(x, n, width-n)).
102/// For modulo: modu(x, 2^n) -> concat(0...0, extract(x, 0, n))
103/// TODO: Support signed division and modulo.
104LogicalResult convertDivUByPowerOfTwo(DivUOp divOp,
105 mlir::PatternRewriter &rewriter);
106LogicalResult convertModUByPowerOfTwo(ModUOp modOp,
107 mlir::PatternRewriter &rewriter);
108
109/// Enum for mux chain folding styles.
111/// Mux chain folding that converts chains of muxes with index
112/// comparisons into array operations or balanced mux trees. `styleFn` is a
113/// callback that returns the desired folding style based on the index
114/// width and number of entries.
116 PatternRewriter &rewriter, MuxOp rootMux, bool isFalseSide,
117 llvm::function_ref<MuxChainWithComparisonFoldingStyle(size_t indexWidth,
118 size_t numEntries)>
119 styleFn);
120
121// Check if the operand is zext() and return the extension bits:
122// zext = comb.concat(0, baseValue)
123template <typename SubType>
125 SubType lhs;
126 ZextByMatcher(SubType lhs) : lhs(std::move(lhs)) {}
127 bool match(Operation *op) {
128 // Check if operand is a concat operation
129 auto concatOp = dyn_cast<ConcatOp>(op);
130 if (!concatOp)
131 return false;
132
133 auto operands = concatOp.getOperands();
134 // ConcatOp must have at least 2 operands: (sign_bits, base_value_1,...)
135 if (operands.size() < 2)
136 return false;
137
138 auto constOp = operands[0].getDefiningOp<hw::ConstantOp>();
139 if (!constOp || !constOp.getValue().isZero())
140 return false;
141
142 // Match the most significant argument of the concat
143 return mlir::detail::matchOperandOrValueAtIndex(op, 0, lhs);
144 }
145};
146
147/// Helper function to create a zero extension matcher
148template <typename SubType>
149static inline ZextByMatcher<SubType> m_ZextBy(const SubType &subExpr) {
150 return ZextByMatcher<SubType>(subExpr);
151}
152
153// Check if the operand has a replicated extension and return the extension
154// bits:
155// ext = comb.replicate(bit, width-baseWidth) or hw.constant -1
156// replExt = comb.concat(ext, baseValue_1, ...)
157template <typename SubType>
159 SubType lhs;
160 ReplExtMatcher(SubType lhs) : lhs(std::move(lhs)) {}
161 bool match(Operation *op) {
162 auto concatOp = dyn_cast<ConcatOp>(op);
163 if (!concatOp)
164 return false;
165
166 auto operands = concatOp.getOperands();
167 if (operands.size() < 2)
168 return false;
169
170 auto replicateOp = operands[0].getDefiningOp<ReplicateOp>();
171 auto constOp = operands[0].getDefiningOp<hw::ConstantOp>();
172 bool isBitReplicate =
173 replicateOp &&
174 replicateOp.getInput().getType().getIntOrFloatBitWidth() == 1;
175 bool isAllOnes = constOp && constOp.getValue().isAllOnes();
176 if (!isBitReplicate && !isAllOnes)
177 return false;
178
179 // Match the most significant argument of the concat.
180 return mlir::detail::matchOperandOrValueAtIndex(op, 0, lhs);
181 }
182};
183
184/// Helper function to create a replicated extension matcher.
185template <typename SubType>
186static inline ReplExtMatcher<SubType> m_ReplExt(const SubType &subExpr) {
187 return ReplExtMatcher<SubType>(subExpr);
188}
189
190// Check if the operand is sext() and return the extension bits:
191// signBit = comb.extract(baseValue, width-1, 1)
192// ext = comb.replicate(signBit, width-baseWidth)
193// sext = comb.concat(ext, baseValue)
194// Also matches the single bit case:
195// sext = comb.concat(signBit, baseValue)
196template <typename SubType>
198 SubType lhs;
199 SextByMatcher(SubType lhs) : lhs(std::move(lhs)) {}
200 bool match(Operation *op) {
201 // Check if operand is a concat operation
202 auto concatOp = dyn_cast<ConcatOp>(op);
203 if (!concatOp)
204 return false;
205
206 auto operands = concatOp.getOperands();
207 // ConcatOp must have at least 2 operands: (sign_bits, base_value_1,...)
208 if (operands.size() < 2)
209 return false;
210
211 Value signBits = operands[0];
212 Value baseValue = operands[1];
213 auto baseWidth = baseValue.getType().getIntOrFloatBitWidth();
214
215 // Check if signBits is a replicate operation
216 auto replicateOp = dyn_cast_or_null<ReplicateOp>(signBits.getDefiningOp());
217 Value signBit = replicateOp ? replicateOp.getInput() : signBits;
218
219 // For the single bit case, check the bitwidth of signBit == 1
220 if (signBit.getType().getIntOrFloatBitWidth() != 1)
221 return false;
222
223 // Check if signBit is the msb of baseValue
224 auto extractOp = dyn_cast_or_null<ExtractOp>(signBit.getDefiningOp());
225 if (!extractOp)
226 return false;
227
228 if ((extractOp.getInput() != baseValue) ||
229 (extractOp.getLowBit() != baseWidth - 1))
230 return false;
231
232 // Match the most significant argument of the concat
233 return mlir::detail::matchOperandOrValueAtIndex(op, 0, lhs);
234 }
235};
236
237/// Helper function to create a sign extension matcher
238template <typename SubType>
239static inline SextByMatcher<SubType> m_SextBy(const SubType &subExpr) {
240 return SextByMatcher<SubType>(subExpr);
241}
242
243} // namespace comb
244} // namespace circt
245
246#endif // CIRCT_DIALECT_COMB_COMBOPS_H
static SextByMatcher< SubType > m_SextBy(const SubType &subExpr)
Helper function to create a sign extension matcher.
Definition CombOps.h:239
static ReplExtMatcher< SubType > m_ReplExt(const SubType &subExpr)
Helper function to create a replicated extension matcher.
Definition CombOps.h:186
void extractBits(OpBuilder &builder, Value val, SmallVectorImpl< Value > &bits)
Extract bits from a value.
Definition CombOps.cpp:124
bool foldMuxChainWithComparison(PatternRewriter &rewriter, MuxOp rootMux, bool isFalseSide, llvm::function_ref< MuxChainWithComparisonFoldingStyle(size_t indexWidth, size_t numEntries)> styleFn)
Mux chain folding that converts chains of muxes with index comparisons into array operations or balan...
bool shouldUseBoothEncoding(Value lhs, Value rhs, unsigned threshold=16)
Return true when both operands are wider than the bitwidth threshold, have matching extension kinds (...
Definition CombOps.cpp:32
Value createOrFoldNot(OpBuilder &builder, Location loc, Value value, bool twoState=false)
Create a `‘Not’' gate on a value.
Definition CombOps.cpp:112
MuxChainWithComparisonFoldingStyle
Enum for mux chain folding styles.
Definition CombOps.h:110
@ BalancedMuxTree
Definition CombOps.h:110
LogicalResult convertSubToAdd(comb::SubOp subOp, mlir::PatternRewriter &rewriter)
Replace a subtraction with an addition of the two's complement.
Definition CombOps.cpp:267
LogicalResult convertModUByPowerOfTwo(ModUOp modOp, mlir::PatternRewriter &rewriter)
Value createDynamicInject(OpBuilder &builder, Location loc, Value value, Value offset, Value replacement, bool twoState=false)
Replace a range of bits in an integer at a dynamic offset, and return the updated integer value.
Definition CombOps.cpp:198
Value createInject(OpBuilder &builder, Location loc, Value value, unsigned offset, Value replacement)
Replace a range of bits in an integer and return the updated integer value.
Definition CombOps.cpp:233
Value createDynamicExtract(OpBuilder &builder, Location loc, Value value, Value offset, unsigned width)
Extract a range of bits from an integer at a dynamic offset.
Definition CombOps.cpp:178
KnownBits computeKnownBits(Value value)
Compute "known bits" information about the specified value - the set of bits that are guaranteed to a...
static ZextByMatcher< SubType > m_ZextBy(const SubType &subExpr)
Helper function to create a zero extension matcher.
Definition CombOps.h:149
Value constructMuxTree(OpBuilder &builder, Location loc, ArrayRef< Value > selectors, ArrayRef< Value > leafNodes, Value outOfBoundsValue)
Construct a mux tree for given leaf nodes.
Definition CombOps.cpp:151
Value createZExt(OpBuilder &builder, Location loc, Value value, unsigned targetWidth)
Create the ops to zero-extend a value to an integer of equal or larger type.
Definition CombOps.cpp:71
Value createOrFoldSExt(OpBuilder &builder, Location loc, Value value, Type destTy)
Create a sign extension operation from a value of integer type to an equal or larger integer type.
Definition CombOps.cpp:89
LogicalResult convertDivUByPowerOfTwo(DivUOp divOp, mlir::PatternRewriter &rewriter)
Convert unsigned division or modulo by a power of two.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition comb.py:1
ReplExtMatcher(SubType lhs)
Definition CombOps.h:160
bool match(Operation *op)
Definition CombOps.h:161
bool match(Operation *op)
Definition CombOps.h:200
SextByMatcher(SubType lhs)
Definition CombOps.h:199
bool match(Operation *op)
Definition CombOps.h:127
ZextByMatcher(SubType lhs)
Definition CombOps.h:126