CIRCT 23.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 and
53/// should use Booth encoding.
54bool shouldUseBoothEncoding(Value lhs, Value rhs, unsigned threshold = 16);
55
56/// Create the ops to zero-extend a value to an integer of equal or larger type.
57Value createZExt(OpBuilder &builder, Location loc, Value value,
58 unsigned targetWidth);
59
60/// Create a sign extension operation from a value of integer type to an equal
61/// or larger integer type.
62Value createOrFoldSExt(OpBuilder &builder, Location loc, Value value,
63 Type destTy);
64Value createOrFoldSExt(ImplicitLocOpBuilder &builder, Value value, Type destTy);
65
66/// Create a ``Not'' gate on a value.
67Value createOrFoldNot(OpBuilder &builder, Location loc, Value value,
68 bool twoState = false);
69Value createOrFoldNot(ImplicitLocOpBuilder &builder, Value value,
70 bool twoState = false);
71
72/// Extract bits from a value.
73void extractBits(OpBuilder &builder, Value val, SmallVectorImpl<Value> &bits);
74
75/// Construct a mux tree for given leaf nodes. `selectors` is the selector for
76/// each level of the tree. Currently the selector is tested from MSB to LSB.
77Value constructMuxTree(OpBuilder &builder, Location loc,
78 ArrayRef<Value> selectors, ArrayRef<Value> leafNodes,
79 Value outOfBoundsValue);
80
81/// Extract a range of bits from an integer at a dynamic offset.
82Value createDynamicExtract(OpBuilder &builder, Location loc, Value value,
83 Value offset, unsigned width);
84
85/// Replace a range of bits in an integer at a dynamic offset, and return the
86/// updated integer value. Calls `createInject` if the offset is constant.
87Value createDynamicInject(OpBuilder &builder, Location loc, Value value,
88 Value offset, Value replacement,
89 bool twoState = false);
90
91/// Replace a range of bits in an integer and return the updated integer value.
92Value createInject(OpBuilder &builder, Location loc, Value value,
93 unsigned offset, Value replacement);
94
95/// Replace a subtraction with an addition of the two's complement.
96LogicalResult convertSubToAdd(comb::SubOp subOp,
97 mlir::PatternRewriter &rewriter);
98
99/// Convert unsigned division or modulo by a power of two.
100/// For division: divu(x, 2^n) -> concat(0...0, extract(x, n, width-n)).
101/// For modulo: modu(x, 2^n) -> concat(0...0, extract(x, 0, n))
102/// TODO: Support signed division and modulo.
103LogicalResult convertDivUByPowerOfTwo(DivUOp divOp,
104 mlir::PatternRewriter &rewriter);
105LogicalResult convertModUByPowerOfTwo(ModUOp modOp,
106 mlir::PatternRewriter &rewriter);
107
108/// Enum for mux chain folding styles.
110/// Mux chain folding that converts chains of muxes with index
111/// comparisons into array operations or balanced mux trees. `styleFn` is a
112/// callback that returns the desired folding style based on the index
113/// width and number of entries.
115 PatternRewriter &rewriter, MuxOp rootMux, bool isFalseSide,
116 llvm::function_ref<MuxChainWithComparisonFoldingStyle(size_t indexWidth,
117 size_t numEntries)>
118 styleFn);
119
120// Check if the operand is zext() and return the extension bits:
121// zext = comb.concat(0, baseValue)
122template <typename SubType>
124 SubType lhs;
125 ZextByMatcher(SubType lhs) : lhs(std::move(lhs)) {}
126 bool match(Operation *op) {
127 // Check if operand is a concat operation
128 auto concatOp = dyn_cast<ConcatOp>(op);
129 if (!concatOp)
130 return false;
131
132 auto operands = concatOp.getOperands();
133 // ConcatOp must have at least 2 operands: (sign_bits, base_value_1,...)
134 if (operands.size() < 2)
135 return false;
136
137 auto constOp = operands[0].getDefiningOp<hw::ConstantOp>();
138 if (!constOp || !constOp.getValue().isZero())
139 return false;
140
141 // Match the most significant argument of the concat
142 return mlir::detail::matchOperandOrValueAtIndex(op, 0, lhs);
143 }
144};
145
146/// Helper function to create a zero extension matcher
147template <typename SubType>
148static inline ZextByMatcher<SubType> m_ZextBy(const SubType &subExpr) {
149 return ZextByMatcher<SubType>(subExpr);
150}
151
152// Check if the operand is sext() and return the extension bits:
153// signBit = comb.extract(baseValue, width-1, 1)
154// ext = comb.replicate(signBit, width-baseWidth)
155// sext = comb.concat(ext, baseValue)
156// Also matches the single bit case:
157// sext = comb.concat(signBit, baseValue)
158template <typename SubType>
160 SubType lhs;
161 SextByMatcher(SubType lhs) : lhs(std::move(lhs)) {}
162 bool match(Operation *op) {
163 // Check if operand is a concat operation
164 auto concatOp = dyn_cast<ConcatOp>(op);
165 if (!concatOp)
166 return false;
167
168 auto operands = concatOp.getOperands();
169 // ConcatOp must have at least 2 operands: (sign_bits, base_value_1,...)
170 if (operands.size() < 2)
171 return false;
172
173 Value signBits = operands[0];
174 Value baseValue = operands[1];
175 auto baseWidth = baseValue.getType().getIntOrFloatBitWidth();
176
177 // Check if signBits is a replicate operation
178 auto replicateOp = dyn_cast_or_null<ReplicateOp>(signBits.getDefiningOp());
179 Value signBit = replicateOp ? replicateOp.getInput() : signBits;
180
181 // For the single bit case, check the bitwidth of signBit == 1
182 if (signBit.getType().getIntOrFloatBitWidth() != 1)
183 return false;
184
185 // Check if signBit is the msb of baseValue
186 auto extractOp = dyn_cast_or_null<ExtractOp>(signBit.getDefiningOp());
187 if (!extractOp)
188 return false;
189
190 if ((extractOp.getInput() != baseValue) ||
191 (extractOp.getLowBit() != baseWidth - 1))
192 return false;
193
194 // Match the most significant argument of the concat
195 return mlir::detail::matchOperandOrValueAtIndex(op, 0, lhs);
196 }
197};
198
199/// Helper function to create a sign extension matcher
200template <typename SubType>
201static inline SextByMatcher<SubType> m_SextBy(const SubType &subExpr) {
202 return SextByMatcher<SubType>(subExpr);
203}
204
205} // namespace comb
206} // namespace circt
207
208#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:201
void extractBits(OpBuilder &builder, Value val, SmallVectorImpl< Value > &bits)
Extract bits from a value.
Definition CombOps.cpp:114
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 and should use Booth encoding.
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:102
MuxChainWithComparisonFoldingStyle
Enum for mux chain folding styles.
Definition CombOps.h:109
@ BalancedMuxTree
Definition CombOps.h:109
LogicalResult convertSubToAdd(comb::SubOp subOp, mlir::PatternRewriter &rewriter)
Replace a subtraction with an addition of the two's complement.
Definition CombOps.cpp:257
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:188
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:223
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:168
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:148
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:141
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:61
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:79
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
bool match(Operation *op)
Definition CombOps.h:162
SextByMatcher(SubType lhs)
Definition CombOps.h:161
bool match(Operation *op)
Definition CombOps.h:126
ZextByMatcher(SubType lhs)
Definition CombOps.h:125